diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.ddev/config.yaml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.ddev/config.yaml new file mode 100644 index 0000000..ead9756 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.ddev/config.yaml @@ -0,0 +1,179 @@ +name: workshop-drupal-automated-testing +type: drupal8 +docroot: web +php_version: "7.4" +webserver_type: nginx-fpm +router_http_port: "80" +router_https_port: "443" +xdebug_enabled: false +additional_hostnames: [] +additional_fqdns: [] +mariadb_version: "10.3" +provider: default +use_dns_when_possible: true +working_dir: + web: /var/www/html + +hooks: + post-start: + - exec: | + if [ ! -f .flag-built ]; then + composer install + + vendor/bin/drush site:install -y \ + --site-name="Drupal Testing Workshop" \ + --account-pass=admin123 + + touch .flag-built + fi + +# This config.yaml was created with ddev version v1.15.3 +# webimage: drud/ddev-webserver:v1.15.3 +# dbimage: drud/ddev-dbserver-mariadb-10.2:v1.15.1 +# dbaimage: phpmyadmin/phpmyadmin:5 +# However we do not recommend explicitly wiring these images into the +# config.yaml as they may break future versions of ddev. +# You can update this config.yaml using 'ddev config'. + +# Key features of ddev's config.yaml: + +# name: # Name of the project, automatically provides +# http://projectname.ddev.site and https://projectname.ddev.site + +# type: # drupal6/7/8, backdrop, typo3, wordpress, php + +# docroot: # Relative path to the directory containing index.php. + +# php_version: "7.3" # PHP version to use, "5.6", "7.0", "7.1", "7.2", "7.3", "7.4" + +# You can explicitly specify the webimage, dbimage, dbaimage lines but this +# is not recommended, as the images are often closely tied to ddev's' behavior, +# so this can break upgrades. + +# webimage: # nginx/php docker image. +# dbimage: # mariadb docker image. +# dbaimage: + +# mariadb_version and mysql_version +# ddev can use many versions of mariadb and mysql +# However these directives are mutually exclusive +# mariadb_version: 10.2 +# mysql_version: 8.0 + +# router_http_port: # Port to be used for http (defaults to port 80) +# router_https_port: # Port for https (defaults to 443) + +# xdebug_enabled: false # Set to true to enable xdebug and "ddev start" or "ddev restart" +# Note that for most people the commands +# "ddev exec enable_xdebug" and "ddev exec disable_xdebug" work better, +# as leaving xdebug enabled all the time is a big performance hit. + +# webserver_type: nginx-fpm # Can be set to apache-fpm or apache-cgi as well + +# timezone: Europe/Berlin +# This is the timezone used in the containers and by PHP; +# it can be set to any valid timezone, +# see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +# For example Europe/Dublin or MST7MDT + +# additional_hostnames: +# - somename +# - someothername +# would provide http and https URLs for "somename.ddev.site" +# and "someothername.ddev.site". + +# additional_fqdns: +# - example.com +# - sub1.example.com +# would provide http and https URLs for "example.com" and "sub1.example.com" +# Please take care with this because it can cause great confusion. + +# upload_dir: custom/upload/dir +# would set the destination path for ddev import-files to custom/upload/dir. + +# working_dir: +# web: /var/www/html +# db: /home +# would set the default working directory for the web and db services. +# These values specify the destination directory for ddev ssh and the +# directory in which commands passed into ddev exec are run. + +# omit_containers: [db, dba, ddev-ssh-agent] +# Currently only these containers are supported. Some containers can also be +# omitted globally in the ~/.ddev/global_config.yaml. Note that if you omit +# the "db" container, several standard features of ddev that access the +# database container will be unusable. + +# nfs_mount_enabled: false +# Great performance improvement but requires host configuration first. +# See https://ddev.readthedocs.io/en/stable/users/performance/#using-nfs-to-mount-the-project-into-the-container + +# host_https_port: "59002" +# The host port binding for https can be explicitly specified. It is +# dynamic unless otherwise specified. +# This is not used by most people, most people use the *router* instead +# of the localhost port. + +# host_webserver_port: "59001" +# The host port binding for the ddev-webserver can be explicitly specified. It is +# dynamic unless otherwise specified. +# This is not used by most people, most people use the *router* instead +# of the localhost port. + +# host_db_port: "59002" +# The host port binding for the ddev-dbserver can be explicitly specified. It is dynamic +# unless explicitly specified. + +# phpmyadmin_port: "8036" +# phpmyadmin_https_port: "8037" +# The PHPMyAdmin ports can be changed from the default 8036 and 8037 + +# mailhog_port: "8025" +# mailhog_https_port: "8026" +# The MailHog ports can be changed from the default 8025 and 8026 + +# webimage_extra_packages: [php7.3-tidy, php-bcmath] +# Extra Debian packages that are needed in the webimage can be added here + +# dbimage_extra_packages: [telnet,netcat] +# Extra Debian packages that are needed in the dbimage can be added here + +# use_dns_when_possible: true +# If the host has internet access and the domain configured can +# successfully be looked up, DNS will be used for hostname resolution +# instead of editing /etc/hosts +# Defaults to true + +# project_tld: ddev.site +# The top-level domain used for project URLs +# The default "ddev.site" allows DNS lookup via a wildcard +# If you prefer you can change this to "ddev.local" to preserve +# pre-v1.9 behavior. + +# ngrok_args: --subdomain mysite --auth username:pass +# Provide extra flags to the "ngrok http" command, see +# https://ngrok.com/docs#http or run "ngrok http -h" + +# disable_settings_management: false +# If true, ddev will not create CMS-specific settings files like +# Drupal's settings.php/settings.ddev.php or TYPO3's AdditionalSettings.php +# In this case the user must provide all such settings. + +# no_project_mount: false +# (Experimental) If true, ddev will not mount the project into the web container; +# the user is responsible for mounting it manually or via a script. +# This is to enable experimentation with alternate file mounting strategies. +# For advanced users only! + +# provider: default # Currently either "default" or "pantheon" +# +# Many ddev commands can be extended to run tasks before or after the +# ddev command is executed, for example "post-start", "post-import-db", +# "pre-composer", "post-composer" +# See https://ddev.readthedocs.io/en/stable/users/extending-commands/ for more +# information on the commands that can be extended and the tasks you can define +# for them. Example: +#hooks: +# post-import-db: +# - exec: drush cr +# - exec: drush updb diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.github/workflows/run-tests.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.github/workflows/run-tests.yml new file mode 100644 index 0000000..57f4c38 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.github/workflows/run-tests.yml @@ -0,0 +1,50 @@ +name: Run tests + +on: push + +jobs: + tests: + runs-on: ubuntu-latest + + name: "Run ${{ matrix.test-types }} tests" + + strategy: + fail-fast: true + matrix: + test-types: + - functional + - kernel + - unit + + steps: + - name: Checkout code + uses: actions/checkout@a81bbbf + + - name: Cache dependencies + uses: actions/cache@d974700 + with: + path: | + ~/.composer/cache/files + vendor + web/core + key: dependencies-composer-${{ hashFiles('composer.json') }} + + - name: Setup PHP + uses: shivammathur/setup-php@5d27b8f + with: + php-version: 7.4 + extensions: mbstring + coverage: none + tools: composer:v1 + + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-suggest + + - name: Start the local web server + run: php -S localhost:8000 -t web 2>&1 & + if: matrix.test-types == 'functional' + + - name: Execute tests + run: composer test -- --colors=always --testsuite=${{ matrix.test-types }} + env: + SIMPLETEST_BASE_URL: http://localhost:8000 diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.gitignore b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.gitignore new file mode 100644 index 0000000..66908d5 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.gitignore @@ -0,0 +1,18 @@ +* +!*/ +!/.ddev/** +!/.github/** +!/.gitignore +!/**/.gitkeep +!/.idea/** +!/composer.json +!/composer.lock +!/docker-compose.yaml +!/Makefile +!/php.ini +!/web/modules/custom/** +!/web/sites/default/settings.php +!/web/sites/default/settings.symfony.php +!/workspace.yml +/.idea/workspace.xml +/vendor/ diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/inspectionProfiles/Project_Default.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/misc.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/modules.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/modules.xml new file mode 100644 index 0000000..0d23deb --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php-test-framework.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php-test-framework.xml new file mode 100644 index 0000000..ac3134f --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php-test-framework.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php.xml new file mode 100644 index 0000000..3f38e07 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/vcs.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/workshop-drupal-automated-testing-code.iml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/workshop-drupal-automated-testing-code.iml new file mode 100644 index 0000000..33986f9 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/workshop-drupal-automated-testing-code.iml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/README.md b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/README.md new file mode 100644 index 0000000..4d788de --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/README.md @@ -0,0 +1,13 @@ +# Drupal Automated Testing Workshop: Example Code + +## Updates + +If we need to update any of the commits, the changes should be rebased into the existing commits so that they continue to be in a linear order as per the workshop document. + +As we want GitHub Actions to run for each commit, we can’t just push the latest commit as that would only trigger a build on the final commit. To do this, we can loop over each of the commit SHAs and push each one separately: + +```bash +for sha1 in $(git rev-list HEAD --reverse); do + git push origin $sha1:main --force +done +``` diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.json b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.json new file mode 100644 index 0000000..4a55556 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.json @@ -0,0 +1,57 @@ +{ + "name": "opdavies/workshop-drupal-automated-testing-code", + "description": "Project template for Drupal 8 projects with a relocated document root", + "type": "project", + "license": "GPL-2.0-or-later", + "homepage": "https://www.drupal.org/project/drupal", + "support": { + "docs": "https://www.drupal.org/docs/user_guide/en/index.html", + "chat": "https://www.drupal.org/node/314178" + }, + "repositories": [ + { + "type": "composer", + "url": "https://packages.drupal.org/8" + } + ], + "require": { + "composer/installers": "^1.2", + "drupal/core-composer-scaffold": "^8.9", + "drupal/core-recommended": "^8.9", + "drush/drush": "^10" + }, + "require-dev": { + "drupal/core-dev": "^8.9" + }, + "conflict": { + "drupal/drupal": "*" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "scripts": { + "phpunit": "phpunit --verbose --testdox --colors=always", + "test": [ + "@phpunit" + ] + }, + "config": { + "sort-packages": true + }, + "extra": { + "drupal-scaffold": { + "locations": { + "web-root": "web/" + } + }, + "installer-paths": { + "web/core": ["type:drupal-core"], + "web/libraries/{$name}": ["type:drupal-library"], + "web/modules/contrib/{$name}": ["type:drupal-module"], + "web/profiles/contrib/{$name}": ["type:drupal-profile"], + "web/themes/contrib/{$name}": ["type:drupal-theme"], + "drush/Commands/contrib/{$name}": ["type:drupal-drush"], + "web/modules/custom/{$name}": ["type:drupal-custom-module"], + "web/themes/custom/{$name}": ["type:drupal-custom-theme"] + } + } +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.lock b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.lock new file mode 100644 index 0000000..4a0617d --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.lock @@ -0,0 +1,8719 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "0cacc6f4042304e22160df4c3d2ae048", + "packages": [ + { + "name": "asm89/stack-cors", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/asm89/stack-cors.git", + "reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/asm89/stack-cors/zipball/b9c31def6a83f84b4d4a40d35996d375755f0e08", + "reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/http-foundation": "~2.7|~3.0|~4.0|~5.0", + "symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0 || ^4.8.10", + "squizlabs/php_codesniffer": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Asm89\\Stack\\": "src/Asm89/Stack/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander", + "email": "iam.asm89@gmail.com" + } + ], + "description": "Cross-origin resource sharing library and stack middleware", + "homepage": "https://github.com/asm89/stack-cors", + "keywords": [ + "cors", + "stack" + ], + "time": "2019-12-24T22:41:47+00:00" + }, + { + "name": "chi-teck/drupal-code-generator", + "version": "1.33.0", + "source": { + "type": "git", + "url": "https://github.com/Chi-teck/drupal-code-generator.git", + "reference": "49f4ce174ed83764e3389ddb75c4758772435243" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/49f4ce174ed83764e3389ddb75c4758772435243", + "reference": "49f4ce174ed83764e3389ddb75c4758772435243", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.5.9", + "symfony/console": "^3.4 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.4 || ^4.0", + "twig/twig": "^1.41 || ^2.12" + }, + "conflict": { + "drush/drush": "< 10.3.2" + }, + "bin": [ + "bin/dcg" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/bootstrap.php" + ], + "psr-4": { + "DrupalCodeGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Drupal code generator", + "time": "2020-10-11T16:56:42+00:00" + }, + { + "name": "composer/installers", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || 2.0.*@dev", + "composer/semver": "1.0.* || 2.0.*@dev", + "phpunit/phpunit": "^4.8.36", + "sebastian/comparator": "^1.2.4", + "symfony/process": "^2.3" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-04-07T06:57:05+00:00" + }, + { + "name": "composer/semver", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c6bea70230ef4dd483e6bbcab6005f682ed3a8de", + "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2020-01-13T12:06:48+00:00" + }, + { + "name": "consolidation/annotated-command", + "version": "2.12.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/annotated-command.git", + "reference": "0ee361762df2274f360c085e3239784a53f850b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/0ee361762df2274f360c085e3239784a53f850b5", + "reference": "0ee361762df2274f360c085e3239784a53f850b5", + "shasum": "" + }, + "require": { + "consolidation/output-formatters": "^3.5.1", + "php": ">=5.4.5", + "psr/log": "^1", + "symfony/console": "^2.8|^3|^4", + "symfony/event-dispatcher": "^2.5|^3|^4", + "symfony/finder": "^2.5|^3|^4|^5" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^6", + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "extra": { + "scenarios": { + "finder5": { + "require": { + "symfony/finder": "^5" + }, + "config": { + "platform": { + "php": "7.2.5" + } + } + }, + "symfony4": { + "require": { + "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + }, + "scenario-options": { + "create-lockfile": "false" + } + }, + "phpunit4": { + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + } + }, + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\AnnotatedCommand\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Initialize Symfony Console commands from annotated command class methods.", + "time": "2020-10-11T04:30:03+00:00" + }, + { + "name": "consolidation/config", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/config.git", + "reference": "cac1279bae7efb5c7fb2ca4c3ba4b8eb741a96c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/config/zipball/cac1279bae7efb5c7fb2ca4c3ba4b8eb741a96c1", + "reference": "cac1279bae7efb5c7fb2ca4c3ba4b8eb741a96c1", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "grasmash/expander": "^1", + "php": ">=5.4.0" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^5", + "squizlabs/php_codesniffer": "2.*", + "symfony/console": "^2.5|^3|^4", + "symfony/yaml": "^2.8.11|^3|^4" + }, + "suggest": { + "symfony/yaml": "Required to use Consolidation\\Config\\Loader\\YamlConfigLoader" + }, + "type": "library", + "extra": { + "scenarios": { + "symfony4": { + "require-dev": { + "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require-dev": { + "symfony/console": "^2.8", + "symfony/event-dispatcher": "^2.8", + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provide configuration services for a commandline tool.", + "time": "2019-03-03T19:37:04+00:00" + }, + { + "name": "consolidation/filter-via-dot-access-data", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/filter-via-dot-access-data.git", + "reference": "a53e96c6b9f7f042f5e085bf911f3493cea823c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/filter-via-dot-access-data/zipball/a53e96c6b9f7f042f5e085bf911f3493cea823c6", + "reference": "a53e96c6b9f7f042f5e085bf911f3493cea823c6", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.5.0" + }, + "require-dev": { + "consolidation/robo": "^1.2.3", + "g1a/composer-test-scenarios": "^3", + "knplabs/github-api": "^2.7", + "php-coveralls/php-coveralls": "^1", + "php-http/guzzle6-adapter": "^1.1", + "phpunit/phpunit": "^5", + "squizlabs/php_codesniffer": "^2.8", + "symfony/console": "^2.8|^3|^4" + }, + "type": "library", + "extra": { + "scenarios": { + "phpunit5": { + "require-dev": { + "phpunit/phpunit": "^5.7.27" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.6.33" + } + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Filter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "This project uses dflydev/dot-access-data to provide simple output filtering for applications built with annotated-command / Robo.", + "time": "2019-01-18T06:05:07+00:00" + }, + { + "name": "consolidation/log", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/log.git", + "reference": "b2e887325ee90abc96b0a8b7b474cd9e7c896e3a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/log/zipball/b2e887325ee90abc96b0a8b7b474cd9e7c896e3a", + "reference": "b2e887325ee90abc96b0a8b7b474cd9e7c896e3a", + "shasum": "" + }, + "require": { + "php": ">=5.4.5", + "psr/log": "^1.0", + "symfony/console": "^2.8|^3|^4" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^6", + "squizlabs/php_codesniffer": "^2" + }, + "type": "library", + "extra": { + "scenarios": { + "symfony4": { + "require": { + "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + }, + "phpunit4": { + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", + "time": "2019-01-01T17:30:51+00:00" + }, + { + "name": "consolidation/output-formatters", + "version": "3.5.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "0d38f13051ef05c223a2bb8e962d668e24785196" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/0d38f13051ef05c223a2bb8e962d668e24785196", + "reference": "0d38f13051ef05c223a2bb8e962d668e24785196", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.4.0", + "symfony/console": "^2.8|^3|^4", + "symfony/finder": "^2.5|^3|^4|^5" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^5.7.27", + "squizlabs/php_codesniffer": "^2.7", + "symfony/var-dumper": "^2.8|^3|^4", + "victorjonsson/markdowndocs": "^1.3" + }, + "suggest": { + "symfony/var-dumper": "For using the var_dump formatter" + }, + "type": "library", + "extra": { + "scenarios": { + "finder5": { + "require": { + "symfony/finder": "^5" + }, + "config": { + "platform": { + "php": "7.2.5" + } + } + }, + "symfony4": { + "require": { + "symfony/console": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^6" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony3": { + "require": { + "symfony/console": "^3.4", + "symfony/finder": "^3.4", + "symfony/var-dumper": "^3.4" + }, + "config": { + "platform": { + "php": "5.6.32" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + }, + "scenario-options": { + "create-lockfile": "false" + } + } + }, + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Format text by applying transformations provided by plug-in formatters.", + "time": "2020-10-11T04:15:32+00:00" + }, + { + "name": "consolidation/robo", + "version": "1.4.13", + "source": { + "type": "git", + "url": "https://github.com/consolidation/Robo.git", + "reference": "fd28dcca1b935950ece26e63541fbdeeb09f7343" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/fd28dcca1b935950ece26e63541fbdeeb09f7343", + "reference": "fd28dcca1b935950ece26e63541fbdeeb09f7343", + "shasum": "" + }, + "require": { + "consolidation/annotated-command": "^2.12.1|^4.1", + "consolidation/config": "^1.2.1", + "consolidation/log": "^1.1.1|^2", + "consolidation/output-formatters": "^3.5.1|^4.1", + "consolidation/self-update": "^1.1.5", + "grasmash/yaml-expander": "^1.4", + "league/container": "^2.4.1", + "php": ">=5.5.0", + "symfony/console": "^2.8|^3|^4", + "symfony/event-dispatcher": "^2.5|^3|^4", + "symfony/filesystem": "^2.5|^3|^4", + "symfony/finder": "^2.5|^3|^4|^5", + "symfony/process": "^2.5|^3|^4" + }, + "replace": { + "codegyre/robo": "< 1.0" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "natxet/cssmin": "3.0.4", + "patchwork/jsqueeze": "^2", + "pear/archive_tar": "^1.4.4", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^5.7.27", + "squizlabs/php_codesniffer": "^3" + }, + "suggest": { + "henrikbjorn/lurker": "For monitoring filesystem changes in taskWatch", + "natxet/CssMin": "For minifying CSS files in taskMinify", + "patchwork/jsqueeze": "For minifying JS files in taskMinify", + "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively." + }, + "bin": [ + "robo" + ], + "type": "library", + "extra": { + "scenarios": { + "finder5": { + "require": { + "symfony/finder": "^5" + }, + "config": { + "platform": { + "php": "7.2.5" + } + } + }, + "symfony4": { + "require": { + "symfony/console": "^4" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.5.9" + } + }, + "scenario-options": { + "create-lockfile": "false" + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Robo\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "description": "Modern task runner", + "time": "2020-10-11T04:51:34+00:00" + }, + { + "name": "consolidation/self-update", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/self-update.git", + "reference": "dba6b2c0708f20fa3ba8008a2353b637578849b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/self-update/zipball/dba6b2c0708f20fa3ba8008a2353b637578849b4", + "reference": "dba6b2c0708f20fa3ba8008a2353b637578849b4", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "symfony/console": "^2.8|^3|^4|^5", + "symfony/filesystem": "^2.5|^3|^4|^5" + }, + "bin": [ + "scripts/release" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "SelfUpdate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander Menk", + "email": "menk@mestrona.net" + }, + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provides a self:update command for Symfony Console applications.", + "time": "2020-04-13T02:49:20+00:00" + }, + { + "name": "consolidation/site-alias", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/site-alias.git", + "reference": "fd40a03f80f8fd4684b10bef8c8c4ec5a9a9bf26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/site-alias/zipball/fd40a03f80f8fd4684b10bef8c8c4ec5a9a9bf26", + "reference": "fd40a03f80f8fd4684b10bef8c8c4ec5a9a9bf26", + "shasum": "" + }, + "require": { + "consolidation/config": "^1.2.1|^2", + "php": ">=5.5.0" + }, + "require-dev": { + "consolidation/robo": "^1.2.3|^2", + "g1a/composer-test-scenarios": "^3", + "knplabs/github-api": "^2.7", + "php-coveralls/php-coveralls": "^2.2", + "php-http/guzzle6-adapter": "^1.1", + "phpunit/phpunit": "^6", + "squizlabs/php_codesniffer": "^2.8", + "symfony/yaml": "~2.3|^3|^4.4|^5" + }, + "type": "library", + "extra": { + "scenarios": { + "phpunit5": { + "require-dev": { + "phpunit/phpunit": "^5.7.27" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.6.33" + } + } + } + }, + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\SiteAlias\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + } + ], + "description": "Manage alias records for local and remote sites.", + "time": "2020-05-28T00:33:41+00:00" + }, + { + "name": "consolidation/site-process", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/site-process.git", + "reference": "f3211fa4c60671c6f068184221f06f932556e443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/site-process/zipball/f3211fa4c60671c6f068184221f06f932556e443", + "reference": "f3211fa4c60671c6f068184221f06f932556e443", + "shasum": "" + }, + "require": { + "consolidation/config": "^1.2.1", + "consolidation/site-alias": "^3", + "php": ">=5.6.0", + "symfony/process": "^3.4" + }, + "require-dev": { + "consolidation/robo": "^1.3", + "g1a/composer-test-scenarios": "^3", + "knplabs/github-api": "^2.7", + "php-coveralls/php-coveralls": "^1", + "php-http/guzzle6-adapter": "^1.1", + "phpunit/phpunit": "^6", + "squizlabs/php_codesniffer": "^2.8" + }, + "type": "library", + "extra": { + "scenarios": { + "phpunit5": { + "require-dev": { + "phpunit/phpunit": "^5.7.27" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.6.33" + } + } + } + }, + "branch-alias": { + "dev-master": "0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\SiteProcess\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + } + ], + "description": "A thin wrapper around the Symfony Process Component that allows applications to use the Site Alias library to specify the target for a remote call.", + "time": "2019-09-10T17:56:24+00:00" + }, + { + "name": "container-interop/container-interop", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "shasum": "" + }, + "require": { + "psr/container": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "homepage": "https://github.com/container-interop/container-interop", + "abandoned": "psr/container", + "time": "2017-02-14T19:40:03+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/3fbd874921ab2c041e899d044585a2ab9795df8a", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Dflydev\\DotAccessData": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "time": "2017-01-20T21:14:22+00:00" + }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "time": "2019-12-04T15:06:13+00:00" + }, + { + "name": "doctrine/annotations", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "54cacc9b81758b14e3ce750f205a393d52339e97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97", + "reference": "54cacc9b81758b14e3ce750f205a393d52339e97", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2017-02-24T16:22:25+00:00" + }, + { + "name": "doctrine/cache", + "version": "v1.6.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/eb152c5100571c7a45470ff2a35095ab3f3b900b", + "reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b", + "shasum": "" + }, + "require": { + "php": "~5.5|~7.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.0", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2017-07-22T12:49:21+00:00" + }, + { + "name": "doctrine/collections", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/coding-standard": "~0.1@dev", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2017-01-03T10:49:41+00:00" + }, + { + "name": "doctrine/common", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "4acb8f89626baafede6ee5475bc5844096eba8a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/4acb8f89626baafede6ee5475bc5844096eba8a9", + "reference": "4acb8f89626baafede6ee5475bc5844096eba8a9", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~5.6|~7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2017-07-22T08:35:12+00:00" + }, + { + "name": "doctrine/inflector", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/e11d84c6e018beedd929cff5220969a3c6d1d462", + "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2017-07-22T12:18:28+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/1febd6c3ef84253d7c815bed85fc622ad207a9f8", + "reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "^4.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "time": "2019-06-08T11:03:04+00:00" + }, + { + "name": "drupal/core", + "version": "8.9.8", + "source": { + "type": "git", + "url": "https://github.com/drupal/core.git", + "reference": "e16f650e7bd7f0cfb4ff4dd8ed753625313cdfdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drupal/core/zipball/e16f650e7bd7f0cfb4ff4dd8ed753625313cdfdb", + "reference": "e16f650e7bd7f0cfb4ff4dd8ed753625313cdfdb", + "shasum": "" + }, + "require": { + "asm89/stack-cors": "^1.1", + "composer/semver": "^1.0", + "doctrine/annotations": "^1.4", + "doctrine/common": "^2.7", + "easyrdf/easyrdf": "^0.9", + "egulias/email-validator": "^2.0", + "ext-date": "*", + "ext-dom": "*", + "ext-filter": "*", + "ext-gd": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-pdo": "*", + "ext-session": "*", + "ext-simplexml": "*", + "ext-spl": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "guzzlehttp/guzzle": "^6.3", + "laminas/laminas-diactoros": "^1.8", + "laminas/laminas-feed": "^2.12", + "masterminds/html5": "^2.1", + "pear/archive_tar": "^1.4.9", + "php": ">=7.0.8", + "psr/log": "^1.0", + "stack/builder": "^1.0", + "symfony-cmf/routing": "^1.4", + "symfony/class-loader": "~3.4.0", + "symfony/console": "~3.4.0", + "symfony/dependency-injection": "~3.4.26", + "symfony/event-dispatcher": "~3.4.0", + "symfony/http-foundation": "~3.4.35", + "symfony/http-kernel": "~3.4.14", + "symfony/polyfill-iconv": "^1.0", + "symfony/process": "~3.4.0", + "symfony/psr-http-message-bridge": "^1.1.2", + "symfony/routing": "~3.4.0", + "symfony/serializer": "~3.4.0", + "symfony/translation": "~3.4.0", + "symfony/validator": "~3.4.0", + "symfony/yaml": "~3.4.5", + "twig/twig": "^1.38.2", + "typo3/phar-stream-wrapper": "^3.1.3" + }, + "conflict": { + "drupal/pathauto": "<1.6", + "drush/drush": "<8.1.10" + }, + "replace": { + "drupal/action": "self.version", + "drupal/aggregator": "self.version", + "drupal/automated_cron": "self.version", + "drupal/ban": "self.version", + "drupal/bartik": "self.version", + "drupal/basic_auth": "self.version", + "drupal/big_pipe": "self.version", + "drupal/block": "self.version", + "drupal/block_content": "self.version", + "drupal/block_place": "self.version", + "drupal/book": "self.version", + "drupal/breakpoint": "self.version", + "drupal/ckeditor": "self.version", + "drupal/claro": "self.version", + "drupal/classy": "self.version", + "drupal/color": "self.version", + "drupal/comment": "self.version", + "drupal/config": "self.version", + "drupal/config_translation": "self.version", + "drupal/contact": "self.version", + "drupal/content_moderation": "self.version", + "drupal/content_translation": "self.version", + "drupal/contextual": "self.version", + "drupal/core-annotation": "self.version", + "drupal/core-assertion": "self.version", + "drupal/core-bridge": "self.version", + "drupal/core-class-finder": "self.version", + "drupal/core-datetime": "self.version", + "drupal/core-dependency-injection": "self.version", + "drupal/core-diff": "self.version", + "drupal/core-discovery": "self.version", + "drupal/core-event-dispatcher": "self.version", + "drupal/core-file-cache": "self.version", + "drupal/core-file-security": "self.version", + "drupal/core-filesystem": "self.version", + "drupal/core-gettext": "self.version", + "drupal/core-graph": "self.version", + "drupal/core-http-foundation": "self.version", + "drupal/core-php-storage": "self.version", + "drupal/core-plugin": "self.version", + "drupal/core-proxy-builder": "self.version", + "drupal/core-render": "self.version", + "drupal/core-serialization": "self.version", + "drupal/core-transliteration": "self.version", + "drupal/core-utility": "self.version", + "drupal/core-uuid": "self.version", + "drupal/core-version": "self.version", + "drupal/datetime": "self.version", + "drupal/datetime_range": "self.version", + "drupal/dblog": "self.version", + "drupal/dynamic_page_cache": "self.version", + "drupal/editor": "self.version", + "drupal/entity_reference": "self.version", + "drupal/field": "self.version", + "drupal/field_layout": "self.version", + "drupal/field_ui": "self.version", + "drupal/file": "self.version", + "drupal/filter": "self.version", + "drupal/forum": "self.version", + "drupal/hal": "self.version", + "drupal/help": "self.version", + "drupal/help_topics": "self.version", + "drupal/history": "self.version", + "drupal/image": "self.version", + "drupal/inline_form_errors": "self.version", + "drupal/jsonapi": "self.version", + "drupal/language": "self.version", + "drupal/layout_builder": "self.version", + "drupal/layout_discovery": "self.version", + "drupal/link": "self.version", + "drupal/locale": "self.version", + "drupal/media": "self.version", + "drupal/media_library": "self.version", + "drupal/menu_link_content": "self.version", + "drupal/menu_ui": "self.version", + "drupal/migrate": "self.version", + "drupal/migrate_drupal": "self.version", + "drupal/migrate_drupal_multilingual": "self.version", + "drupal/migrate_drupal_ui": "self.version", + "drupal/minimal": "self.version", + "drupal/node": "self.version", + "drupal/options": "self.version", + "drupal/page_cache": "self.version", + "drupal/path": "self.version", + "drupal/path_alias": "self.version", + "drupal/quickedit": "self.version", + "drupal/rdf": "self.version", + "drupal/responsive_image": "self.version", + "drupal/rest": "self.version", + "drupal/search": "self.version", + "drupal/serialization": "self.version", + "drupal/settings_tray": "self.version", + "drupal/seven": "self.version", + "drupal/shortcut": "self.version", + "drupal/simpletest": "self.version", + "drupal/standard": "self.version", + "drupal/stark": "self.version", + "drupal/statistics": "self.version", + "drupal/syslog": "self.version", + "drupal/system": "self.version", + "drupal/taxonomy": "self.version", + "drupal/telephone": "self.version", + "drupal/text": "self.version", + "drupal/toolbar": "self.version", + "drupal/tour": "self.version", + "drupal/tracker": "self.version", + "drupal/update": "self.version", + "drupal/user": "self.version", + "drupal/views": "self.version", + "drupal/views_ui": "self.version", + "drupal/workflows": "self.version", + "drupal/workspaces": "self.version" + }, + "type": "drupal-core", + "extra": { + "drupal-scaffold": { + "file-mapping": { + "[project-root]/.editorconfig": "assets/scaffold/files/editorconfig", + "[project-root]/.gitattributes": "assets/scaffold/files/gitattributes", + "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc", + "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore", + "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json", + "[web-root]/.ht.router.php": "assets/scaffold/files/ht.router.php", + "[web-root]/.htaccess": "assets/scaffold/files/htaccess", + "[web-root]/example.gitignore": "assets/scaffold/files/example.gitignore", + "[web-root]/index.php": "assets/scaffold/files/index.php", + "[web-root]/INSTALL.txt": "assets/scaffold/files/drupal.INSTALL.txt", + "[web-root]/README.txt": "assets/scaffold/files/drupal.README.txt", + "[web-root]/robots.txt": "assets/scaffold/files/robots.txt", + "[web-root]/update.php": "assets/scaffold/files/update.php", + "[web-root]/web.config": "assets/scaffold/files/web.config", + "[web-root]/sites/README.txt": "assets/scaffold/files/sites.README.txt", + "[web-root]/sites/development.services.yml": "assets/scaffold/files/development.services.yml", + "[web-root]/sites/example.settings.local.php": "assets/scaffold/files/example.settings.local.php", + "[web-root]/sites/example.sites.php": "assets/scaffold/files/example.sites.php", + "[web-root]/sites/default/default.services.yml": "assets/scaffold/files/default.services.yml", + "[web-root]/sites/default/default.settings.php": "assets/scaffold/files/default.settings.php", + "[web-root]/modules/README.txt": "assets/scaffold/files/modules.README.txt", + "[web-root]/profiles/README.txt": "assets/scaffold/files/profiles.README.txt", + "[web-root]/themes/README.txt": "assets/scaffold/files/themes.README.txt" + } + } + }, + "autoload": { + "psr-4": { + "Drupal\\Core\\": "lib/Drupal/Core", + "Drupal\\Component\\": "lib/Drupal/Component", + "Drupal\\Driver\\": "../drivers/lib/Drupal/Driver" + }, + "classmap": [ + "lib/Drupal.php", + "lib/Drupal/Component/Utility/Timer.php", + "lib/Drupal/Component/Utility/Unicode.php", + "lib/Drupal/Core/Database/Database.php", + "lib/Drupal/Core/DrupalKernel.php", + "lib/Drupal/Core/DrupalKernelInterface.php", + "lib/Drupal/Core/Site/Settings.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Drupal is an open source content management platform powering millions of websites and applications.", + "time": "2020-11-05T16:34:55+00:00" + }, + { + "name": "drupal/core-composer-scaffold", + "version": "8.9.8", + "source": { + "type": "git", + "url": "https://github.com/drupal/core-composer-scaffold.git", + "reference": "c902d07cb49ef73777e2b33a39e54c2861a8c81d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drupal/core-composer-scaffold/zipball/c902d07cb49ef73777e2b33a39e54c2861a8c81d", + "reference": "c902d07cb49ef73777e2b33a39e54c2861a8c81d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1 || ^2", + "php": ">=7.0.8" + }, + "conflict": { + "drupal-composer/drupal-scaffold": "*" + }, + "require-dev": { + "composer/composer": "^1.8@stable" + }, + "type": "composer-plugin", + "extra": { + "class": "Drupal\\Composer\\Plugin\\Scaffold\\Plugin", + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Drupal\\Composer\\Plugin\\Scaffold\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "A flexible Composer project scaffold builder.", + "homepage": "https://www.drupal.org/project/drupal", + "keywords": [ + "drupal" + ], + "time": "2020-08-07T22:30:30+00:00" + }, + { + "name": "drupal/core-recommended", + "version": "8.9.8", + "source": { + "type": "git", + "url": "https://github.com/drupal/core-recommended.git", + "reference": "561766436ccc17aa03362d740b004375fcc4d514" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/561766436ccc17aa03362d740b004375fcc4d514", + "reference": "561766436ccc17aa03362d740b004375fcc4d514", + "shasum": "" + }, + "require": { + "asm89/stack-cors": "1.3.0", + "composer/semver": "1.5.1", + "doctrine/annotations": "v1.4.0", + "doctrine/cache": "v1.6.2", + "doctrine/collections": "v1.4.0", + "doctrine/common": "v2.7.3", + "doctrine/inflector": "v1.2.0", + "doctrine/lexer": "1.0.2", + "drupal/core": "8.9.8", + "easyrdf/easyrdf": "0.9.1", + "egulias/email-validator": "2.1.17", + "guzzlehttp/guzzle": "6.5.4", + "guzzlehttp/promises": "v1.3.1", + "guzzlehttp/psr7": "1.6.1", + "laminas/laminas-diactoros": "1.8.7p2", + "laminas/laminas-escaper": "2.6.1", + "laminas/laminas-feed": "2.12.2", + "laminas/laminas-stdlib": "3.2.1", + "laminas/laminas-zendframework-bridge": "1.0.4", + "masterminds/html5": "2.3.0", + "paragonie/random_compat": "v9.99.99", + "pear/archive_tar": "1.4.9", + "pear/console_getopt": "v1.4.3", + "pear/pear-core-minimal": "v1.10.10", + "pear/pear_exception": "v1.0.1", + "psr/container": "1.0.0", + "psr/http-message": "1.0.1", + "psr/log": "1.1.3", + "ralouphie/getallheaders": "3.0.3", + "stack/builder": "v1.0.5", + "symfony-cmf/routing": "1.4.1", + "symfony/class-loader": "v3.4.41", + "symfony/console": "v3.4.41", + "symfony/debug": "v3.4.41", + "symfony/dependency-injection": "v3.4.41", + "symfony/event-dispatcher": "v3.4.41", + "symfony/http-foundation": "v3.4.41", + "symfony/http-kernel": "v3.4.44", + "symfony/polyfill-ctype": "v1.17.0", + "symfony/polyfill-iconv": "v1.17.0", + "symfony/polyfill-intl-idn": "v1.17.0", + "symfony/polyfill-mbstring": "v1.17.0", + "symfony/polyfill-php56": "v1.17.0", + "symfony/polyfill-php70": "v1.17.0", + "symfony/polyfill-php72": "v1.17.0", + "symfony/polyfill-util": "v1.17.0", + "symfony/process": "v3.4.41", + "symfony/psr-http-message-bridge": "v1.1.2", + "symfony/routing": "v3.4.41", + "symfony/serializer": "v3.4.41", + "symfony/translation": "v3.4.41", + "symfony/validator": "v3.4.41", + "symfony/yaml": "v3.4.41", + "twig/twig": "v1.42.5", + "typo3/phar-stream-wrapper": "v3.1.4" + }, + "conflict": { + "webflo/drupal-core-strict": "*" + }, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Locked core dependencies; require this project INSTEAD OF drupal/core.", + "time": "2020-11-05T16:34:55+00:00" + }, + { + "name": "drush/drush", + "version": "10.3.6", + "source": { + "type": "git", + "url": "https://github.com/drush-ops/drush.git", + "reference": "fc985a95c6010e04891a2dbcf3f39984b8c9ef0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drush-ops/drush/zipball/fc985a95c6010e04891a2dbcf3f39984b8c9ef0a", + "reference": "fc985a95c6010e04891a2dbcf3f39984b8c9ef0a", + "shasum": "" + }, + "require": { + "chi-teck/drupal-code-generator": "^1.32.1", + "composer/semver": "^1.4 || ^3", + "consolidation/config": "^1.2", + "consolidation/filter-via-dot-access-data": "^1", + "consolidation/robo": "^1.4.11 || ^2", + "consolidation/site-alias": "^3.0.0@stable", + "consolidation/site-process": "^2.1 || ^4", + "ext-dom": "*", + "grasmash/yaml-expander": "^1.1.1", + "guzzlehttp/guzzle": "^6.3 || ^7.0", + "league/container": "~2", + "php": ">=7.1.3", + "psr/log": "~1.0", + "psy/psysh": "~0.6", + "symfony/event-dispatcher": "^3.4 || ^4.0", + "symfony/finder": "^3.4 || ^4.0 || ^5", + "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0", + "symfony/yaml": "^3.4 || ^4.0", + "webflo/drupal-finder": "^1.2", + "webmozart/path-util": "^2.1.0" + }, + "require-dev": { + "composer/installers": "^1.7", + "cweagans/composer-patches": "~1.0", + "david-garcia/phpwhois": "4.3.0", + "drupal/alinks": "1.0.0", + "drupal/core-recommended": "^8.8", + "lox/xhprof": "dev-master", + "phpunit/phpunit": "^4.8.36 || ^6.1", + "squizlabs/php_codesniffer": "^2.7 || ^3", + "vlucas/phpdotenv": "^2.4" + }, + "bin": [ + "drush" + ], + "type": "library", + "extra": { + "installer-paths": { + "sut/core": [ + "type:drupal-core" + ], + "sut/libraries/{$name}": [ + "type:drupal-library" + ], + "sut/modules/unish/{$name}": [ + "drupal/devel" + ], + "sut/themes/unish/{$name}": [ + "drupal/empty_theme" + ], + "sut/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "sut/profiles/contrib/{$name}": [ + "type:drupal-profile" + ], + "sut/themes/contrib/{$name}": [ + "type:drupal-theme" + ], + "sut/drush/contrib/{$name}": [ + "type:drupal-drush" + ] + } + }, + "autoload": { + "psr-4": { + "Drush\\": "src/", + "Drush\\Internal\\": "src/internal-forks" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + }, + { + "name": "Owen Barton", + "email": "drupal@owenbarton.com" + }, + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Jonathan Araña Cruz", + "email": "jonhattan@faita.net" + }, + { + "name": "Jonathan Hedstrom", + "email": "jhedstrom@gmail.com" + }, + { + "name": "Christopher Gervais", + "email": "chris@ergonlogic.com" + }, + { + "name": "Dave Reid", + "email": "dave@davereid.net" + }, + { + "name": "Damian Lee", + "email": "damiankloip@googlemail.com" + } + ], + "description": "Drush is a command line shell and scripting interface for Drupal, a veritable Swiss Army knife designed to make life easier for those of us who spend some of our working hours hacking away at the command prompt.", + "homepage": "http://www.drush.org", + "funding": [ + { + "url": "https://github.com/weitzman", + "type": "github" + } + ], + "time": "2020-11-11T04:36:51+00:00" + }, + { + "name": "easyrdf/easyrdf", + "version": "0.9.1", + "source": { + "type": "git", + "url": "https://github.com/easyrdf/easyrdf.git", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/easyrdf/easyrdf/zipball/acd09dfe0555fbcfa254291e433c45fdd4652566", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-pcre": "*", + "php": ">=5.2.8" + }, + "require-dev": { + "phpunit/phpunit": "~3.5", + "sami/sami": "~1.4", + "squizlabs/php_codesniffer": "~1.4.3" + }, + "suggest": { + "ml/json-ld": "~1.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "EasyRdf_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nicholas Humfrey", + "email": "njh@aelius.com", + "homepage": "http://www.aelius.com/njh/", + "role": "Developer" + }, + { + "name": "Alexey Zakhlestin", + "email": "indeyets@gmail.com", + "role": "Developer" + } + ], + "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", + "homepage": "http://www.easyrdf.org/", + "keywords": [ + "Linked Data", + "RDF", + "Semantic Web", + "Turtle", + "rdfa", + "sparql" + ], + "time": "2015-02-27T09:45:49+00:00" + }, + { + "name": "egulias/email-validator", + "version": "2.1.17", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "ade6887fd9bd74177769645ab5c474824f8a418a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ade6887fd9bd74177769645ab5c474824f8a418a", + "reference": "ade6887fd9bd74177769645ab5c474824f8a418a", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.0.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.10" + }, + "require-dev": { + "dominicsayers/isemail": "^3.0.7", + "phpunit/phpunit": "^4.8.36|^7.5.15", + "satooshi/php-coveralls": "^1.0.1" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "EmailValidator" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "time": "2020-02-13T22:36:52+00:00" + }, + { + "name": "grasmash/expander", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/grasmash/expander.git", + "reference": "95d6037344a4be1dd5f8e0b0b2571a28c397578f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/grasmash/expander/zipball/95d6037344a4be1dd5f8e0b0b2571a28c397578f", + "reference": "95d6037344a4be1dd5f8e0b0b2571a28c397578f", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.4" + }, + "require-dev": { + "greg-1-anderson/composer-test-scenarios": "^1", + "phpunit/phpunit": "^4|^5.5.4", + "satooshi/php-coveralls": "^1.0.2|dev-master", + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Grasmash\\Expander\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Grasmick" + } + ], + "description": "Expands internal property references in PHP arrays file.", + "time": "2017-12-21T22:14:55+00:00" + }, + { + "name": "grasmash/yaml-expander", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/grasmash/yaml-expander.git", + "reference": "3f0f6001ae707a24f4d9733958d77d92bf9693b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/grasmash/yaml-expander/zipball/3f0f6001ae707a24f4d9733958d77d92bf9693b1", + "reference": "3f0f6001ae707a24f4d9733958d77d92bf9693b1", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.4", + "symfony/yaml": "^2.8.11|^3|^4" + }, + "require-dev": { + "greg-1-anderson/composer-test-scenarios": "^1", + "phpunit/phpunit": "^4.8|^5.5.4", + "satooshi/php-coveralls": "^1.0.2|dev-master", + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Grasmash\\YamlExpander\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Grasmick" + } + ], + "description": "Expands internal property references in a yaml file.", + "time": "2017-12-16T16:06:03+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.4", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a4a1b6930528a8f7ee03518e6442ec7a44155d9d", + "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "1.17.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2020-05-25T19:35:05+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "laminas/laminas-diactoros", + "version": "1.8.7p2", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-diactoros.git", + "reference": "6991c1af7c8d2c8efee81b22ba97024781824aaa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6991c1af7c8d2c8efee81b22ba97024781824aaa", + "reference": "6991c1af7c8d2c8efee81b22ba97024781824aaa", + "shasum": "" + }, + "require": { + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "replace": { + "zendframework/zend-diactoros": "~1.8.7.0" + }, + "require-dev": { + "ext-dom": "*", + "ext-libxml": "*", + "laminas/laminas-coding-standard": "~1.0", + "php-http/psr7-integration-tests": "dev-master", + "phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-release-1.8": "1.8.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions/create_uploaded_file.php", + "src/functions/marshal_headers_from_sapi.php", + "src/functions/marshal_method_from_sapi.php", + "src/functions/marshal_protocol_version_from_sapi.php", + "src/functions/marshal_uri_from_sapi.php", + "src/functions/normalize_server.php", + "src/functions/normalize_uploaded_files.php", + "src/functions/parse_cookie_header.php", + "src/functions/create_uploaded_file.legacy.php", + "src/functions/marshal_headers_from_sapi.legacy.php", + "src/functions/marshal_method_from_sapi.legacy.php", + "src/functions/marshal_protocol_version_from_sapi.legacy.php", + "src/functions/marshal_uri_from_sapi.legacy.php", + "src/functions/normalize_server.legacy.php", + "src/functions/normalize_uploaded_files.legacy.php", + "src/functions/parse_cookie_header.legacy.php" + ], + "psr-4": { + "Laminas\\Diactoros\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "PSR HTTP Message implementations", + "homepage": "https://laminas.dev", + "keywords": [ + "http", + "laminas", + "psr", + "psr-7" + ], + "time": "2020-03-23T15:28:28+00:00" + }, + { + "name": "laminas/laminas-escaper", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-escaper.git", + "reference": "25f2a053eadfa92ddacb609dcbbc39362610da70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/25f2a053eadfa92ddacb609dcbbc39362610da70", + "reference": "25f2a053eadfa92ddacb609dcbbc39362610da70", + "shasum": "" + }, + "require": { + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-escaper": "self.version" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~1.0.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Escaper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", + "homepage": "https://laminas.dev", + "keywords": [ + "escaper", + "laminas" + ], + "time": "2019-12-31T16:43:30+00:00" + }, + { + "name": "laminas/laminas-feed", + "version": "2.12.2", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-feed.git", + "reference": "8a193ac96ebcb3e16b6ee754ac2a889eefacb654" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-feed/zipball/8a193ac96ebcb3e16b6ee754ac2a889eefacb654", + "reference": "8a193ac96ebcb3e16b6ee754ac2a889eefacb654", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "laminas/laminas-escaper": "^2.5.2", + "laminas/laminas-stdlib": "^3.2.1", + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-feed": "^2.12.0" + }, + "require-dev": { + "laminas/laminas-cache": "^2.7.2", + "laminas/laminas-coding-standard": "~1.0.0", + "laminas/laminas-db": "^2.8.2", + "laminas/laminas-http": "^2.7", + "laminas/laminas-servicemanager": "^2.7.8 || ^3.3", + "laminas/laminas-validator": "^2.10.1", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20", + "psr/http-message": "^1.0.1" + }, + "suggest": { + "laminas/laminas-cache": "Laminas\\Cache component, for optionally caching feeds between requests", + "laminas/laminas-db": "Laminas\\Db component, for use with PubSubHubbub", + "laminas/laminas-http": "Laminas\\Http for PubSubHubbub, and optionally for use with Laminas\\Feed\\Reader", + "laminas/laminas-servicemanager": "Laminas\\ServiceManager component, for easily extending ExtensionManager implementations", + "laminas/laminas-validator": "Laminas\\Validator component, for validating email addresses used in Atom feeds and entries when using the Writer subcomponent", + "psr/http-message": "PSR-7 ^1.0.1, if you wish to use Laminas\\Feed\\Reader\\Http\\Psr7ResponseDecorator" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.12.x-dev", + "dev-develop": "2.13.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Feed\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides functionality for consuming RSS and Atom feeds", + "homepage": "https://laminas.dev", + "keywords": [ + "feed", + "laminas" + ], + "time": "2020-03-29T12:36:29+00:00" + }, + { + "name": "laminas/laminas-stdlib", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-stdlib.git", + "reference": "2b18347625a2f06a1a485acfbc870f699dbe51c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/2b18347625a2f06a1a485acfbc870f699dbe51c6", + "reference": "2b18347625a2f06a1a485acfbc870f699dbe51c6", + "shasum": "" + }, + "require": { + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-stdlib": "self.version" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~1.0.0", + "phpbench/phpbench": "^0.13", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev", + "dev-develop": "3.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Stdlib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "SPL extensions, array utilities, error handlers, and more", + "homepage": "https://laminas.dev", + "keywords": [ + "laminas", + "stdlib" + ], + "time": "2019-12-31T17:51:15+00:00" + }, + { + "name": "laminas/laminas-zendframework-bridge", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-zendframework-bridge.git", + "reference": "fcd87520e4943d968557803919523772475e8ea3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/fcd87520e4943d968557803919523772475e8ea3", + "reference": "fcd87520e4943d968557803919523772475e8ea3", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev", + "dev-develop": "1.1.x-dev" + }, + "laminas": { + "module": "Laminas\\ZendFrameworkBridge" + } + }, + "autoload": { + "files": [ + "src/autoload.php" + ], + "psr-4": { + "Laminas\\ZendFrameworkBridge\\": "src//" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Alias legacy ZF class names to Laminas Project equivalents.", + "keywords": [ + "ZendFramework", + "autoloading", + "laminas", + "zf" + ], + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2020-05-20T16:45:56+00:00" + }, + { + "name": "league/container", + "version": "2.4.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/container.git", + "reference": "43f35abd03a12977a60ffd7095efd6a7808488c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/container/zipball/43f35abd03a12977a60ffd7095efd6a7808488c0", + "reference": "43f35abd03a12977a60ffd7095efd6a7808488c0", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.2", + "php": "^5.4.0 || ^7.0" + }, + "provide": { + "container-interop/container-interop-implementation": "^1.2", + "psr/container-implementation": "^1.0" + }, + "replace": { + "orno/di": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Container\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Bennett", + "email": "philipobenito@gmail.com", + "homepage": "http://www.philipobenito.com", + "role": "Developer" + } + ], + "description": "A fast and intuitive dependency injection container.", + "homepage": "https://github.com/thephpleague/container", + "keywords": [ + "container", + "dependency", + "di", + "injection", + "league", + "provider", + "service" + ], + "time": "2017-05-10T09:20:27+00:00" + }, + { + "name": "masterminds/html5", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "2c37c6c520b995b761674de3be8455a381679067" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/2c37c6c520b995b761674de3be8455a381679067", + "reference": "2c37c6c520b995b761674de3be8455a381679067", + "shasum": "" + }, + "require": { + "ext-libxml": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "sami/sami": "~2.0", + "satooshi/php-coveralls": "1.0.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ], + "time": "2017-09-04T12:26:28+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.10.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "658f1be311a230e0907f5dfe0213742aff0596de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de", + "reference": "658f1be311a230e0907f5dfe0213742aff0596de", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2020-09-26T10:30:38+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" + }, + { + "name": "pear/archive_tar", + "version": "1.4.9", + "source": { + "type": "git", + "url": "https://github.com/pear/Archive_Tar.git", + "reference": "c5b00053770e1d72128252c62c2c1a12c26639f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/c5b00053770e1d72128252c62c2c1a12c26639f0", + "reference": "c5b00053770e1d72128252c62c2c1a12c26639f0", + "shasum": "" + }, + "require": { + "pear/pear-core-minimal": "^1.10.0alpha2", + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-bz2": "Bz2 compression support.", + "ext-xz": "Lzma2 compression support.", + "ext-zlib": "Gzip compression support." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Archive_Tar": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Vincent Blavet", + "email": "vincent@phpconcept.net" + }, + { + "name": "Greg Beaver", + "email": "greg@chiaraquartet.net" + }, + { + "name": "Michiel Rook", + "email": "mrook@php.net" + } + ], + "description": "Tar file management class with compression support (gzip, bzip2, lzma2)", + "homepage": "https://github.com/pear/Archive_Tar", + "keywords": [ + "archive", + "tar" + ], + "time": "2019-12-04T10:17:28+00:00" + }, + { + "name": "pear/console_getopt", + "version": "v1.4.3", + "source": { + "type": "git", + "url": "https://github.com/pear/Console_Getopt.git", + "reference": "a41f8d3e668987609178c7c4a9fe48fecac53fa0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Console_Getopt/zipball/a41f8d3e668987609178c7c4a9fe48fecac53fa0", + "reference": "a41f8d3e668987609178c7c4a9fe48fecac53fa0", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Console": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Andrei Zmievski", + "email": "andrei@php.net", + "role": "Lead" + }, + { + "name": "Stig Bakken", + "email": "stig@php.net", + "role": "Developer" + }, + { + "name": "Greg Beaver", + "email": "cellog@php.net", + "role": "Helper" + } + ], + "description": "More info available on: http://pear.php.net/package/Console_Getopt", + "time": "2019-11-20T18:27:48+00:00" + }, + { + "name": "pear/pear-core-minimal", + "version": "v1.10.10", + "source": { + "type": "git", + "url": "https://github.com/pear/pear-core-minimal.git", + "reference": "625a3c429d9b2c1546438679074cac1b089116a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/625a3c429d9b2c1546438679074cac1b089116a7", + "reference": "625a3c429d9b2c1546438679074cac1b089116a7", + "shasum": "" + }, + "require": { + "pear/console_getopt": "~1.4", + "pear/pear_exception": "~1.0" + }, + "replace": { + "rsky/pear-core-min": "self.version" + }, + "type": "library", + "autoload": { + "psr-0": { + "": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "src/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@php.net", + "role": "Lead" + } + ], + "description": "Minimal set of PEAR core files to be used as composer dependency", + "time": "2019-11-19T19:00:24+00:00" + }, + { + "name": "pear/pear_exception", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/pear/PEAR_Exception.git", + "reference": "dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7", + "reference": "dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7", + "shasum": "" + }, + "require": { + "php": ">=4.4.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "class", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "PEAR/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "." + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Helgi Thormar", + "email": "dufuz@php.net" + }, + { + "name": "Greg Beaver", + "email": "cellog@php.net" + } + ], + "description": "The PEAR Exception base class.", + "homepage": "https://github.com/pear/PEAR_Exception", + "keywords": [ + "exception" + ], + "time": "2019-12-10T10:24:42+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.10.4", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "a8aec1b2981ab66882a01cce36a49b6317dc3560" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/a8aec1b2981ab66882a01cce36a49b6317dc3560", + "reference": "a8aec1b2981ab66882a01cce36a49b6317dc3560", + "shasum": "" + }, + "require": { + "dnoegel/php-xdg-base-dir": "0.1.*", + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "~4.0|~3.0|~2.0|~1.3", + "php": "^8.0 || ^7.0 || ^5.5.9", + "symfony/console": "~5.0|~4.0|~3.0|^2.4.2|~2.3.10", + "symfony/var-dumper": "~5.0|~4.0|~3.0|~2.7" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "hoa/console": "3.17.*" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", + "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.10.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "time": "2020-05-03T19:32:03+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "stack/builder", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/stackphp/builder.git", + "reference": "fb3d136d04c6be41120ebf8c0cc71fe9507d750a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stackphp/builder/zipball/fb3d136d04c6be41120ebf8c0cc71fe9507d750a", + "reference": "fb3d136d04c6be41120ebf8c0cc71fe9507d750a", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/http-foundation": "~2.1|~3.0|~4.0", + "symfony/http-kernel": "~2.1|~3.0|~4.0" + }, + "require-dev": { + "silex/silex": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Stack": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Builder for stack middlewares based on HttpKernelInterface.", + "keywords": [ + "stack" + ], + "time": "2017-11-18T14:57:29+00:00" + }, + { + "name": "symfony-cmf/routing", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony-cmf/routing.git", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony-cmf/routing/zipball/fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", + "shasum": "" + }, + "require": { + "php": "^5.3.9|^7.0", + "psr/log": "1.*", + "symfony/http-kernel": "^2.2|3.*", + "symfony/routing": "^2.2|3.*" + }, + "require-dev": { + "friendsofsymfony/jsrouting-bundle": "^1.1", + "symfony-cmf/testing": "^1.3", + "symfony/config": "^2.2|3.*", + "symfony/dependency-injection": "^2.0.5|3.*", + "symfony/event-dispatcher": "^2.1|3.*" + }, + "suggest": { + "symfony/event-dispatcher": "DynamicRouter can optionally trigger an event at the start of matching. Minimal version (~2.1)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Cmf\\Component\\Routing\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony CMF Community", + "homepage": "https://github.com/symfony-cmf/Routing/contributors" + } + ], + "description": "Extends the Symfony2 routing component for dynamic routes and chaining several routers", + "homepage": "http://cmf.symfony.com", + "keywords": [ + "database", + "routing" + ], + "time": "2017-05-09T08:10:41+00:00" + }, + { + "name": "symfony/class-loader", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/class-loader.git", + "reference": "e4636a4f23f157278a19e5db160c63de0da297d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/e4636a4f23f157278a19e5db160c63de0da297d8", + "reference": "e4636a4f23f157278a19e5db160c63de0da297d8", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "require-dev": { + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/polyfill-apcu": "~1.1" + }, + "suggest": { + "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\ClassLoader\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ClassLoader Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-03-15T09:38:08+00:00" + }, + { + "name": "symfony/console", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "bfe29ead7e7b1cc9ce74c6a40d06ad1f96fced13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/bfe29ead7e7b1cc9ce74c6a40d06ad1f96fced13", + "reference": "bfe29ead7e7b1cc9ce74c6a40d06ad1f96fced13", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/debug": "~2.8|~3.0|~4.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.3|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.3|~4.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-30T18:58:05+00:00" + }, + { + "name": "symfony/debug", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "518c6a00d0872da30bd06aee3ea59a0a5cf54d6d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/518c6a00d0872da30bd06aee3ea59a0a5cf54d6d", + "reference": "518c6a00d0872da30bd06aee3ea59a0a5cf54d6d", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/http-kernel": "~2.8|~3.0|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-22T18:25:20+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "e39380b7104b0ec538a075ae919f00c7e5267bac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e39380b7104b0ec538a075ae919f00c7e5267bac", + "reference": "e39380b7104b0ec538a075ae919f00c7e5267bac", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/container": "^1.0" + }, + "conflict": { + "symfony/config": "<3.3.7", + "symfony/finder": "<3.3", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-30T21:06:01+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "14d978f8e8555f2de719c00eb65376be7d2e9081" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/14d978f8e8555f2de719c00eb65376be7d2e9081", + "reference": "14d978f8e8555f2de719c00eb65376be7d2e9081", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "conflict": { + "symfony/dependency-injection": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/stopwatch": "~2.8|~3.0|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-05T15:06:23+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e58d7841cddfed6e846829040dca2cca0ebbbbb3", + "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/finder", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "4e1da3c110c52d868f8a9153b7de3ebc381fba78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/4e1da3c110c52d868f8a9153b7de3ebc381fba78", + "reference": "4e1da3c110c52d868f8a9153b7de3ebc381fba78", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "fbd216d2304b1a3fe38d6392b04729c8dd356359" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/fbd216d2304b1a3fe38d6392b04729c8dd356359", + "reference": "fbd216d2304b1a3fe38d6392b04729c8dd356359", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php70": "~1.6" + }, + "require-dev": { + "symfony/expression-language": "~2.8|~3.0|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-16T13:15:54+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v3.4.44", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/27dcaa8c6b18c75df9f37badeb4d3564ffaa1326", + "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/log": "~1.0", + "symfony/debug": "^3.3.3|~4.0", + "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/http-foundation": "~3.4.12|~4.0.12|^4.1.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php56": "~1.8" + }, + "conflict": { + "symfony/config": "<2.8", + "symfony/dependency-injection": "<3.4.10|<4.0.10,>=4", + "symfony/var-dumper": "<3.3", + "twig/twig": "<1.34|<2.4,>=2" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/cache": "~1.0", + "symfony/browser-kit": "~2.8|~3.0|~4.0", + "symfony/class-loader": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/console": "~2.8|~3.0|~4.0", + "symfony/css-selector": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "^3.4.10|^4.0.10", + "symfony/dom-crawler": "~2.8|~3.0|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/process": "~2.8|~3.0|~4.0", + "symfony/routing": "~3.4|~4.0", + "symfony/stopwatch": "~2.8|~3.0|~4.0", + "symfony/templating": "~2.8|~3.0|~4.0", + "symfony/translation": "~2.8|~3.0|~4.0", + "symfony/var-dumper": "~3.3|~4.0" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "", + "symfony/var-dumper": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpKernel Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-08-31T05:53:42+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:14:59+00:00" + }, + { + "name": "symfony/polyfill-iconv", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-iconv.git", + "reference": "c4de7601eefbf25f9d47190abe07f79fe0a27424" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/c4de7601eefbf25f9d47190abe07f79fe0a27424", + "reference": "c4de7601eefbf25f9d47190abe07f79fe0a27424", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-iconv": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Iconv\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Iconv extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "iconv", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php56", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php56.git", + "reference": "e3c8c138280cdfe4b81488441555583aa1984e23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/e3c8c138280cdfe4b81488441555583aa1984e23", + "reference": "e3c8c138280cdfe4b81488441555583aa1984e23", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-util": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php56\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "82225c2d7d23d7e70515496d249c0152679b468e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/82225c2d7d23d7e70515496d249c0152679b468e", + "reference": "82225c2d7d23d7e70515496d249c0152679b468e", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "f048e612a3905f34931127360bdd2def19a5e582" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582", + "reference": "f048e612a3905f34931127360bdd2def19a5e582", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-util", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-util.git", + "reference": "4afb4110fc037752cf0ce9869f9ab8162c4e20d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/4afb4110fc037752cf0ce9869f9ab8162c4e20d7", + "reference": "4afb4110fc037752cf0ce9869f9ab8162c4e20d7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Util\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony utilities for portability of PHP codes", + "homepage": "https://symfony.com", + "keywords": [ + "compat", + "compatibility", + "polyfill", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:14:59+00:00" + }, + { + "name": "symfony/process", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "8a895f0c92a7c4b10db95139bcff71bdf66d4d21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/8a895f0c92a7c4b10db95139bcff71bdf66d4d21", + "reference": "8a895f0c92a7c4b10db95139bcff71bdf66d4d21", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-23T17:05:51+00:00" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "a33352af16f78a5ff4f9d90811536abf210df12b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/a33352af16f78a5ff4f9d90811536abf210df12b", + "reference": "a33352af16f78a5ff4f9d90811536abf210df12b", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^2.3.42 || ^3.4 || ^4.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3.4 || ^4.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "time": "2019-04-03T17:09:40+00:00" + }, + { + "name": "symfony/routing", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "e0d43b6f9417ad59ecaa8e2f799b79eef417387f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/e0d43b6f9417ad59ecaa8e2f799b79eef417387f", + "reference": "e0d43b6f9417ad59ecaa8e2f799b79eef417387f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "conflict": { + "symfony/config": "<3.3.1", + "symfony/dependency-injection": "<3.3", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "psr/log": "~1.0", + "symfony/config": "^3.3.1|~4.0", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/http-foundation": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-30T19:50:06+00:00" + }, + { + "name": "symfony/serializer", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/serializer.git", + "reference": "0db90db012b1b0a04fbb2d64ae9160871cad9d4f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/serializer/zipball/0db90db012b1b0a04fbb2d64ae9160871cad9d4f", + "reference": "0db90db012b1b0a04fbb2d64ae9160871cad9d4f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "phpdocumentor/type-resolver": "<0.2.1", + "symfony/dependency-injection": "<3.2", + "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4", + "symfony/property-info": "<3.1", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0", + "symfony/cache": "~3.1|~4.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.2|~4.0", + "symfony/http-foundation": "~2.8|~3.0|~4.0", + "symfony/property-access": "~2.8|~3.0|~4.0", + "symfony/property-info": "^3.4.13|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "psr/cache-implementation": "For using the metadata cache.", + "symfony/config": "For using the XML mapping loader.", + "symfony/http-foundation": "For using a MIME type guesser within the DataUriNormalizer.", + "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/property-info": "To deserialize relations.", + "symfony/yaml": "For using the default YAML mapping loader." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Serializer Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-30T18:58:05+00:00" + }, + { + "name": "symfony/translation", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "b0cd62ef0ff7ec31b67d78d7fc818e2bda4e844f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/b0cd62ef0ff7ec31b67d78d7fc818e2bda4e844f", + "reference": "b0cd62ef0ff7ec31b67d78d7fc818e2bda4e844f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<2.8", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/http-kernel": "~3.4|~4.0", + "symfony/intl": "^2.8.18|^3.2.5|~4.0", + "symfony/var-dumper": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-30T18:58:05+00:00" + }, + { + "name": "symfony/validator", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/validator.git", + "reference": "5fb88120a11a75e17b602103a893dd8b27804529" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/validator/zipball/5fb88120a11a75e17b602103a893dd8b27804529", + "reference": "5fb88120a11a75e17b602103a893dd8b27804529", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation": "~2.8|~3.0|~4.0" + }, + "conflict": { + "doctrine/lexer": "<1.0.2", + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/dependency-injection": "<3.3", + "symfony/http-kernel": "<3.3.5", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.7", + "doctrine/cache": "~1.0", + "egulias/email-validator": "^2.1.10", + "symfony/cache": "~3.1|~4.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/http-foundation": "~2.8|~3.0|~4.0", + "symfony/http-kernel": "^3.3.5|~4.0", + "symfony/intl": "^2.8.18|^3.2.5|~4.0", + "symfony/property-access": "~2.8|~3.0|~4.0", + "symfony/var-dumper": "~3.3|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "egulias/email-validator": "Strict (RFC compliant) email validation", + "psr/cache-implementation": "For using the metadata cache.", + "symfony/config": "", + "symfony/expression-language": "For using the Expression validator", + "symfony/http-foundation": "", + "symfony/intl": "", + "symfony/property-access": "For accessing properties within comparison constraints", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Validator\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Validator Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-30T18:43:38+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v4.4.16", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "3718e18b68d955348ad860e505991802c09f5f73" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3718e18b68d955348ad860e505991802c09f5f73", + "reference": "3718e18b68d955348ad860e505991802c09f5f73", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php72": "~1.5", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/console": "<3.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/process": "^4.4|^5.0", + "twig/twig": "^1.34|^2.4|^3.0" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-26T20:47:51+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "7233ac2bfdde24d672f5305f2b3f6b5d741ef8eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/7233ac2bfdde24d672f5305f2b3f6b5d741ef8eb", + "reference": "7233ac2bfdde24d672f5305f2b3f6b5d741ef8eb", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-11T07:51:54+00:00" + }, + { + "name": "twig/twig", + "version": "v1.42.5", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e", + "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "symfony/polyfill-ctype": "^1.8" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.42-dev" + } + }, + "autoload": { + "psr-0": { + "Twig_": "lib/" + }, + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "time": "2020-02-11T05:59:23+00:00" + }, + { + "name": "typo3/phar-stream-wrapper", + "version": "v3.1.4", + "source": { + "type": "git", + "url": "https://github.com/TYPO3/phar-stream-wrapper.git", + "reference": "e0c1b495cfac064f4f5c4bcb6bf67bb7f345ed04" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TYPO3/phar-stream-wrapper/zipball/e0c1b495cfac064f4f5c4bcb6bf67bb7f345ed04", + "reference": "e0c1b495cfac064f4f5c4bcb6bf67bb7f345ed04", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.0" + }, + "require-dev": { + "ext-xdebug": "*", + "phpunit/phpunit": "^6.5" + }, + "suggest": { + "ext-fileinfo": "For PHP builtin file type guessing, otherwise uses internal processing" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "v3.x-dev" + } + }, + "autoload": { + "psr-4": { + "TYPO3\\PharStreamWrapper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Interceptors for PHP's native phar:// stream handling", + "homepage": "https://typo3.org/", + "keywords": [ + "phar", + "php", + "security", + "stream-wrapper" + ], + "time": "2019-12-10T11:53:27+00:00" + }, + { + "name": "webflo/drupal-finder", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/webflo/drupal-finder.git", + "reference": "c8e5dbe65caef285fec8057a4c718a0d4138d1ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/c8e5dbe65caef285fec8057a4c718a0d4138d1ee", + "reference": "c8e5dbe65caef285fec8057a4c718a0d4138d1ee", + "shasum": "" + }, + "require": { + "ext-json": "*" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^4.8" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/DrupalFinder.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Florian Weber", + "email": "florian@webflo.org" + } + ], + "description": "Helper class to locate a Drupal installation from a given path.", + "time": "2020-10-27T09:42:17+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2020-07-08T17:02:28+00:00" + }, + { + "name": "webmozart/path-util", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "time": "2015-12-17T08:42:14+00:00" + } + ], + "packages-dev": [ + { + "name": "behat/mink", + "version": "v1.8.1", + "source": { + "type": "git", + "url": "https://github.com/minkphp/Mink.git", + "reference": "07c6a9fe3fa98c2de074b25d9ed26c22904e3887" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/07c6a9fe3fa98c2de074b25d9ed26c22904e3887", + "reference": "07c6a9fe3fa98c2de074b25d9ed26c22904e3887", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/css-selector": "^2.7|^3.0|^4.0|^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20", + "symfony/debug": "^2.7|^3.0|^4.0", + "symfony/phpunit-bridge": "^3.4.38 || ^5.0.5" + }, + "suggest": { + "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", + "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation", + "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", + "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)", + "dmore/chrome-mink-driver": "fast and JS-enabled driver for any app (requires chromium or google chrome)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Browser controller/emulator abstraction for PHP", + "homepage": "http://mink.behat.org/", + "keywords": [ + "browser", + "testing", + "web" + ], + "time": "2020-03-11T15:45:53+00:00" + }, + { + "name": "behat/mink-browserkit-driver", + "version": "v1.3.4", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkBrowserKitDriver.git", + "reference": "e3b90840022ebcd544c7b394a3c9597ae242cbee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/e3b90840022ebcd544c7b394a3c9597ae242cbee", + "reference": "e3b90840022ebcd544c7b394a3c9597ae242cbee", + "shasum": "" + }, + "require": { + "behat/mink": "^1.7.1@dev", + "php": ">=5.3.6", + "symfony/browser-kit": "~2.3|~3.0|~4.0", + "symfony/dom-crawler": "~2.3|~3.0|~4.0" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master", + "symfony/debug": "^2.7|^3.0|^4.0", + "symfony/http-kernel": "~2.3|~3.0|~4.0" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Symfony2 BrowserKit driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "Mink", + "Symfony2", + "browser", + "testing" + ], + "time": "2020-03-11T09:49:45+00:00" + }, + { + "name": "behat/mink-goutte-driver", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkGoutteDriver.git", + "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", + "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", + "shasum": "" + }, + "require": { + "behat/mink": "~1.6@dev", + "behat/mink-browserkit-driver": "~1.2@dev", + "fabpot/goutte": "~1.0.4|~2.0|~3.1", + "php": ">=5.3.1" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7|~3.0" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Goutte driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "browser", + "goutte", + "headless", + "testing" + ], + "time": "2016-03-05T09:04:22+00:00" + }, + { + "name": "behat/mink-selenium2-driver", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkSelenium2Driver.git", + "reference": "312a967dd527f28980cce40850339cd5316da092" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/312a967dd527f28980cce40850339cd5316da092", + "reference": "312a967dd527f28980cce40850339cd5316da092", + "shasum": "" + }, + "require": { + "behat/mink": "~1.7@dev", + "instaclick/php-webdriver": "~1.1", + "php": ">=5.4" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Pete Otaqui", + "email": "pete@otaqui.com", + "homepage": "https://github.com/pete-otaqui" + }, + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Selenium2 (WebDriver) driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "ajax", + "browser", + "javascript", + "selenium", + "testing", + "webdriver" + ], + "time": "2020-03-11T14:43:21+00:00" + }, + { + "name": "composer/ca-bundle", + "version": "1.2.8", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "8a7ecad675253e4654ea05505233285377405215" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8a7ecad675253e4654ea05505233285377405215", + "reference": "8a7ecad675253e4654ea05505233285377405215", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-08-23T12:54:47+00:00" + }, + { + "name": "composer/composer", + "version": "1.10.17", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "09d42e18394d8594be24e37923031c4b7442a1cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/09d42e18394d8594be24e37923031c4b7442a1cb", + "reference": "09d42e18394d8594be24e37923031c4b7442a1cb", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.2", + "composer/xdebug-handler": "^1.1", + "justinrainbow/json-schema": "^5.2.10", + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.7 || ^3.0 || ^4.0 || ^5.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0 || ^5.0", + "symfony/finder": "^2.7 || ^3.0 || ^4.0 || ^5.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0 || ^5.0" + }, + "conflict": { + "symfony/console": "2.8.38" + }, + "require-dev": { + "phpspec/prophecy": "^1.10", + "symfony/phpunit-bridge": "^4.2" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-10-30T21:31:58+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.5.4", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "6946f785871e2314c60b4524851f3702ea4f2223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/6946f785871e2314c60b4524851f3702ea4f2223", + "reference": "6946f785871e2314c60b4524851f3702ea4f2223", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-07-15T15:35:07+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "f28d44c286812c714741478d968104c5e604a1d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f28d44c286812c714741478d968104c5e604a1d4", + "reference": "f28d44c286812c714741478d968104c5e604a1d4", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-11-13T08:04:11+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-11-10T18:47:58+00:00" + }, + { + "name": "drupal/coder", + "version": "8.3.11", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/coder.git", + "reference": "67c1bcf2d6860237ce4b176fd55ef4c7c014d84e" + }, + "require": { + "ext-mbstring": "*", + "php": ">=7.0.8", + "sirbrillig/phpcs-variable-analysis": "^2.8", + "squizlabs/php_codesniffer": "^3.5.6", + "symfony/yaml": ">=2.0.5" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.51", + "phpunit/phpunit": "^6.0 || ^7.0" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "Drupal\\": "coder_sniffer/Drupal/", + "DrupalPractice\\": "coder_sniffer/DrupalPractice/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Coder is a library to review Drupal code.", + "homepage": "https://www.drupal.org/project/coder", + "keywords": [ + "code review", + "phpcs", + "standards" + ], + "time": "2020-11-04T14:55:07+00:00" + }, + { + "name": "drupal/core-dev", + "version": "8.9.8", + "source": { + "type": "git", + "url": "https://github.com/drupal/core-dev.git", + "reference": "36370b3f42911c09ffb35f08fc72853d20e6efd7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drupal/core-dev/zipball/36370b3f42911c09ffb35f08fc72853d20e6efd7", + "reference": "36370b3f42911c09ffb35f08fc72853d20e6efd7", + "shasum": "" + }, + "require": { + "behat/mink": "^1.8", + "behat/mink-goutte-driver": "^1.2", + "behat/mink-selenium2-driver": "^1.4", + "composer/composer": "^1.9.1", + "drupal/coder": "^8.3.7", + "jcalderonzumba/gastonjs": "^1.0.2", + "jcalderonzumba/mink-phantomjs-driver": "^0.3.1", + "justinrainbow/json-schema": "^5.2", + "mikey179/vfsstream": "^1.6.8", + "phpspec/prophecy": "^1.7", + "phpunit/phpunit": "^6.5 || ^7", + "symfony/browser-kit": "^3.4.0", + "symfony/css-selector": "^3.4.0", + "symfony/debug": "^3.4.0", + "symfony/dom-crawler": "^3.4.0 !=3.4.38", + "symfony/filesystem": "~3.4.0", + "symfony/finder": "~3.4.0", + "symfony/lock": "~3.4.0", + "symfony/phpunit-bridge": "^3.4.3" + }, + "conflict": { + "webflo/drupal-core-require-dev": "*" + }, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "require-dev dependencies from drupal/drupal; use in addition to drupal/core-recommended to run tests from drupal/core.", + "time": "2020-05-09T07:53:22+00:00" + }, + { + "name": "fabpot/goutte", + "version": "v3.2.3", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/Goutte.git", + "reference": "3f0eaf0a40181359470651f1565b3e07e3dd31b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/3f0eaf0a40181359470651f1565b3e07e3dd31b8", + "reference": "3f0eaf0a40181359470651f1565b3e07e3dd31b8", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0", + "php": ">=5.5.0", + "symfony/browser-kit": "~2.1|~3.0|~4.0", + "symfony/css-selector": "~2.1|~3.0|~4.0", + "symfony/dom-crawler": "~2.1|~3.0|~4.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3.3 || ^4" + }, + "type": "application", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Goutte\\": "Goutte" + }, + "exclude-from-classmap": [ + "Goutte/Tests" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A simple PHP Web Scraper", + "homepage": "https://github.com/FriendsOfPHP/Goutte", + "keywords": [ + "scraper" + ], + "time": "2018-06-29T15:13:57+00:00" + }, + { + "name": "instaclick/php-webdriver", + "version": "1.4.7", + "source": { + "type": "git", + "url": "https://github.com/instaclick/php-webdriver.git", + "reference": "b5f330e900e9b3edfc18024a5ec8c07136075712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/b5f330e900e9b3edfc18024a5ec8c07136075712", + "reference": "b5f330e900e9b3edfc18024a5ec8c07136075712", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "^1.0||^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "WebDriver": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Justin Bishop", + "email": "jubishop@gmail.com", + "role": "Developer" + }, + { + "name": "Anthon Pang", + "email": "apang@softwaredevelopment.ca", + "role": "Fork Maintainer" + } + ], + "description": "PHP WebDriver for Selenium 2", + "homepage": "http://instaclick.com/", + "keywords": [ + "browser", + "selenium", + "webdriver", + "webtest" + ], + "time": "2019-09-25T09:05:11+00:00" + }, + { + "name": "jcalderonzumba/gastonjs", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/jcalderonzumba/gastonjs.git", + "reference": "575a9c18d8b87990c37252e8d9707b29f0a313f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jcalderonzumba/gastonjs/zipball/575a9c18d8b87990c37252e8d9707b29f0a313f3", + "reference": "575a9c18d8b87990c37252e8d9707b29f0a313f3", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~5.0|~6.0", + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.6", + "silex/silex": "~1.2", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.1" + }, + "type": "phantomjs-api", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zumba\\GastonJS\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Juan Francisco Calderón Zumba", + "email": "juanfcz@gmail.com", + "homepage": "http://github.com/jcalderonzumba" + } + ], + "description": "PhantomJS API based server for webpage automation", + "homepage": "https://github.com/jcalderonzumba/gastonjs", + "keywords": [ + "api", + "automation", + "browser", + "headless", + "phantomjs" + ], + "time": "2017-03-31T07:31:47+00:00" + }, + { + "name": "jcalderonzumba/mink-phantomjs-driver", + "version": "v0.3.3", + "source": { + "type": "git", + "url": "https://github.com/jcalderonzumba/MinkPhantomJSDriver.git", + "reference": "008f43670e94acd39273d15add1e7348eb23848d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jcalderonzumba/MinkPhantomJSDriver/zipball/008f43670e94acd39273d15add1e7348eb23848d", + "reference": "008f43670e94acd39273d15add1e7348eb23848d", + "shasum": "" + }, + "require": { + "behat/mink": "~1.7", + "jcalderonzumba/gastonjs": "~1.0", + "php": ">=5.4", + "twig/twig": "~1.20|~2.0" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master", + "phpunit/phpunit": "~4.6" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "0.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zumba\\Mink\\Driver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Juan Francisco Calderón Zumba", + "email": "juanfcz@gmail.com", + "homepage": "http://github.com/jcalderonzumba" + } + ], + "description": "PhantomJS driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "ajax", + "browser", + "headless", + "javascript", + "phantomjs", + "testing" + ], + "time": "2016-12-01T10:57:30+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.10", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2020-05-27T16:41:55+00:00" + }, + { + "name": "mikey179/vfsstream", + "version": "v1.6.8", + "source": { + "type": "git", + "url": "https://github.com/bovigo/vfsStream.git", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "org\\bovigo\\vfs\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Frank Kleine", + "homepage": "http://frankkleine.de/", + "role": "Developer" + } + ], + "description": "Virtual file system to mock the real file system in unit tests.", + "homepage": "http://vfs.bovigo.org/", + "time": "2019-10-30T15:31:00+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.2", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-11-13T09:40:50+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2018-07-08T19:23:20+00:00" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2018-07-08T19:19:57+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.2.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2020-09-03T19:13:55+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2020-09-17T18:55:26+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0 || ^9.0 <9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2020-09-29T09:10:42+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^2.0", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1 || ^4.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2018-10-31T16:06:48+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "050bedf145a257b1ff02746c31894800e5122946" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", + "reference": "050bedf145a257b1ff02746c31894800e5122946", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2018-09-13T20:33:42+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2019-06-07T04:22:29+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "abandoned": true, + "time": "2019-09-17T06:23:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.5.20", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", + "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.7", + "phar-io/manifest": "^1.0.2", + "phar-io/version": "^2.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.7", + "phpunit/php-file-iterator": "^2.0.1", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.1", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^4.0", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^2.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpunit/phpunit-mock-objects": "*" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2020-01-08T08:45:45+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-07-12T15:12:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2019-02-04T06:01:07+00:00" + }, + { + "name": "sebastian/environment", + "version": "4.2.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2019-11-20T08:46:58+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2019-09-14T09:02:43+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2018-10-04T04:07:39+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.8.3", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9ad6ce79c342fbd44df10ea95511a1b24dee5b57", + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", + "type": "tidelift" + } + ], + "time": "2020-11-11T09:19:24+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8674b1d84ffb47cc59a101f5d5a3b61e87d23796", + "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phar" + ], + "time": "2020-07-07T18:42:57+00:00" + }, + { + "name": "sirbrillig/phpcs-variable-analysis", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git", + "reference": "ff54d4ec7f2bd152d526fdabfeff639aa9b8be01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/ff54d4ec7f2bd152d526fdabfeff639aa9b8be01", + "reference": "ff54d4ec7f2bd152d526fdabfeff639aa9b8be01", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "squizlabs/php_codesniffer": "^3.1" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4 || ^0.5 || ^0.6", + "limedeck/phpunit-detailed-printer": "^3.1 || ^4.0 || ^5.0", + "phpstan/phpstan": "^0.11.8", + "phpunit/phpunit": "^5.0 || ^6.5 || ^7.0 || ^8.0", + "sirbrillig/phpcs-import-detection": "^1.1" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "VariableAnalysis\\": "VariableAnalysis/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Sam Graham", + "email": "php-codesniffer-variableanalysis@illusori.co.uk" + }, + { + "name": "Payton Swick", + "email": "payton@foolord.com" + } + ], + "description": "A PHPCS sniff to detect problems with variables.", + "time": "2020-10-07T23:32:29+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.5.8", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2020-10-23T02:01:07+00:00" + }, + { + "name": "symfony/browser-kit", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "9590bd3d3f9fa2f28d34b713ed4765a8cc8ad15c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9590bd3d3f9fa2f28d34b713ed4765a8cc8ad15c", + "reference": "9590bd3d3f9fa2f28d34b713ed4765a8cc8ad15c", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/dom-crawler": "~2.8|~3.0|~4.0" + }, + "require-dev": { + "symfony/css-selector": "~2.8|~3.0|~4.0", + "symfony/process": "~2.8|~3.0|~4.0" + }, + "suggest": { + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony BrowserKit Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/da3d9da2ce0026771f5fe64cb332158f1bd2bc33", + "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/dom-crawler", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "ef97bcfbae5b384b4ca6c8d57b617722f15241a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/ef97bcfbae5b384b4ca6c8d57b617722f15241a6", + "reference": "ef97bcfbae5b384b4ca6c8d57b617722f15241a6", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony/css-selector": "~2.8|~3.0|~4.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DomCrawler Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/lock", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/lock.git", + "reference": "8d451ed419a3d5d503bd491437b447fd4c549ceb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/lock/zipball/8d451ed419a3d5d503bd491437b447fd4c549ceb", + "reference": "8d451ed419a3d5d503bd491437b447fd4c549ceb", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/log": "~1.0", + "symfony/polyfill-php70": "~1.0" + }, + "require-dev": { + "predis/predis": "~1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Lock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jérémy Derussé", + "email": "jeremy@derusse.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Lock Component", + "homepage": "https://symfony.com", + "keywords": [ + "cas", + "flock", + "locking", + "mutex", + "redlock", + "semaphore" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/phpunit-bridge", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "8d05c61270c40f457e0fc11d47cc112c0f2e3606" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/8d05c61270c40f457e0fc11d47cc112c0f2e3606", + "reference": "8d05c61270c40f457e0fc11d47cc112c0f2e3606", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0|9.1.2" + }, + "suggest": { + "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + }, + "bin": [ + "bin/simple-phpunit" + ], + "type": "symfony-bridge", + "extra": { + "thanks": { + "name": "phpunit/phpunit", + "url": "https://github.com/sebastianbergmann/phpunit" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Bridge\\PhpUnit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PHPUnit Bridge", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "75a63c33a8577608444246075ea0af0d052e452a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2020-07-12T23:59:07+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/config/.gitkeep b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/config/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/phpunit.xml.dist b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/phpunit.xml.dist new file mode 100644 index 0000000..a0e7463 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/phpunit.xml.dist @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + ./web/modules/custom/**/tests/**/Functional + + + ./web/modules/custom/**/tests/**/Kernel + + + ./web/modules/custom/**/tests/**/Unit + + + diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.routing.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.routing.yml new file mode 100644 index 0000000..9683277 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.routing.yml @@ -0,0 +1,7 @@ +blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.services.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.services.yml new file mode 100644 index 0000000..23aee82 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.services.yml @@ -0,0 +1,3 @@ +services: + Drupal\my_module\Repository\ArticleRepository: + autowire: true diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Controller/BlogPageController.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Controller/BlogPageController.php new file mode 100644 index 0000000..d11eb05 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Controller/BlogPageController.php @@ -0,0 +1,18 @@ + $this->t('Welcome to my blog!'), + ]; + } + +} + diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Entity/Post.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Entity/Post.php new file mode 100644 index 0000000..83e9aac --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Entity/Post.php @@ -0,0 +1,23 @@ +bundle() != 'article') { + throw new \InvalidArgumentException(); + } + + $this->node = $node; + } + + public function getTitle(): string { + return $this->node->label(); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Repository/ArticleRepository.php new file mode 100644 index 0000000..20147b6 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Repository/ArticleRepository.php @@ -0,0 +1,36 @@ +nodeStorage = $entityTypeManager->getStorage('node'); + } + + public function getAll(): array { + $articles = $this->nodeStorage->loadByProperties([ + 'status' => NodeInterface::PUBLISHED, + 'type' => 'article', + ]); + + $this->sortByCreatedDate($articles); + + return array_map(function (NodeInterface $node): Post { + return new Post($node); + }, $articles); + } + + private function sortByCreatedDate(array &$articles): void { + uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { + return $a->getCreatedTime() < $b->getCreatedTime(); + }); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php new file mode 100644 index 0000000..043f5db --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php @@ -0,0 +1,28 @@ +drupalGet('blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + $session->responseContains('

Blog

'); + $session->pageTextContains('Welcome to my blog!'); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..b8f7ffe --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,41 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + + /** @test */ + public function the_admin_page_is_not_accessible_to_anonymous_users() { + $this->drupalGet('admin'); + + $this->assertResponse(Response::HTTP_FORBIDDEN); + } + + /** @test */ + public function the_admin_page_is_accessible_by_admin_users() { + $adminUser = $this->createUser([ + 'access administration pages', + ]); + + $this->drupalLogin($adminUser); + + $this->drupalGet('admin'); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php new file mode 100644 index 0000000..443486b --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -0,0 +1,82 @@ +createNode(['type' => 'article', 'title' => 'Test post'])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(1, $articles); + $this->assertIsObject($articles[1]); + $this->assertInstanceOf(Post::class, $articles[1]); + $this->assertSame('Test post', $articles[1]->getTitle()); + } + + /** @test */ + public function nodes_that_are_not_articles_are_not_returned() { + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function only_published_articles_are_returned() { + $this->createNode(['type' => 'article', 'status' => NodeInterface::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => NodeInterface::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => NodeInterface::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => NodeInterface::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => NodeInterface::PUBLISHED])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); + + $repository = $this->container->get(ArticleRepository::class); + $nodes = $repository->getAll(); + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + + protected function setUp() { + parent::setUp(); + + $this->installConfig(['filter']); + + $this->installSchema('node', ['node_access']); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php new file mode 100644 index 0000000..dd724f9 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php @@ -0,0 +1,36 @@ +createMock(NodeInterface::class); + + $node->expects($this->once()) + ->method('label') + ->willReturn('Test post'); + $node->method('bundle')->willReturn('article'); + + $post = new Post($node); + + $this->assertSame('Test post', $post->getTitle()); + } + + /** @test */ + public function it_throws_an_exception_if_the_node_is_not_an_article() { + $node = $this->createMock(NodeInterface::class); + + $node->method('bundle')->willReturn('page'); + + $this->expectException(\InvalidArgumentException::class); + + new Post($node); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/sites/default/settings.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/sites/default/settings.php new file mode 100644 index 0000000..051e0e4 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/sites/default/settings.php @@ -0,0 +1,16 @@ +`__ installed and would like better performance (particularly on macOS), you could use the PHP's local web server. + +As we're going to use SQLite to run the tests, there's no need for a connection to a MySQL database or another service. + +If you need to override any environment variables, you can do so before running the command: + +:: + + $ SIMPLETEST_BASE_URL=http://localhost:8000 vendor/bin/phpunit + +The different types of available tests +-------------------------------------- + +- **Functional** (web, feature) - tests behaviour and functionality, makes HTTP requests to the webserver and has access to the database and other services via the service container. Slower to run. +- **FunctionalJavascript** - functional tests, but access to JavaScript. +- **Kernel** (integration) - no browser capabilities, has access to the database and other services but requires more configuration. +- **Unit** - no access to the database or service container, all dependencies need to be mocked. Fast to run. + +Different approaches to testing +------------------------------- + +- Inside-out (testing pyramid) - mostly unit tests, some integration tests, few functional tests. +- Outside-in (testing trophy) - mostly functional tests, some integration tests, few unit tests. More flexible, easier to refactor. + +The structure of a test +----------------------- + +- **Arrange** - set up the environment. Create users, nodes, set up dependencies +- **Act** - perform an action +- **Assert** - verify that something happened + +What is Test Driven Development? +-------------------------------- + +- Writing tests first +- Red, green, refactor loop +- Writing failing test first +- Write code to make the test pass +- Refactor when tests pass +- Three (simplified) rules of TDD: +- Write production code only to make a failing unit test pass. +- Write only enough of a unit test to fail. +- Write only enough production code to make the failing unit test pass. +- http://www.javiersaldana.com/articles/tech/refactoring-the-three-laws-of-tdd + +Acceptance criteria +------------------- + +This module will be used to demonstrate how to take a test-driven approach to develop a module to the following acceptance criteria: + +- As a site visitor +- I want to see a list of all published articles at ``/blog`` +- Ordered by post date, with the newest posts first + +Preparation +----------- + +To begin, we need the site to be running. + +.. code:: bash + + # Using DDEV + ddev start + + # Using PHP's web server + php -S localhost:8000 -t web + +You don’t need to install Drupal. It just needs to be able to connect to the database. + +Writing your first test +----------------------- + +Create the module directory +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create a directory for the new module: + +:: + + mkdir -p web/modules/custom/my_module + +1b. Create an ``.info.yml`` file for the module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to install the module, it needs an info.yml file that matches the name of the module (e.g. ``my_module.info.yml``). + +Within the ``my_module`` directory, create the file and paste in the following content: + +.. code:: yaml + + name: My Module + type: module + core_version_requirement: ^8 || ^9 + +Create the directory structure for tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: bash + + mkdir -p tests/src/Functional + +Create your first test case +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + config('system.site') + ->set('page.front', '/node') + ->save(TRUE); + + $this->drupalGet(''); + + $assert = $this->assertSession(); + $assert->statusCodeEquals(Response::HTTP_OK); + $assert->pageTextContains('Welcome to Drupal'); + $assert->pageTextContains('No front page content has been created yet.'); + } + + } + +Some things to note: + +- The name of the class must match the filename. +- The filename must end with ``Test.php``. +- The namespace is ``Drupal\Tests\{module_name}``, followed by any additional directories (e.g. ``Functional``). +- Test methods must start with ``test``, or use the ``@test`` annotation. + +Preparing PHPUnit +~~~~~~~~~~~~~~~~~ + +Firstly, we need to create a ``phpunit.xml`` file to configure PHPUnit. Core has a ``phpunit.xml.dist`` file that we can duplicate and edit. + +.. code:: bash + + cp web/core/phpunit.xml.dist web/core/phpunit.xml + +Update the ``SIMPLETEST_BASE_URL`` value to be the address that the website is currently running on. This needs to be correct so that functional tests return the correct response codes, so ensure that any port numbers are correct and also that the site is correctly marked as HTTP or HTTPS. + +We also need to configure the database for Drupal to connect to and use when running functional and kernel tests. This could be your project’s MySQL or PostgreSQL database with a table prefix, but in this case, we’ll use a separate SQLite database. + +.. code:: diff + + - + + + + - + + + +Running the tests +~~~~~~~~~~~~~~~~~ + +.. code:: bash + + $ vendor/bin/phpunit modules/custom/my_module + +You should see a summary of the number of tests and assertions that were run. This is the expected output if all of the tests pass: + + OK (1 test, 3 assertions) + +If a test failed, the output would show the class and method name for the failing test, and give a summary of the failure. + + Drupal\ *module::the*\ front\_page\_loads\_for\_anonymous\_users + Behat: Current response status code is 404, but 200 expected. + +Other useful options include ``--stop-on-failure``, ``--filter`` and ``--testdox``. + +(Optional) Running tests via a Composer script +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To simplify running tests, the command could be simplified by `adding a script ` to ``composer.json``: + +.. code:: json + + "scripts": { + "test:phpunit": "phpunit --verbose --testdox --colors=always", + "test": [ + "@test:phpunit" + ] + } + +This means that you can run just ``ddev composer test:phpunit`` or ``ddev composer test`` and it will execute the ``phpunit`` command. + +This approach can be useful if you want to run other commands in addition to PHPUnit such as PHPStan, PHP Code Sniffer or Drupal Check. Each command can be added to the script and they will each be executed. + +If needed, you can still pass additional arguments and options to the command by appending ``--`` followed by the arguments. + +.. code:: bash + + ddev composer test:phpunit -- modules/custom/my_module \ + --stop-on-failure \ + --filter=the_front_page_loads_for_anonymous_users + +Locally, ensure that the command is prefixed with ``ddev`` so that it is run within the container. This ensures that the correct PHP version etc is used. + +Adding more test methods +------------------------ + +Ensure that anonymous users cannot access admin pages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now that we’re sure that the front page loads correctly, lets also check anonymous users cannot access the administration area. This test is very similar to the previous one, though instead we’re making a GET request to ``/admin`` and ensuring that the response code is 403 (forbidden). + +As this functionality is provided by Drupal core by default, this should pass automatically. + +.. code:: php + + drupalGet('admin'); + + $this->assertSession()->statusCodeEquals(Response::HTTP_FORBIDDEN); + } + +Ensure that administrators can access admin pages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now let’s check that an administrator user *can* access the admin pages. + +This introduces some new concepts. We need to create a user to begin with, and assign it some permissions. Because tests may be included within Drupal core a contributed module, permissions need to be added to users directly as modules won’t know about roles that are specific to your site. + +The ``BrowserTestBase`` class gives access to a number of helper methods, including ones for creating and logging-in users (``createUser`` and ``drupalLogin`` respectively). When creating a user, the first argument is an array of permission names to add. In this case, we can make the user an admin user by adding the ``access administration pages`` permission. + +.. code:: php + + createUser([ + 'access administration pages', + ]); + + $this->drupalLogin($adminUser); + + $this->drupalGet('admin'); + + $this->assertSession()->statusCodeEquals(Response::HTTP_OK); + } + +Again, as this functionality is provided by Drupal core by default, this should pass. However, we can be confident that the test is doing what’s needed by making it fail by removing or changing the assigned permissions, or not logging in the user before accessing the page. + +Building a blog +--------------- + +Anonymous users should be able to view the blog page +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let’s start by building a blog page. This will look very similar to the admin page tests, but instead we’ll be testing the ``/blog`` page. + +.. code:: php + + drupalGet('blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + } + + } + +This test will fail as there’s no route for ``/blog`` and no View that generates that page. Because of this, the response code will be a 404 instead of the 200 that we want. + + Current response status code is 404, but 200 expected. + +Add a route for the blog page +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We’ll create a blog page using a custom route in the module. You could also do this with the Views module by creating a View with a page on that path, and exporting the configuration into the module’s ``config/install`` directory. + +To add a route, we need to create a ``my_module.routing.yml`` file. + +.. code:: yaml + + # my_module.routing.yml + + blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content + +We set our path to ``/blog``, specify the Controller to use and which permission the needs to have to access the page. + +If we run the tests now, we get an access denied error (403 response). + + Current response status code is 403, but 200 expected. + +Fix permission error +~~~~~~~~~~~~~~~~~~~~ + +Because we need to node module to be able to access the ``access content`` permission, we need to enable it within our tests. + +We can do this by adding it to the ``$modules`` array within the test. + +.. code:: diff + + protected static $modules = [ + + 'node', + 'my_module', + ]; + +Now the error has changed, and is now returning a 500 response because we’ve specified a Controller that doesn’t exist. + + Current response status code is 500, but 200 expected. + +Add the BlogPageController +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let’s create the ``BlogPageController``. + +:: + + mkdir src/Controller + +Let’s start by creating a minimal controller, that returns an empty render array. Because we didn’t specify a method to use within the route file, we use PHP’s ``__invoke()`` method. + +.. code:: php + + drupalGet('/blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + + $session->responseContains('

Blog

'); + + $session->pageTextContains('Welcome to my blog!'); + } + +The page title is created by the ``_title`` value within the routing file, but no page text has been added yet so this will cause the test to fail. + + Behat: The text "Welcome to my blog!" was not found anywhere in the + text of the current page. + +To fix this, we can return some text from the BlogPageController rather than an empty render array. + +.. code:: diff + + namespace Drupal\my_module\Controller; + + + use Drupal\Core\StringTranslation\StringTranslationTrait; + + class BlogPageController { + + + use StringTranslationTrait; + + public function __invoke(): array { + - return []; + + return [ + + '#markup' => $this->t('Welcome to my blog!'), + + ]; + } + + } + +Now the tests will pass because we’re returning the correct text. + + OK (1 test, 3 assertions) + +.. figure:: images/2.png + :alt: + +Getting blog posts +------------------ + +Creating our first kernel test +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We’ll be using an ArticleRepository class to get the blog posts from the database, and this is also a good time to switch to writing kernel tests as we don’t need to check any responses from the browser. + +Within the tests directory, create a new ``Kernel`` directory. + +:: + + mkdir tests/src/Kernel + +And an ``ArticleRepositoryTest`` class. + +.. code:: php + + assertCount(1, $articles); + } + +As we aren’t yet returning any articles, or even creating that variable, the test is going to fail, but we can move on to getting articles. + + Undefined variable: articles + +Trying to use the ArticleRepository +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As the test name suggests, we’re going to be retrieving the articles from an ``ArticleRepository`` service - though this doesn’t exist yet, but let’s let the tests tell us that. + +.. code:: diff + + /** @test */ + public function it_returns_blog_posts() { + + $repository = $this->container->get(ArticleRepository::class); + + + $this->assertCount(1, $articles); + } + +Because this is a kernel test, we have access to the container, and we can use it to retrieve our repository service. + +Running the test now gives us a different error, and tells us what the next step is: + + Symfony: You have requested a non-existent service "Drupal\_module". + +Creating an article repository +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: bash + + mkdir src/Repository + +To begin with, let’s create a basic ``ArticleRepository`` class. + +.. code:: php + + container->get(ArticleRepository::class); + + $articles = $repository->getAll(); + + $this->assertCount(1, $articles); + +This method doesn’t exist on the repository yet, so the test will fail. + + Error : Call to undefined method Drupal\_module::getAll() + +Let’s fix that by adding the ``getAll()`` method. For now, have it return an empty array. + +.. code:: php + + // my_module/Repository/ArticleRepository.php + + public function getAll(): array { + return []; + } + +Now we’ve got everything in place, and the test failure is because we aren’t returning the correct number of articles. + + Failed asserting that actual size 0 matches expected size 3. + +We can fix this by building up the ``ArticleRepository`` class. + +Building up the ArticleRepository +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``ArticleRepository`` needs to return some articles. We can do this by injecting the ``EntityTypeManager`` and using it to return nodes from the ``getAll()`` method rather than the empty array. + +.. code:: diff + + + use Drupal\Core\Entity\EntityTypeManagerInterface; + + + + /** + + * @var \Drupal\Core\Entity\EntityStorageInterface + + */ + + private $nodeStorage; + + + public function __construct(EntityTypeManagerInterface $entityTypeManager) { + + $this->nodeStorage = $entityTypeManager->getStorage('node'); + + } + + public function getAll(): array { + - return []; + + return $this->nodeStorage->loadMultiple(); + } + +Within our services file, we now need to add the ``EntityTypeManager`` as an argument so that it’s used to create the ``ArticleRepository``. Currently we don’t have enough arguments. + + ArgumentCountError : Too few arguments to function + Drupal\_module::\_\_construct(), 0 passed and exactly 1 expected + +The quickest way to do that is to enable autowiring for the ArticleRepository within ``my_module.services.yml``. This will automatically inject services rather than needing to specify each argument individually. + +.. code:: diff + + - Drupal\my_module\Repository\ArticleRepository: ~ + + Drupal\Core\Entity\EntityTypeManagerInterface: + + alias: entity_type.manager + + + + Drupal\my_module\Repository\ArticleRepository: + + autowire: true + + Drupal: The "node" entity type does not exist. + +As we did previously, we need to enable the ``node`` module. + +.. code:: diff + + public static $modules = [ + + 'node', + 'my_module', + ]; + +The ``ArticleRepository`` is now working, but is still returning no articles - though this is because we haven’t created any inside the test. + + Failed asserting that actual size 0 matches expected size 1. + +Adding articles +~~~~~~~~~~~~~~~ + +To test the ArticleRepository, we need articles to be created so that they can be returned. + +Within the ``ArticleRepositoryTest`` we can make use of one of a number of traits that are provided. + +Within the class, enable the trait: + +.. code:: diff + + + use NodeCreationTrait + +Include the import statement at the top of the file if it hasn’t been added automatically. + +.. code:: diff + + + use Drupal\Tests\node\Traits\NodeCreationTrait; + +This gives us a ``createNode`` method that we can use to create nodes by passing an array of values. + +As we need an article to retrieve, let’s create one. + +.. code:: diff + + + $this->createNode(['type' => 'article', 'title' => 'Test post'])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + +The next error is a little cryptic: + + Error : Call to a member function id() on bool + +Looking at the stack trace, this error is within ``filter.module``, where it’s trying to call an ``id()`` method on a filter format. + +.. code:: php + + // filter.module + + $formats = filter_formats($account); + $format = reset($formats); + return $format->id(); + +As kernel tests don’t install configuration by default, we need to install the missing filter configuration. + +As we’ll need this for all test methods in this case, we can use the ``setUp()`` method that will run before each test. + +.. code:: diff + + + protected function setUp() { + + parent::setUp(); + + + + $this->installConfig([ + + 'filter', + + ]); + + } + +We also need to create the ``node_access`` table as indicated by the next error: + + Drupal: SQLSTATE[HY000]: General error: 1 no such table: + test90927710.node\_access: DELETE FROM {node\_access} + +.. code:: diff + + protected function setUp() { + parent::setUp(); + + + + $this->installSchema('node', ['node_access']); + + + $this->installConfig([ + 'filter', + ]); + } + +We’ve successfully returned our article and this test now passes. + + OK (1 test, 11 assertions) + +Whilst the test is passing, let's add some additional assertions to check the type of object being returned and its title. + +.. code:: diff + + $this->assertCount(1, $articles); + + $this->assertIsObject($articles[1]); + + $this->assertInstanceOf(NodeInterface::class, $articles[1]); + + $this->assertSame('Test post', $articles[1]->label()); + + OK (1 test, 14 assertions) + +Ensuring that only articles are returned +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's start with a new test, this time with three article nodes: + +.. code:: php + + createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + +Again, we can use the node creation trait to create the required content. + +As we already have the ``ArticleRepository`` in place, this test should pass straight away. + + OK (1 test, 11 assertions) + +Making this test less brittle +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The test is passing, but it currently returns *all* nodes and not just articles. + +If we create some page nodes too, these will also be returned and the assertion will now fail. + +.. code:: diff + + $this->createNode(['type' => 'article'])->save(); + + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + + Failed asserting that actual size 5 matches expected size 3. + +We can make a change to the ``ArticleRepository`` to fix this, and ensure that we’re only loading and returning article nodes. + +.. code:: diff + + - return $this->nodeStorage->loadMultiple(); + + return $this->nodeStorage->loadByProperties([ + + 'type' => 'article', + + ]); + +Ensuring that only published articles are returned +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We now know that only article nodes are returned, but *all* articles are being returned. On our blog, we only want to published articles to be displayed. + +Let’s create another test for this. + +.. code:: diff + + + /** @test */ + + public function only_published_articles_are_returned() { + + $repository = $this->container->get(ArticleRepository::class); + + $articles = $repository->getAll(); + + + $this->assertCount(3, $articles); + + } + +We already know that only articles are returned, so in this test we can focus on the published status. We can create a number of articles, some which are published and some which are unpublished. + +.. code:: diff + + /** @test */ + public function only_published_articles_are_returned() { + + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + +Because we have no filter on the published state, all the articles are returned including the unpublished ones. + + Failed asserting that actual size 5 matches expected size 3. + +We can again update the ``ArticleRepository`` to add this extra condition to filter out any unpublished articles. + +.. code:: diff + + + use Drupal\node\Entity\Node; + + public function getAll(): array { + return $this->nodeStorage->loadByProperties([ + + 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); + } + +With this added, the test passes again. + + OK (1 test, 6 assertions) + +Ensuring that articles are returned in the correct order +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As per our acceptance criteria, we need the articles to be returned based on their created date, so let’s create another test. + +In this test, let’s ensure assert that some article node IDs are returned within a specific order. + +.. code:: diff + + + /** @test */ + + public function nodes_are_ordered_by_date_and_newest_first() { + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + + } + +We can use the same ``getAll()`` method, and get the node IDs from the array keys. + +.. code:: diff + + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + + $repository = $this->container->get(ArticleRepository::class); + + $nodes = $repository->getAll(); + + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + +Use ``createNode()`` again to create some article nodes, each with a different ``created`` date to match our assertion. This is to ensure that the test doesn’t pass by default. + +.. code:: diff + + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); + + $repository = $this->container->get(ArticleRepository::class); + $nodes = $repository->getAll(); + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + +This test fails as expected, as the nodes are returned in their default order, by node ID. + + Failed asserting that two arrays are identical. --- Expected +++ + Actual @@ @@ Array &0 ( + + - 0 => 3 + - 1 => 1 + - 2 => 2 + - 3 => 5 + - 4 => 4 + + - 0 => 1 + - 1 => 2 + - 2 => 3 + - 3 => 4 + - 4 => 5 ) + +To order the articles by their created date, we can update the ``getAll()`` method within the ``ArticleRepository``. + +.. code:: diff + + public function getAll(): array { + - return $this->nodeStorage->loadByProperties([ + + $articles = $this->nodeStorage->loadByProperties([ + 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); + + + + $this->sortByCreatedDate($articles); + + + + return $articles; + + } + + + + private function sortByCreatedDate(array &$articles): void { + + uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { + + return $a->getCreatedTime() < $b->getCreatedTime(); + + }); + } + +The nodes are now ordered by their created date, and in the correct order to match the assertion. + + OK (1 test, 11 assertions) + +Linking up the repository to the BlogPageController +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now that our ``ArticleRepository`` tests are passing, we can use it within ``BlogPageController`` so that articles are displayed on the page. + +Let’s add ``BlogPageController`` as a service and enable autowiring. + +.. code:: diff + + # my_module.services.yml + + services: + + Drupal\my_module\Controller\BlogPageController: + + autowire: true + + Drupal\my_module\Repository\ArticleRepository: + autowire: true + +Now we can inject the ``ArticleRepository`` and use it to load and render the articles on the page. + +.. code:: diff + + + namespace Drupal\my_module\Controller; + + use Drupal\Core\Entity\EntityTypeManagerInterface; + use Drupal\Core\StringTranslation\StringTranslationTrait; + use Drupal\my_module\Repository\ArticleRepository; + + class BlogPageController { + + use StringTranslationTrait; + + + /** + + * @var \Drupal\my_module\Repository\ArticleRepository + + */ + + private $articleRepository; + + + + /** + + * @var \Drupal\Core\Entity\EntityViewBuilderInterface + + */ + + private $nodeViewBuilder; + + + + public function __construct( + + EntityTypeManagerInterface $entityTypeManager, + + ArticleRepository $articleRepository + + ) { + + $this->nodeViewBuilder = $entityTypeManager->getViewBuilder('node'); + + $this->articleRepository = $articleRepository; + + } + + public function __invoke(): array { + - return []; + + $build = []; + + + + $articles = $this->articleRepository->getAll(); + + + foreach ($articles as $article) { + + $build[] = $this->nodeViewBuilder->view($article, 'teaser'); + + } + + + + return [ + + '#markup' => render($build), + + ]; + } + + } + +In the browser, we should see our list of articles. + +.. figure:: images/3.png + :alt: + +Creating a custom Post class +---------------------------- + +What if we wanted to return a custom ``Post`` class from the repository with its own data and logic rather than a generic Drupal node? As the repository is responsible for finding and returning nodes, we can make changes there and return what we want. + +Let's start by changing one of our existing tests. + +Changing the existing test +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In ``ArticleRepositoryTest`` we have existing assertions as to what type of object is returned. Currently, this should be an instance of a ``Node::class``. Let's change that to a new ``Post::class`` and also change the ``label`` method to a more desciriptive ``getTitle()``. + +.. code:: diff + + $this->assertCount(1, $articles); + $this->assertIsObject($articles[1]); + - $this->assertInstanceOf(Node::class, $articles[1]); + - $this->assertSame('Test post', $articles[1]->label()); + + $this->assertInstanceOf(Post::class, $articles[1]); + + $this->assertSame('Test post', $articles[1]->getTitle()); + +As we have no ``Post`` class and are still returning the original nodes from the Repository, this will cause the test to now fail. + + 1) Drupal\ *module::it*\ returns\_blog\_posts PHPUnit: Argument #1 + (No Value) of PHPUnit::assertInstanceOf() must be a class or + interface name + +Adding a Post class +~~~~~~~~~~~~~~~~~~~ + +Create a new ``Entity`` directory and a new ``Post.php`` file inside it. + +:: + + mkdir -p src/Entity + +.. code:: php + + assertSame('Test post', $post->getTitle()); + } + +If we run this, we get an undefined method error: + + Error: Call to undefined method Drupal\_module::getTitle() + +Adding the getTitle() method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Within the ``Post`` class, add a ``getTitle()`` method which will return a string. For now, let's return an empty string: + +.. code:: php + + node = $node; + } + + public function getTitle(): string { + return $this->node->label(); + } + + } + +This test will fail as we need to update the test to include the node: + + ArgumentCountError: Too few arguments to function Drupal\_module::\_\_construct(), 0 passed in /home/opdavies/Code/Personal/workshop-drupal-automated-testing-code/web/modules/custom/my\_module/tests/src/Unit/Entity/PostTest.php on line 12 and exactly 1 expected + +Mocking the article node +~~~~~~~~~~~~~~~~~~~~~~~~ + +As we are working with a unit test, we can't interact with the database in the same way that we can with functional or kernel tests. This means that using methods like ``Node::create`` won't work in unit tests, so we need to create our own mock node and tell it what to return. + +.. code:: php + + createMock(NodeInterface::class); + + $node->expects($this->once()) + ->method('label') + ->willReturn('Test post'); + +This ensures that the ``label()`` method will only be called once and that it will return the string ``Test post``. + +As this is the same value as our expection in the test, this test should now pass. + +However, whilst the unit tests are all passing, one of the kernel tests is now failing. + +Fixing the ArticleRepository test +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To get ``ArticleRepositoryTest`` passing again, we need to update the ``getAll()`` method and add the node as an argument to the create ``Post``. + +.. code:: diff + + return array_map(function (NodeInterface $node): Post { + - return new Post(); + + return new Post($node); + }, $articles); + +Only article nodes should be used for Posts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Currently any node is able to be passed to the ``Post`` class. Let's ensure that only article nodes can be added by adding a check and throwing an Exception. + +.. code:: php + + createMock(NodeInterface::class); + + $node->method('bundle')->willReturn('page'); + + $this->expectException(\InvalidArgumentException::class); + + new Post($node); + } + +Again, we need to mock the node, but this time, let's set the ``bundle()`` method to return a value that should throw an Exception. + +Throw an Exception for non-articles +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's add a check to the ``Post`` constructor + +.. code:: diff + + public function __construct(NodeInterface $node) { + + if ($node->bundle() != 'article') { + + throw new \InvalidArgumentException(); + + } + + + $this->node = $node; + } + +This will result in the Exception being thrown if the node is not an article, and the test should pass. + +Fixing the existing unit test +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to this new check, we also need to update the previous unit test so that includes a value for the bundle. + +.. code:: diff + + $node->expects($this->once()) + ->method('label') + ->willReturn('Test post'); + + $node->method('bundle')->willReturn('article'); diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/1.png b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/1.png new file mode 100644 index 0000000..be24c98 Binary files /dev/null and b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/1.png differ diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/2.png b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/2.png new file mode 100644 index 0000000..5676619 Binary files /dev/null and b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/2.png differ diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/3.png b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/3.png new file mode 100644 index 0000000..fa3044c Binary files /dev/null and b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/3.png differ diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..cb34eb7 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,19 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..7f2924e --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,39 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + + /** @test */ + public function the_admin_page_is_not_accessible_to_anonymous_users() { + $this->drupalGet('admin'); + + $this->assertResponse(Response::HTTP_FORBIDDEN); + } + + /** @test */ + public function the_admin_page_is_accessible_by_admin_users() { + $adminUser = $this->createUser([ + 'access administration pages', + ]); + + $this->drupalLogin($adminUser); + + $this->drupalGet('/admin'); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.routing.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.routing.yml new file mode 100644 index 0000000..9683277 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.routing.yml @@ -0,0 +1,7 @@ +blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/src/Controller/BlogPageController.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/src/Controller/BlogPageController.php new file mode 100644 index 0000000..1f1378e --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/src/Controller/BlogPageController.php @@ -0,0 +1,17 @@ + $this->t('Welcome to my blog!'), + ]; + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php new file mode 100644 index 0000000..1798947 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php @@ -0,0 +1,28 @@ +drupalGet('/blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + $session->responseContains('

Blog

'); + $session->pageTextContains('Welcome to my blog!'); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..cb34eb7 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,19 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.routing.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.routing.yml new file mode 100644 index 0000000..9683277 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.routing.yml @@ -0,0 +1,7 @@ +blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.services.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.services.yml new file mode 100644 index 0000000..a97d210 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.services.yml @@ -0,0 +1,6 @@ +services: + Drupal\my_module\Controller\BlogPageController: + autowire: true + + Drupal\my_module\Repository\ArticleRepository: + autowire: true diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Controller/BlogPageController.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Controller/BlogPageController.php new file mode 100644 index 0000000..05e7fa3 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Controller/BlogPageController.php @@ -0,0 +1,45 @@ +nodeViewBuilder = $entityTypeManager->getViewBuilder('node'); + $this->articleRepository = $articleRepository; + } + + public function __invoke(): array { + $build = []; + + $articles = $this->articleRepository->getAll(); + + foreach ($articles as $article) { + $build[] = $this->nodeViewBuilder->view($article, 'teaser'); + } + + return [ + '#markup' => render($build), + ]; + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php new file mode 100644 index 0000000..aee9127 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php @@ -0,0 +1,33 @@ +nodeStorage = $entityTypeManager->getStorage('node'); + } + + public function getAll(): array { + $articles = $this->nodeStorage->loadByProperties([ + 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); + + uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { + return $a->getCreatedTime() < $b->getCreatedTime(); + }); + + return $articles; + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php new file mode 100644 index 0000000..1827604 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php @@ -0,0 +1,27 @@ +drupalGet('/blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + $session->responseContains('

Blog

'); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..cb34eb7 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,19 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php new file mode 100644 index 0000000..60d6d46 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php @@ -0,0 +1,75 @@ +installSchema('node', ['node_access']); + + $this->installConfig([ + 'filter', + ]); + } + + /** @test */ + public function nodes_that_are_not_articles_are_not_returned() { + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $this->assertCount(5, Node::loadMultiple()); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function only_published_articles_are_returned() { + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); + + $repository = $this->container->get(ArticleRepository::class); + $nodes = $repository->getAll(); + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.routing.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.routing.yml new file mode 100644 index 0000000..9683277 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.routing.yml @@ -0,0 +1,7 @@ +blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.services.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.services.yml new file mode 100644 index 0000000..a97d210 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.services.yml @@ -0,0 +1,6 @@ +services: + Drupal\my_module\Controller\BlogPageController: + autowire: true + + Drupal\my_module\Repository\ArticleRepository: + autowire: true diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php new file mode 100644 index 0000000..05e7fa3 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php @@ -0,0 +1,45 @@ +nodeViewBuilder = $entityTypeManager->getViewBuilder('node'); + $this->articleRepository = $articleRepository; + } + + public function __invoke(): array { + $build = []; + + $articles = $this->articleRepository->getAll(); + + foreach ($articles as $article) { + $build[] = $this->nodeViewBuilder->view($article, 'teaser'); + } + + return [ + '#markup' => render($build), + ]; + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php new file mode 100644 index 0000000..aee9127 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php @@ -0,0 +1,33 @@ +nodeStorage = $entityTypeManager->getStorage('node'); + } + + public function getAll(): array { + $articles = $this->nodeStorage->loadByProperties([ + 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); + + uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { + return $a->getCreatedTime() < $b->getCreatedTime(); + }); + + return $articles; + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php new file mode 100644 index 0000000..fc6d516 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php @@ -0,0 +1,40 @@ +verifyNodeType($node); + + $this->time = $time; + $this->article = $node; + } + + public function getOriginal(): NodeInterface { + return $this->article; + } + + private function verifyNodeType(NodeInterface $node): void { + if ($node->bundle() != 'article') { + throw new \InvalidArgumentException(sprintf( + '%s is not an article', + $node->bundle() + )); + } + } + + public function isPublishable(): bool { + $created = $this->article->getCreatedTime(); + + $difference = $this->time->getRequestTime() - $created; + + return $difference >= 60 * 60 * 24 * 3; + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php new file mode 100644 index 0000000..1827604 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php @@ -0,0 +1,27 @@ +drupalGet('/blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + $session->responseContains('

Blog

'); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..cb34eb7 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,19 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php new file mode 100644 index 0000000..60d6d46 --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php @@ -0,0 +1,75 @@ +installSchema('node', ['node_access']); + + $this->installConfig([ + 'filter', + ]); + } + + /** @test */ + public function nodes_that_are_not_articles_are_not_returned() { + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $this->assertCount(5, Node::loadMultiple()); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function only_published_articles_are_returned() { + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); + + $repository = $this->container->get(ArticleRepository::class); + $nodes = $repository->getAll(); + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + +} diff --git a/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php new file mode 100644 index 0000000..8a6537f --- /dev/null +++ b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php @@ -0,0 +1,73 @@ +time = $this->createMock(TimeInterface::class); + } + + /** @test */ + public function it_returns_the_article() { + $article = $this->createMock(NodeInterface::class); + $article->method('id')->willReturn(5); + $article->method('bundle')->willReturn('article'); + + $articleWrapper = new ArticleWrapper($this->time, $article); + + $this->assertInstanceOf(NodeInterface::class, $articleWrapper->getOriginal()); + $this->assertSame(5, $articleWrapper->getOriginal()->id()); + $this->assertSame('article', $articleWrapper->getOriginal()->bundle()); + } + + /** @test */ + public function it_throws_an_exception_if_the_node_is_not_an_article() { + $this->expectException(\InvalidArgumentException::class); + + $page = $this->createMock(NodeInterface::class); + $page->method('bundle')->willReturn('page'); + + new ArticleWrapper($this->time, $page); + } + + /** + * @test + * @dataProvider articleCreatedDateProvider + */ + public function articles_created_less_than_3_days_ago_are_not_publishable( + string $offset, + bool $expected + ) { + $this->time->method('getRequestTime')->willReturn( + (new \DateTime())->getTimestamp() + ); + + $article = $this->createMock(NodeInterface::class); + $article->method('bundle')->willReturn('article'); + + $article->method('getCreatedTime')->willReturn( + (new \DateTime())->modify($offset)->getTimestamp() + ); + + $articleWrapper = new ArticleWrapper($this->time, $article); + + $this->assertSame($expected, $articleWrapper->isPublishable()); + } + + public function articleCreatedDateProvider() { + return [ + ['-1 day', FALSE], + ['-2 days 59 minutes', FALSE], + ['-3 days', TRUE], + ['-1 week', TRUE], + ]; + } +}