diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..c4011e0
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1 @@
+https://www.gnu.org/licenses/gpl-3.0.html
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5022913
--- /dev/null
+++ b/README.md
@@ -0,0 +1,45 @@
+# WordPress Batch Processing
+
+Provides a framework to handle large data processing jobs by breaking it into smaller chunks and running each job individually via AJAX requests.
+
+## Installation
+
+The recommended method of installation is via [Composer](https://getcomposer.org/).
+
+### Composer
+For more information on using Composer to manage WordPress plugins [read this guide](https://deliciousbrains.com/using-composer-manage-wordpress-themes-plugins/).
+
+#### Add the repository to composer.json
+
+1. In the `extra` array ensure you have:
+
+```js
+"installer-paths": {
+ "content/plugins/{$name}/": ["type:wordpress-plugin"]
+}
+```
+
+Be sure that the installer path reflects your WordPress plugin directory.
+
+
+2. In the `repositories` array of composer.json, add the following
+
+```js
+{
+ "type": "git",
+ "url": "git@github.com:RamseyInHouse/wp-ramsey-batch.git"
+}
+```
+
+3. In the `require` object add:
+
+```js
+"RamseyInHouse/wp-ramsey-batch": "^1.0"
+```
+If you'd like a different version of the plugin, check the [Releases](https://github.com/RamseyInHouse/wp-ramsey-batch/releases) section of Github. This plugin adheres to [semantic versioning guidelines](https://getcomposer.org/doc/articles/versions.md).
+
+4. Run the `composer install` command.
+
+### Download and Install
+
+You can download the plugin files here and add them to the `plugins` directory of your WordPress installation. [Follow the directions here](https://codex.wordpress.org/Managing_Plugins#Manual_Plugin_Installation_by_FTP).
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..d349c30
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,35 @@
+{
+ "name": "RamseyInHouse/wp-ramsey-batch",
+ "description": "Perform batch jobs inside of WordPress.",
+ "type": "wordpress-plugin",
+ "license": "GPL v3",
+ "version": "1.0.0",
+ "authors": [
+ {
+ "name": "Philip Downer",
+ "email": "philip.downer@daveramsey.com",
+ "homepage": "http://philipdowner.com"
+ },
+ {
+ "name": "Alex MacArthur",
+ "email": "alex.macarthur@daveramsey.com",
+ "homepage": "https://macarthur.me"
+ }
+ ],
+ "require-dev": {
+ "phpunit/phpunit": "^7.3",
+ "mockery/mockery": "^1.1"
+ },
+ "autoload": {
+ "psr-4": {"RamseySolutions\\RamseyBatch\\": "src/"}
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "RamseyBatchTests\\": "tests/"
+ }
+ },
+ "require": {
+ "php": ">=7.2",
+ "composer/installers": "^1.0.7"
+ }
+}
\ No newline at end of file
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..e828fec
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,1662 @@
+{
+ "_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": "9654ef43b831d55a5f1d3332fa104f2d",
+ "packages": [
+ {
+ "name": "composer/installers",
+ "version": "v1.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/installers.git",
+ "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b",
+ "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0"
+ },
+ "replace": {
+ "roundcube/plugin-installer": "*",
+ "shama/baton": "*"
+ },
+ "require-dev": {
+ "composer/composer": "1.0.*@dev",
+ "phpunit/phpunit": "^4.8.36"
+ },
+ "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",
+ "Mautic",
+ "Maya",
+ "OXID",
+ "Plentymarkets",
+ "Porto",
+ "RadPHP",
+ "SMF",
+ "Thelia",
+ "WolfCMS",
+ "agl",
+ "aimeos",
+ "annotatecms",
+ "attogram",
+ "bitrix",
+ "cakephp",
+ "chef",
+ "cockpit",
+ "codeigniter",
+ "concrete5",
+ "croogo",
+ "dokuwiki",
+ "drupal",
+ "eZ Platform",
+ "elgg",
+ "expressionengine",
+ "fuelphp",
+ "grav",
+ "installer",
+ "itop",
+ "joomla",
+ "kohana",
+ "laravel",
+ "lavalite",
+ "lithium",
+ "magento",
+ "majima",
+ "mako",
+ "mediawiki",
+ "modulework",
+ "modx",
+ "moodle",
+ "osclass",
+ "phpbb",
+ "piwik",
+ "ppi",
+ "puppet",
+ "pxcms",
+ "reindex",
+ "roundcube",
+ "shopware",
+ "silverstripe",
+ "sydes",
+ "symfony",
+ "typo3",
+ "wordpress",
+ "yawik",
+ "zend",
+ "zikula"
+ ],
+ "time": "2018-08-27T06:10:37+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "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": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "time": "2017-07-22T11:58:36+00:00"
+ },
+ {
+ "name": "hamcrest/hamcrest-php",
+ "version": "v2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/hamcrest/hamcrest-php.git",
+ "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad",
+ "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3|^7.0"
+ },
+ "replace": {
+ "cordoval/hamcrest-php": "*",
+ "davedevelopment/hamcrest-php": "*",
+ "kodova/hamcrest-php": "*"
+ },
+ "require-dev": {
+ "phpunit/php-file-iterator": "1.3.3",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "hamcrest"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD"
+ ],
+ "description": "This is the PHP port of Hamcrest Matchers",
+ "keywords": [
+ "test"
+ ],
+ "time": "2016-01-20T08:20:44+00:00"
+ },
+ {
+ "name": "mockery/mockery",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/mockery/mockery.git",
+ "reference": "100633629bf76d57430b86b7098cd6beb996a35a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/mockery/mockery/zipball/100633629bf76d57430b86b7098cd6beb996a35a",
+ "reference": "100633629bf76d57430b86b7098cd6beb996a35a",
+ "shasum": ""
+ },
+ "require": {
+ "hamcrest/hamcrest-php": "~2.0",
+ "lib-pcre": ">=7.0",
+ "php": ">=5.6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5.7.10|~6.5|~7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Mockery": "library/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Pádraic Brady",
+ "email": "padraic.brady@gmail.com",
+ "homepage": "http://blog.astrumfutura.com"
+ },
+ {
+ "name": "Dave Marshall",
+ "email": "dave.marshall@atstsolutions.co.uk",
+ "homepage": "http://davedevelopment.co.uk"
+ }
+ ],
+ "description": "Mockery is a simple yet flexible PHP mock object framework",
+ "homepage": "https://github.com/mockery/mockery",
+ "keywords": [
+ "BDD",
+ "TDD",
+ "library",
+ "mock",
+ "mock objects",
+ "mockery",
+ "stub",
+ "test",
+ "test double",
+ "testing"
+ ],
+ "time": "2018-10-02T21:52:37+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "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"
+ ],
+ "time": "2018-06-11T23:09: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": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.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": "2017-09-11T18:02:19+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "4.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0",
+ "phpdocumentor/type-resolver": "^0.4.0",
+ "webmozart/assert": "^1.0"
+ },
+ "require-dev": {
+ "doctrine/instantiator": "~1.0.5",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "time": "2017-11-30T07:14:17+00:00"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "0.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^5.2||^4.8.24"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.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"
+ }
+ ],
+ "time": "2017-07-14T14:27:02+00:00"
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "1.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "sebastian/comparator": "^1.1|^2.0|^3.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^2.5|^3.2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.8.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "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": "2018-08-05T17:53:17+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "6.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4d3ae9b21a7d7e440bd0cf65565533117976859f",
+ "reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f",
+ "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-23T05:59:32+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.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f",
+ "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "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",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2018-02-01T13:07:23+00:00"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace",
+ "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "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": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2018-02-01T13:16:43+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "7.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "c151651fb6ed264038d486ea262e243af72e5e64"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c151651fb6ed264038d486ea262e243af72e5e64",
+ "reference": "c151651fb6ed264038d486ea262e243af72e5e64",
+ "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.0",
+ "sebastian/comparator": "^3.0",
+ "sebastian/diff": "^3.0",
+ "sebastian/environment": "^3.1 || ^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.4-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": "2018-10-23T05:57:41+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.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "366541b989927187c4ca70490a35615d3fef2dce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce",
+ "reference": "366541b989927187c4ca70490a35615d3fef2dce",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.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": "2018-06-10T07:54:39+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
+ "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.1"
+ },
+ "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"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "time": "2017-07-01T08:51:00+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "234199f4528de6d12aaa58b612e98f7d36adb937"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937",
+ "reference": "234199f4528de6d12aaa58b612e98f7d36adb937",
+ "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": "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"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2017-04-03T13:19:02+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": "theseer/tokenizer",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b",
+ "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^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"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "time": "2017-04-07T12:08:54+00:00"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "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": "2018-01-29T19:49:41+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=7.2"
+ },
+ "platform-dev": []
+}
diff --git a/js/src/ramsey-batch.js b/js/src/ramsey-batch.js
new file mode 100644
index 0000000..840c8ad
--- /dev/null
+++ b/js/src/ramsey-batch.js
@@ -0,0 +1,150 @@
+jQuery( document ).ready( ( $ ) => {
+ const ramseyBatch = {};
+ ramseyBatch.items = [];
+ ramseyBatch.totalItems = ramseyBatch.items.length;
+ ramseyBatch.currentItem = 0;
+ ramseyBatch.itemsComplete = 0;
+ const buttons = $( 'button[name="batchJobTrigger"]' );
+ let currentButton;
+ let progressMeter;
+ let progressBar;
+ let statusMsg;
+
+ /**
+ * Update fetched items
+ * @param {Array} items - Item ID's
+ */
+ function updateItems( items ) {
+ ramseyBatch.items = Object.values( items );
+ ramseyBatch.totalItems = ramseyBatch.items.length;
+ }
+
+ /**
+ * Update the progress bar status
+ * @param {int} current - The number of the current item.
+ */
+ function updateStatus( current ) {
+ const percentComplete = current / ramseyBatch.totalItems * 100;
+ statusMsg.text( `Processing ${current} of ${ramseyBatch.totalItems} items...` );
+ progressBar.css( {
+ width: `${percentComplete}%`
+ } );
+ }
+
+ /**
+ * Complete the batch
+ */
+ function completeBatch() {
+ statusMsg.html( `Done . Processed ${ramseyBatch.totalItems} of ${ramseyBatch.totalItems} items!` );
+ console.log( `Batch is complete! Processed ${ramseyBatch.totalItems} of ${ramseyBatch.totalItems} items!` );
+ ramseyBatch.items = [];
+ ramseyBatch.totalItems = ramseyBatch.items.length;
+ ramseyBatch.currentItem = 0;
+ ramseyBatch.itemsComplete = 0;
+ currentButton.prop( 'disabled', false );
+ }
+
+ /**
+ * Process an individual item
+ * @param {mixed} item - Usually an item ID
+ * @return {bool} - False if the AJAX call failed
+ */
+ function processItem( item ) {
+ return new Promise( ( resolve, reject ) => {
+ ramseyBatch.currentItem += 1;
+ updateStatus( ramseyBatch.currentItem );
+
+ console.log( 'Current item:', item );
+
+ $.ajax( {
+ url: ajaxurl,
+ method: 'POST',
+ data: {
+ action: 'ramsey-batch-item',
+ item
+ },
+ success( response ) {
+ if ( ! response.success ) {
+ console.log( response.data.reason, response );
+
+ return reject();
+ }
+
+ ramseyBatch.itemsComplete++;
+
+ console.log( response.data.reason, response );
+
+ return resolve();
+ }
+ } );
+ } );
+ }
+
+ /**
+ * Process queued items
+ */
+ function processBatchItems() {
+ ramseyBatch.items.reduce( ( promise, currentPromise, index ) => promise.then( () => processItem( currentPromise ) ), Promise.resolve() ).then( completeBatch );
+ }
+
+ /**
+ * Get all the items we'll be working on
+ * @param {Object} trigger - Triggering event
+ * @return {Object} Promise object
+ */
+ function startBatch( trigger ) {
+ return new Promise( ( resolve, reject ) => {
+ currentButton = $( trigger );
+ const batchName = currentButton.data( 'batchName' );
+ const batchNameClean = batchName.replace( new RegExp( '\\\\', 'g' ), '' );
+
+ progressMeter = $( `tr.progressMeter[data-batch-name="${batchNameClean}"]` );
+ progressBar = progressMeter.find( '.meter' );
+ statusMsg = progressMeter.find( '.status' );
+
+ progressMeter.show();
+ currentButton.prop( 'disabled', true );
+
+ $.ajax( {
+ url: ajaxurl,
+ method: 'POST',
+ data: {
+ action: 'ramsey-batch',
+ batchName
+ },
+ success( response ) {
+ if ( ! response.success ) {
+ return reject( new Error( response.data.reason ) );
+ }
+
+ console.log( 'Starting batch!', response.data.items );
+
+ updateItems( response.data.items );
+
+ // No items found
+ if ( ! ramseyBatch.totalItems ) {
+ statusMsg.text( 'No items found.' );
+ currentButton.prop( 'disabled', false );
+ progressBar.css( {
+ width: `100%`
+ } );
+
+ return resolve( 'No items found.' );
+ }
+
+ // Process each item
+ statusMsg.text( `Found ${ramseyBatch.totalItems} items...` );
+
+ resolve();
+ }
+ } );
+ } );
+ }
+
+ // Handle the initial trigger
+ $( buttons ).on( 'click', ( e ) => {
+ startBatch( e.target ).then( processBatchItems, ( response ) => {
+ throw new Error( 'Batch failed.' );
+ } );
+ } );
+} );
diff --git a/src/BatchJob.php b/src/BatchJob.php
new file mode 100644
index 0000000..2bab9d1
--- /dev/null
+++ b/src/BatchJob.php
@@ -0,0 +1,107 @@
+items = [];
+ $this->lastRunTimes = get_option(RB_PLUGIN_SLUG . '_batch-run-timestamps', []);
+
+ add_action('wp_ajax_' . RB_PLUGIN_SLUG, [$this, 'run'] );
+ add_action('wp_ajax_' . RB_PLUGIN_SLUG . '-item', [$this, 'runItem']);
+ }
+
+ /**
+ * Get batch items
+ * @return obj|array Iterable object or array
+ */
+ public function getItems() {
+ return $this->items;
+ }
+
+ /**
+ * Check if batch items are available
+ */
+ public function hasItems() {
+ return !empty( $this->getItems() );
+ }
+
+ /**
+ * Check if the batch name is allowed to run based on the instantiated class.
+ * @return boolean
+ */
+ public function isAllowedBatch() {
+ if( empty($_REQUEST) || !array_key_exists('batchName', $_REQUEST) ) return false;
+
+ return stripslashes($_REQUEST['batchName']) == get_class($this);
+ }
+
+ /**
+ * Get the timestamp corresponding to the time this particular batch was last run.
+ * @return float Timestamp
+ */
+ public function getLastRunTime() {
+ if( empty($this->lastRunTimes) || !array_key_exists(get_called_class(), $this->lastRunTimes) ) {
+ return '';
+ }
+
+ return $this->lastRunTimes[get_called_class()];
+ }
+
+ /**
+ * Get the formatted date corresponding to the time this particular batch was last run.
+ * @param string $format PHP date format
+ * @param string $default Default string if batch has never been run
+ * @return string
+ */
+ public function getLastRunDate($format = 'M j, Y H:i:s', $default = '--') {
+ if( !$this->getLastRunTime() ) return $default;
+ return date($format, $this->getLastRunTime());
+ }
+
+ /**
+ * Update the timestamp when this batch was last run
+ * @param float $timestamp A PHP timestamp
+ * @return bool True if option value has changed, false if not or if update failed.
+ */
+ protected function updateLastRunDate($timestamp = null) {
+ if( !$timestamp ) {
+ $timestamp = current_time('timestamp');
+ }
+ $this->lastRunTimes[get_called_class()] = $timestamp;
+ return update_option(RB_PLUGIN_SLUG . '_batch-run-timestamps', $this->lastRunTimes, false);
+ }
+
+}
diff --git a/src/Controllers/BatchController.php b/src/Controllers/BatchController.php
new file mode 100644
index 0000000..4d4566c
--- /dev/null
+++ b/src/Controllers/BatchController.php
@@ -0,0 +1,44 @@
+jobs = apply_filters(RB_PLUGIN_SLUG . '-jobs', [], $this);
+ }
+
+ /**
+ * Enqueue JS scripts
+ * @return void
+ */
+ public static function enqueueScripts() {
+ wp_register_script(RB_PLUGIN_SLUG, RB_PLUGIN_URL . '/js/src/ramsey-batch.js', ['jquery'], get_plugin_data(RB_PLUGIN_ROOT . '/wp-ramsey-batch.php', false)['Version']);
+
+ $currentScreen = get_current_screen();
+ if( $currentScreen->id == 'tools_page_' . RB_PLUGIN_SLUG) {
+ wp_enqueue_script(RB_PLUGIN_SLUG);
+ }
+ }
+
+ public static function register(string $name) {
+ if( !class_exists($name) ) return;
+ new $name;
+ }
+
+ public function getJobs() {
+ return $this->jobs;
+ }
+
+}
\ No newline at end of file
diff --git a/src/Views/AdminPage.php b/src/Views/AdminPage.php
new file mode 100644
index 0000000..4dd6c1b
--- /dev/null
+++ b/src/Views/AdminPage.php
@@ -0,0 +1,35 @@
+controller = $controller;
+ $this->slug = $slug;
+ $this->title = $title;
+ }
+
+ protected function open() {
+ return '
' . $this->title . ' ';
+ }
+
+ protected function close() {
+ return '
';//.wrap
+ }
+
+ public function debug() {
+ dump(__CLASS__);
+ dump(dirname(__FILE__));
+ dump(get_current_screen());
+ dump($this->controller);
+ dump(RB_PLUGIN_ROOT);
+ dump(RB_PLUGIN_URL);
+ }
+
+}
\ No newline at end of file
diff --git a/src/Views/BatchView.php b/src/Views/BatchView.php
new file mode 100644
index 0000000..53283db
--- /dev/null
+++ b/src/Views/BatchView.php
@@ -0,0 +1,63 @@
+open();
+ ?>
+
+
The batch jobs here are powerful and must be run with caution . It's likely that they will irreversibly change your data. Carefully read and understand each job's description before proceeding.
+
+
+
+
+ Batch Name
+ Job Description
+ Date Last Run
+ Run Job
+
+
+ listBatchJobs(); ?>
+
+
+ debug();
+ echo $this->close();
+ }
+
+ /**
+ * List batch jobs
+ * @return string
+ */
+ protected function listBatchJobs() {
+ $jobs = $this->controller->getJobs();
+ ob_start();
+
+ if( empty($jobs) ) {
+ echo 'There are no registered batch jobs. ';
+ return ob_get_clean();
+ }
+
+ foreach( $jobs as $key => $job ) {
+ echo "";
+ echo '' . $job['name'] . ' ';
+ echo '' . $job['description'] . ' ';
+ echo '' . $job['lastRunDate'] . ' ';
+ echo 'Run Now ';
+ echo " ";
+ echo '';
+ echo '';
+ echo 'Starting job…
';
+ echo '
';
+ echo ' ';
+ echo " ";
+ }
+ return ob_get_clean();
+ }
+
+}
\ No newline at end of file
diff --git a/vendor/autoload.php b/vendor/autoload.php
new file mode 100644
index 0000000..16b98b4
--- /dev/null
+++ b/vendor/autoload.php
@@ -0,0 +1,7 @@
+
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier
+ * @author Jordi Boggiano
+ * @see http://www.php-fig.org/psr/psr-0/
+ * @see http://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ // PSR-4
+ private $prefixLengthsPsr4 = array();
+ private $prefixDirsPsr4 = array();
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ private $prefixesPsr0 = array();
+ private $fallbackDirsPsr0 = array();
+
+ private $useIncludePath = false;
+ private $classMap = array();
+ private $classMapAuthoritative = false;
+ private $missingClasses = array();
+ private $apcuPrefix;
+
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
+ }
+
+ return array();
+ }
+
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array $classMap Class to filename map
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ (array) $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ (array) $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 base directories
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return bool|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ includeFile($file);
+
+ return true;
+ }
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath . '\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+
+ return false;
+ }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+ include $file;
+}
diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE
new file mode 100644
index 0000000..f27399a
--- /dev/null
+++ b/vendor/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
new file mode 100644
index 0000000..f79ddda
--- /dev/null
+++ b/vendor/composer/autoload_classmap.php
@@ -0,0 +1,619 @@
+ $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArray.php',
+ 'Hamcrest\\Arrays\\IsArrayContaining' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContaining.php',
+ 'Hamcrest\\Arrays\\IsArrayContainingInAnyOrder' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInAnyOrder.php',
+ 'Hamcrest\\Arrays\\IsArrayContainingInOrder' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInOrder.php',
+ 'Hamcrest\\Arrays\\IsArrayContainingKey' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKey.php',
+ 'Hamcrest\\Arrays\\IsArrayContainingKeyValuePair' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKeyValuePair.php',
+ 'Hamcrest\\Arrays\\IsArrayWithSize' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayWithSize.php',
+ 'Hamcrest\\Arrays\\MatchingOnce' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/MatchingOnce.php',
+ 'Hamcrest\\Arrays\\SeriesMatchingOnce' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/SeriesMatchingOnce.php',
+ 'Hamcrest\\AssertionError' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/AssertionError.php',
+ 'Hamcrest\\BaseDescription' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/BaseDescription.php',
+ 'Hamcrest\\BaseMatcher' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/BaseMatcher.php',
+ 'Hamcrest\\Collection\\IsEmptyTraversable' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsEmptyTraversable.php',
+ 'Hamcrest\\Collection\\IsTraversableWithSize' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsTraversableWithSize.php',
+ 'Hamcrest\\Core\\AllOf' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/AllOf.php',
+ 'Hamcrest\\Core\\AnyOf' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/AnyOf.php',
+ 'Hamcrest\\Core\\CombinableMatcher' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/CombinableMatcher.php',
+ 'Hamcrest\\Core\\DescribedAs' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/DescribedAs.php',
+ 'Hamcrest\\Core\\Every' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Every.php',
+ 'Hamcrest\\Core\\HasToString' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/HasToString.php',
+ 'Hamcrest\\Core\\Is' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Is.php',
+ 'Hamcrest\\Core\\IsAnything' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsAnything.php',
+ 'Hamcrest\\Core\\IsCollectionContaining' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsCollectionContaining.php',
+ 'Hamcrest\\Core\\IsEqual' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsEqual.php',
+ 'Hamcrest\\Core\\IsIdentical' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsIdentical.php',
+ 'Hamcrest\\Core\\IsInstanceOf' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsInstanceOf.php',
+ 'Hamcrest\\Core\\IsNot' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNot.php',
+ 'Hamcrest\\Core\\IsNull' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNull.php',
+ 'Hamcrest\\Core\\IsSame' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsSame.php',
+ 'Hamcrest\\Core\\IsTypeOf' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsTypeOf.php',
+ 'Hamcrest\\Core\\Set' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Set.php',
+ 'Hamcrest\\Core\\ShortcutCombination' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/ShortcutCombination.php',
+ 'Hamcrest\\Description' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Description.php',
+ 'Hamcrest\\DiagnosingMatcher' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/DiagnosingMatcher.php',
+ 'Hamcrest\\FeatureMatcher' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/FeatureMatcher.php',
+ 'Hamcrest\\Internal\\SelfDescribingValue' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Internal/SelfDescribingValue.php',
+ 'Hamcrest\\Matcher' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matcher.php',
+ 'Hamcrest\\MatcherAssert' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/MatcherAssert.php',
+ 'Hamcrest\\Matchers' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matchers.php',
+ 'Hamcrest\\NullDescription' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/NullDescription.php',
+ 'Hamcrest\\Number\\IsCloseTo' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Number/IsCloseTo.php',
+ 'Hamcrest\\Number\\OrderingComparison' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Number/OrderingComparison.php',
+ 'Hamcrest\\SelfDescribing' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/SelfDescribing.php',
+ 'Hamcrest\\StringDescription' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/StringDescription.php',
+ 'Hamcrest\\Text\\IsEmptyString' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEmptyString.php',
+ 'Hamcrest\\Text\\IsEqualIgnoringCase' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringCase.php',
+ 'Hamcrest\\Text\\IsEqualIgnoringWhiteSpace' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringWhiteSpace.php',
+ 'Hamcrest\\Text\\MatchesPattern' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/MatchesPattern.php',
+ 'Hamcrest\\Text\\StringContains' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContains.php',
+ 'Hamcrest\\Text\\StringContainsIgnoringCase' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsIgnoringCase.php',
+ 'Hamcrest\\Text\\StringContainsInOrder' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsInOrder.php',
+ 'Hamcrest\\Text\\StringEndsWith' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringEndsWith.php',
+ 'Hamcrest\\Text\\StringStartsWith' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringStartsWith.php',
+ 'Hamcrest\\Text\\SubstringMatcher' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/SubstringMatcher.php',
+ 'Hamcrest\\TypeSafeDiagnosingMatcher' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/TypeSafeDiagnosingMatcher.php',
+ 'Hamcrest\\TypeSafeMatcher' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/TypeSafeMatcher.php',
+ 'Hamcrest\\Type\\IsArray' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsArray.php',
+ 'Hamcrest\\Type\\IsBoolean' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsBoolean.php',
+ 'Hamcrest\\Type\\IsCallable' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsCallable.php',
+ 'Hamcrest\\Type\\IsDouble' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsDouble.php',
+ 'Hamcrest\\Type\\IsInteger' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsInteger.php',
+ 'Hamcrest\\Type\\IsNumeric' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsNumeric.php',
+ 'Hamcrest\\Type\\IsObject' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsObject.php',
+ 'Hamcrest\\Type\\IsResource' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsResource.php',
+ 'Hamcrest\\Type\\IsScalar' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsScalar.php',
+ 'Hamcrest\\Type\\IsString' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsString.php',
+ 'Hamcrest\\Util' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Util.php',
+ 'Hamcrest\\Xml\\HasXPath' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Xml/HasXPath.php',
+ 'PHPUnit\\Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php',
+ 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php',
+ 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php',
+ 'PHPUnit\\Framework\\CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php',
+ 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php',
+ 'PHPUnit\\Framework\\Constraint\\ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php',
+ 'PHPUnit\\Framework\\Constraint\\Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php',
+ 'PHPUnit\\Framework\\Constraint\\Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php',
+ 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php',
+ 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php',
+ 'PHPUnit\\Framework\\Constraint\\Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php',
+ 'PHPUnit\\Framework\\Constraint\\Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php',
+ 'PHPUnit\\Framework\\Constraint\\Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php',
+ 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php',
+ 'PHPUnit\\Framework\\Constraint\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php',
+ 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php',
+ 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php',
+ 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php',
+ 'PHPUnit\\Framework\\Constraint\\FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php',
+ 'PHPUnit\\Framework\\Constraint\\GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php',
+ 'PHPUnit\\Framework\\Constraint\\IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php',
+ 'PHPUnit\\Framework\\Constraint\\IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php',
+ 'PHPUnit\\Framework\\Constraint\\IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php',
+ 'PHPUnit\\Framework\\Constraint\\IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php',
+ 'PHPUnit\\Framework\\Constraint\\IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php',
+ 'PHPUnit\\Framework\\Constraint\\IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php',
+ 'PHPUnit\\Framework\\Constraint\\IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php',
+ 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php',
+ 'PHPUnit\\Framework\\Constraint\\IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php',
+ 'PHPUnit\\Framework\\Constraint\\IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php',
+ 'PHPUnit\\Framework\\Constraint\\IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php',
+ 'PHPUnit\\Framework\\Constraint\\IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php',
+ 'PHPUnit\\Framework\\Constraint\\IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php',
+ 'PHPUnit\\Framework\\Constraint\\IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php',
+ 'PHPUnit\\Framework\\Constraint\\IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php',
+ 'PHPUnit\\Framework\\Constraint\\JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php',
+ 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php',
+ 'PHPUnit\\Framework\\Constraint\\LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php',
+ 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php',
+ 'PHPUnit\\Framework\\Constraint\\LogicalNot' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php',
+ 'PHPUnit\\Framework\\Constraint\\LogicalOr' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php',
+ 'PHPUnit\\Framework\\Constraint\\LogicalXor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php',
+ 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php',
+ 'PHPUnit\\Framework\\Constraint\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php',
+ 'PHPUnit\\Framework\\Constraint\\SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php',
+ 'PHPUnit\\Framework\\Constraint\\StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php',
+ 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php',
+ 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php',
+ 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php',
+ 'PHPUnit\\Framework\\Constraint\\TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php',
+ 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php',
+ 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php',
+ 'PHPUnit\\Framework\\DataProviderTestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php',
+ 'PHPUnit\\Framework\\Error\\Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php',
+ 'PHPUnit\\Framework\\Error\\Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Error.php',
+ 'PHPUnit\\Framework\\Error\\Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php',
+ 'PHPUnit\\Framework\\Error\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php',
+ 'PHPUnit\\Framework\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php',
+ 'PHPUnit\\Framework\\ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php',
+ 'PHPUnit\\Framework\\ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php',
+ 'PHPUnit\\Framework\\IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php',
+ 'PHPUnit\\Framework\\IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php',
+ 'PHPUnit\\Framework\\IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php',
+ 'PHPUnit\\Framework\\InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php',
+ 'PHPUnit\\Framework\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php',
+ 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/NamespaceMatch.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php',
+ 'PHPUnit\\Framework\\MockObject\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php',
+ 'PHPUnit\\Framework\\MockObject\\Generator' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Generator.php',
+ 'PHPUnit\\Framework\\MockObject\\Invocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation/Invocation.php',
+ 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/InvocationMocker.php',
+ 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation/ObjectInvocation.php',
+ 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation/StaticInvocation.php',
+ 'PHPUnit\\Framework\\MockObject\\Invokable' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invokable.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/AnyInvokedCount.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/AnyParameters.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/ConsecutiveParameters.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\DeferredError' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/DeferredError.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/Invocation.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtIndex.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtMostCount.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedCount.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedRecorder.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/MethodName.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/Parameters.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/StatelessInvocation.php',
+ 'PHPUnit\\Framework\\MockObject\\MockBuilder' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php',
+ 'PHPUnit\\Framework\\MockObject\\MockMethod' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockMethod.php',
+ 'PHPUnit\\Framework\\MockObject\\MockMethodSet' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php',
+ 'PHPUnit\\Framework\\MockObject\\MockObject' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/ForwardCompatibility/MockObject.php',
+ 'PHPUnit\\Framework\\MockObject\\RuntimeException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/MatcherCollection.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php',
+ 'PHPUnit\\Framework\\MockObject\\Verifiable' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Verifiable.php',
+ 'PHPUnit\\Framework\\OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php',
+ 'PHPUnit\\Framework\\RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php',
+ 'PHPUnit\\Framework\\RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php',
+ 'PHPUnit\\Framework\\SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php',
+ 'PHPUnit\\Framework\\SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php',
+ 'PHPUnit\\Framework\\SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php',
+ 'PHPUnit\\Framework\\SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php',
+ 'PHPUnit\\Framework\\SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php',
+ 'PHPUnit\\Framework\\SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php',
+ 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php',
+ 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php',
+ 'PHPUnit\\Framework\\TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php',
+ 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php',
+ 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php',
+ 'PHPUnit\\Framework\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php',
+ 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php',
+ 'PHPUnit\\Framework\\TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php',
+ 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php',
+ 'PHPUnit\\Framework\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php',
+ 'PHPUnit\\Framework\\WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php',
+ 'PHPUnit\\Runner\\AfterIncompleteTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php',
+ 'PHPUnit\\Runner\\AfterLastTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php',
+ 'PHPUnit\\Runner\\AfterRiskyTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php',
+ 'PHPUnit\\Runner\\AfterSkippedTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php',
+ 'PHPUnit\\Runner\\AfterSuccessfulTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php',
+ 'PHPUnit\\Runner\\AfterTestErrorHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php',
+ 'PHPUnit\\Runner\\AfterTestFailureHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php',
+ 'PHPUnit\\Runner\\AfterTestWarningHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php',
+ 'PHPUnit\\Runner\\BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php',
+ 'PHPUnit\\Runner\\BeforeFirstTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php',
+ 'PHPUnit\\Runner\\BeforeTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php',
+ 'PHPUnit\\Runner\\Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php',
+ 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php',
+ 'PHPUnit\\Runner\\Filter\\Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php',
+ 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php',
+ 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php',
+ 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php',
+ 'PHPUnit\\Runner\\Hook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/Hook.php',
+ 'PHPUnit\\Runner\\NullTestResultCache' => $vendorDir . '/phpunit/phpunit/src/Util/NullTestResultCache.php',
+ 'PHPUnit\\Runner\\PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Runner/PhptTestCase.php',
+ 'PHPUnit\\Runner\\ResultCacheExtension' => $vendorDir . '/phpunit/phpunit/src/Runner/ResultCacheExtension.php',
+ 'PHPUnit\\Runner\\StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php',
+ 'PHPUnit\\Runner\\TestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/TestHook.php',
+ 'PHPUnit\\Runner\\TestListenerAdapter' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php',
+ 'PHPUnit\\Runner\\TestResultCache' => $vendorDir . '/phpunit/phpunit/src/Util/TestResultCache.php',
+ 'PHPUnit\\Runner\\TestResultCacheInterface' => $vendorDir . '/phpunit/phpunit/src/Util/TestResultCacheInterface.php',
+ 'PHPUnit\\Runner\\TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php',
+ 'PHPUnit\\Runner\\TestSuiteSorter' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteSorter.php',
+ 'PHPUnit\\Runner\\Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php',
+ 'PHPUnit\\TextUI\\Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php',
+ 'PHPUnit\\TextUI\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php',
+ 'PHPUnit\\TextUI\\TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php',
+ 'PHPUnit\\Util\\Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php',
+ 'PHPUnit\\Util\\Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php',
+ 'PHPUnit\\Util\\ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php',
+ 'PHPUnit\\Util\\ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php',
+ 'PHPUnit\\Util\\FileLoader' => $vendorDir . '/phpunit/phpunit/src/Util/FileLoader.php',
+ 'PHPUnit\\Util\\Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php',
+ 'PHPUnit\\Util\\Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php',
+ 'PHPUnit\\Util\\Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php',
+ 'PHPUnit\\Util\\GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php',
+ 'PHPUnit\\Util\\InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php',
+ 'PHPUnit\\Util\\Json' => $vendorDir . '/phpunit/phpunit/src/Util/Json.php',
+ 'PHPUnit\\Util\\Log\\JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php',
+ 'PHPUnit\\Util\\Log\\TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php',
+ 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php',
+ 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php',
+ 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php',
+ 'PHPUnit\\Util\\Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php',
+ 'PHPUnit\\Util\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Util/RegularExpression.php',
+ 'PHPUnit\\Util\\Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php',
+ 'PHPUnit\\Util\\TestDox\\CliTestDoxPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php',
+ 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php',
+ 'PHPUnit\\Util\\TestDox\\NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php',
+ 'PHPUnit\\Util\\TestDox\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php',
+ 'PHPUnit\\Util\\TestDox\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TestResult.php',
+ 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php',
+ 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php',
+ 'PHPUnit\\Util\\TextTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/TextTestListRenderer.php',
+ 'PHPUnit\\Util\\Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php',
+ 'PHPUnit\\Util\\XdebugFilterScriptGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/XdebugFilterScriptGenerator.php',
+ 'PHPUnit\\Util\\Xml' => $vendorDir . '/phpunit/phpunit/src/Util/Xml.php',
+ 'PHPUnit\\Util\\XmlTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php',
+ 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockObject.php',
+ 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php',
+ 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php',
+ 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php',
+ 'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php',
+ 'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php',
+ 'PharIo\\Manifest\\AuthorCollection' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollection.php',
+ 'PharIo\\Manifest\\AuthorCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollectionIterator.php',
+ 'PharIo\\Manifest\\AuthorElement' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElement.php',
+ 'PharIo\\Manifest\\AuthorElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElementCollection.php',
+ 'PharIo\\Manifest\\BundledComponent' => $vendorDir . '/phar-io/manifest/src/values/BundledComponent.php',
+ 'PharIo\\Manifest\\BundledComponentCollection' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollection.php',
+ 'PharIo\\Manifest\\BundledComponentCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php',
+ 'PharIo\\Manifest\\BundlesElement' => $vendorDir . '/phar-io/manifest/src/xml/BundlesElement.php',
+ 'PharIo\\Manifest\\ComponentElement' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElement.php',
+ 'PharIo\\Manifest\\ComponentElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElementCollection.php',
+ 'PharIo\\Manifest\\ContainsElement' => $vendorDir . '/phar-io/manifest/src/xml/ContainsElement.php',
+ 'PharIo\\Manifest\\CopyrightElement' => $vendorDir . '/phar-io/manifest/src/xml/CopyrightElement.php',
+ 'PharIo\\Manifest\\CopyrightInformation' => $vendorDir . '/phar-io/manifest/src/values/CopyrightInformation.php',
+ 'PharIo\\Manifest\\ElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ElementCollection.php',
+ 'PharIo\\Manifest\\Email' => $vendorDir . '/phar-io/manifest/src/values/Email.php',
+ 'PharIo\\Manifest\\Exception' => $vendorDir . '/phar-io/manifest/src/exceptions/Exception.php',
+ 'PharIo\\Manifest\\ExtElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtElement.php',
+ 'PharIo\\Manifest\\ExtElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ExtElementCollection.php',
+ 'PharIo\\Manifest\\Extension' => $vendorDir . '/phar-io/manifest/src/values/Extension.php',
+ 'PharIo\\Manifest\\ExtensionElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtensionElement.php',
+ 'PharIo\\Manifest\\InvalidApplicationNameException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php',
+ 'PharIo\\Manifest\\InvalidEmailException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidEmailException.php',
+ 'PharIo\\Manifest\\InvalidUrlException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidUrlException.php',
+ 'PharIo\\Manifest\\Library' => $vendorDir . '/phar-io/manifest/src/values/Library.php',
+ 'PharIo\\Manifest\\License' => $vendorDir . '/phar-io/manifest/src/values/License.php',
+ 'PharIo\\Manifest\\LicenseElement' => $vendorDir . '/phar-io/manifest/src/xml/LicenseElement.php',
+ 'PharIo\\Manifest\\Manifest' => $vendorDir . '/phar-io/manifest/src/values/Manifest.php',
+ 'PharIo\\Manifest\\ManifestDocument' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocument.php',
+ 'PharIo\\Manifest\\ManifestDocumentException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php',
+ 'PharIo\\Manifest\\ManifestDocumentLoadingException' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php',
+ 'PharIo\\Manifest\\ManifestDocumentMapper' => $vendorDir . '/phar-io/manifest/src/ManifestDocumentMapper.php',
+ 'PharIo\\Manifest\\ManifestDocumentMapperException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php',
+ 'PharIo\\Manifest\\ManifestElement' => $vendorDir . '/phar-io/manifest/src/xml/ManifestElement.php',
+ 'PharIo\\Manifest\\ManifestElementException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestElementException.php',
+ 'PharIo\\Manifest\\ManifestLoader' => $vendorDir . '/phar-io/manifest/src/ManifestLoader.php',
+ 'PharIo\\Manifest\\ManifestLoaderException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php',
+ 'PharIo\\Manifest\\ManifestSerializer' => $vendorDir . '/phar-io/manifest/src/ManifestSerializer.php',
+ 'PharIo\\Manifest\\PhpElement' => $vendorDir . '/phar-io/manifest/src/xml/PhpElement.php',
+ 'PharIo\\Manifest\\PhpExtensionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpExtensionRequirement.php',
+ 'PharIo\\Manifest\\PhpVersionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpVersionRequirement.php',
+ 'PharIo\\Manifest\\Requirement' => $vendorDir . '/phar-io/manifest/src/values/Requirement.php',
+ 'PharIo\\Manifest\\RequirementCollection' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollection.php',
+ 'PharIo\\Manifest\\RequirementCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollectionIterator.php',
+ 'PharIo\\Manifest\\RequiresElement' => $vendorDir . '/phar-io/manifest/src/xml/RequiresElement.php',
+ 'PharIo\\Manifest\\Type' => $vendorDir . '/phar-io/manifest/src/values/Type.php',
+ 'PharIo\\Manifest\\Url' => $vendorDir . '/phar-io/manifest/src/values/Url.php',
+ 'PharIo\\Version\\AbstractVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AbstractVersionConstraint.php',
+ 'PharIo\\Version\\AndVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/AndVersionConstraintGroup.php',
+ 'PharIo\\Version\\AnyVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AnyVersionConstraint.php',
+ 'PharIo\\Version\\ExactVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/ExactVersionConstraint.php',
+ 'PharIo\\Version\\Exception' => $vendorDir . '/phar-io/version/src/exceptions/Exception.php',
+ 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php',
+ 'PharIo\\Version\\InvalidPreReleaseSuffixException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php',
+ 'PharIo\\Version\\InvalidVersionException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidVersionException.php',
+ 'PharIo\\Version\\OrVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/OrVersionConstraintGroup.php',
+ 'PharIo\\Version\\PreReleaseSuffix' => $vendorDir . '/phar-io/version/src/PreReleaseSuffix.php',
+ 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php',
+ 'PharIo\\Version\\SpecificMajorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php',
+ 'PharIo\\Version\\UnsupportedVersionConstraintException' => $vendorDir . '/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php',
+ 'PharIo\\Version\\Version' => $vendorDir . '/phar-io/version/src/Version.php',
+ 'PharIo\\Version\\VersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/VersionConstraint.php',
+ 'PharIo\\Version\\VersionConstraintParser' => $vendorDir . '/phar-io/version/src/VersionConstraintParser.php',
+ 'PharIo\\Version\\VersionConstraintValue' => $vendorDir . '/phar-io/version/src/VersionConstraintValue.php',
+ 'PharIo\\Version\\VersionNumber' => $vendorDir . '/phar-io/version/src/VersionNumber.php',
+ 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php',
+ 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php',
+ 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php',
+ 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php',
+ 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php',
+ 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Source.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php',
+ 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php',
+ 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php',
+ 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php',
+ 'SebastianBergmann\\CodeCoverage\\Version' => $vendorDir . '/phpunit/php-code-coverage/src/Version.php',
+ 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php',
+ 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php',
+ 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php',
+ 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php',
+ 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php',
+ 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php',
+ 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php',
+ 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php',
+ 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php',
+ 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php',
+ 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php',
+ 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php',
+ 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php',
+ 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php',
+ 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php',
+ 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php',
+ 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php',
+ 'SebastianBergmann\\Diff\\ConfigurationException' => $vendorDir . '/sebastian/diff/src/Exception/ConfigurationException.php',
+ 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php',
+ 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php',
+ 'SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php',
+ 'SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php',
+ 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php',
+ 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php',
+ 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php',
+ 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php',
+ 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php',
+ 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php',
+ 'SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php',
+ 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php',
+ 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php',
+ 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php',
+ 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php',
+ 'SebastianBergmann\\Environment\\OperatingSystem' => $vendorDir . '/sebastian/environment/src/OperatingSystem.php',
+ 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php',
+ 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php',
+ 'SebastianBergmann\\FileIterator\\Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php',
+ 'SebastianBergmann\\FileIterator\\Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php',
+ 'SebastianBergmann\\FileIterator\\Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php',
+ 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php',
+ 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php',
+ 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/exceptions/Exception.php',
+ 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php',
+ 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/exceptions/RuntimeException.php',
+ 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php',
+ 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php',
+ 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php',
+ 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\ObjectReflector\\Exception' => $vendorDir . '/sebastian/object-reflector/src/Exception.php',
+ 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => $vendorDir . '/sebastian/object-reflector/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => $vendorDir . '/sebastian/object-reflector/src/ObjectReflector.php',
+ 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php',
+ 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php',
+ 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php',
+ 'SebastianBergmann\\Timer\\Exception' => $vendorDir . '/phpunit/php-timer/src/Exception.php',
+ 'SebastianBergmann\\Timer\\RuntimeException' => $vendorDir . '/phpunit/php-timer/src/RuntimeException.php',
+ 'SebastianBergmann\\Timer\\Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php',
+ 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php',
+ 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php',
+ 'TheSeer\\Tokenizer\\Exception' => $vendorDir . '/theseer/tokenizer/src/Exception.php',
+ 'TheSeer\\Tokenizer\\NamespaceUri' => $vendorDir . '/theseer/tokenizer/src/NamespaceUri.php',
+ 'TheSeer\\Tokenizer\\NamespaceUriException' => $vendorDir . '/theseer/tokenizer/src/NamespaceUriException.php',
+ 'TheSeer\\Tokenizer\\Token' => $vendorDir . '/theseer/tokenizer/src/Token.php',
+ 'TheSeer\\Tokenizer\\TokenCollection' => $vendorDir . '/theseer/tokenizer/src/TokenCollection.php',
+ 'TheSeer\\Tokenizer\\TokenCollectionException' => $vendorDir . '/theseer/tokenizer/src/TokenCollectionException.php',
+ 'TheSeer\\Tokenizer\\Tokenizer' => $vendorDir . '/theseer/tokenizer/src/Tokenizer.php',
+ 'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php',
+);
diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php
new file mode 100644
index 0000000..d931b8f
--- /dev/null
+++ b/vendor/composer/autoload_files.php
@@ -0,0 +1,10 @@
+ $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
+);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
new file mode 100644
index 0000000..e652f47
--- /dev/null
+++ b/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,11 @@
+ array($vendorDir . '/phpspec/prophecy/src'),
+ 'Mockery' => array($vendorDir . '/mockery/mockery/library'),
+);
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
new file mode 100644
index 0000000..66a00f0
--- /dev/null
+++ b/vendor/composer/autoload_psr4.php
@@ -0,0 +1,16 @@
+ array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'),
+ 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
+ 'RamseySolutions\\RamseyBatch\\' => array($baseDir . '/src'),
+ 'RamseyBatchTests\\' => array($baseDir . '/tests'),
+ 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
+ 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
+ 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
+);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
new file mode 100644
index 0000000..6a53b21
--- /dev/null
+++ b/vendor/composer/autoload_real.php
@@ -0,0 +1,70 @@
+= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
+ if ($useStaticLoader) {
+ require_once __DIR__ . '/autoload_static.php';
+
+ call_user_func(\Composer\Autoload\ComposerStaticInit92ac2e15ce8f444fc54507a43b3e6bb1::getInitializer($loader));
+ } else {
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
+
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
+
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
+ }
+ }
+
+ $loader->register(true);
+
+ if ($useStaticLoader) {
+ $includeFiles = Composer\Autoload\ComposerStaticInit92ac2e15ce8f444fc54507a43b3e6bb1::$files;
+ } else {
+ $includeFiles = require __DIR__ . '/autoload_files.php';
+ }
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequire92ac2e15ce8f444fc54507a43b3e6bb1($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
+
+function composerRequire92ac2e15ce8f444fc54507a43b3e6bb1($fileIdentifier, $file)
+{
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ require $file;
+
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+ }
+}
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
new file mode 100644
index 0000000..670d67b
--- /dev/null
+++ b/vendor/composer/autoload_static.php
@@ -0,0 +1,711 @@
+ __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 'p' =>
+ array (
+ 'phpDocumentor\\Reflection\\' => 25,
+ ),
+ 'W' =>
+ array (
+ 'Webmozart\\Assert\\' => 17,
+ ),
+ 'R' =>
+ array (
+ 'RamseySolutions\\RamseyBatch\\' => 28,
+ 'RamseyBatchTests\\' => 17,
+ ),
+ 'D' =>
+ array (
+ 'Doctrine\\Instantiator\\' => 22,
+ 'DeepCopy\\' => 9,
+ ),
+ 'C' =>
+ array (
+ 'Composer\\Installers\\' => 20,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'phpDocumentor\\Reflection\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
+ 1 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
+ 2 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
+ ),
+ 'Webmozart\\Assert\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/webmozart/assert/src',
+ ),
+ 'RamseySolutions\\RamseyBatch\\' =>
+ array (
+ 0 => __DIR__ . '/../..' . '/src',
+ ),
+ 'RamseyBatchTests\\' =>
+ array (
+ 0 => __DIR__ . '/../..' . '/tests',
+ ),
+ 'Doctrine\\Instantiator\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator',
+ ),
+ 'DeepCopy\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy',
+ ),
+ 'Composer\\Installers\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
+ ),
+ );
+
+ public static $prefixesPsr0 = array (
+ 'P' =>
+ array (
+ 'Prophecy\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/phpspec/prophecy/src',
+ ),
+ ),
+ 'M' =>
+ array (
+ 'Mockery' =>
+ array (
+ 0 => __DIR__ . '/..' . '/mockery/mockery/library',
+ ),
+ ),
+ );
+
+ public static $classMap = array (
+ 'Hamcrest\\Arrays\\IsArray' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArray.php',
+ 'Hamcrest\\Arrays\\IsArrayContaining' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContaining.php',
+ 'Hamcrest\\Arrays\\IsArrayContainingInAnyOrder' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInAnyOrder.php',
+ 'Hamcrest\\Arrays\\IsArrayContainingInOrder' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInOrder.php',
+ 'Hamcrest\\Arrays\\IsArrayContainingKey' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKey.php',
+ 'Hamcrest\\Arrays\\IsArrayContainingKeyValuePair' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKeyValuePair.php',
+ 'Hamcrest\\Arrays\\IsArrayWithSize' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayWithSize.php',
+ 'Hamcrest\\Arrays\\MatchingOnce' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/MatchingOnce.php',
+ 'Hamcrest\\Arrays\\SeriesMatchingOnce' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/SeriesMatchingOnce.php',
+ 'Hamcrest\\AssertionError' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/AssertionError.php',
+ 'Hamcrest\\BaseDescription' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/BaseDescription.php',
+ 'Hamcrest\\BaseMatcher' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/BaseMatcher.php',
+ 'Hamcrest\\Collection\\IsEmptyTraversable' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsEmptyTraversable.php',
+ 'Hamcrest\\Collection\\IsTraversableWithSize' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsTraversableWithSize.php',
+ 'Hamcrest\\Core\\AllOf' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/AllOf.php',
+ 'Hamcrest\\Core\\AnyOf' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/AnyOf.php',
+ 'Hamcrest\\Core\\CombinableMatcher' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/CombinableMatcher.php',
+ 'Hamcrest\\Core\\DescribedAs' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/DescribedAs.php',
+ 'Hamcrest\\Core\\Every' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Every.php',
+ 'Hamcrest\\Core\\HasToString' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/HasToString.php',
+ 'Hamcrest\\Core\\Is' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Is.php',
+ 'Hamcrest\\Core\\IsAnything' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsAnything.php',
+ 'Hamcrest\\Core\\IsCollectionContaining' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsCollectionContaining.php',
+ 'Hamcrest\\Core\\IsEqual' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsEqual.php',
+ 'Hamcrest\\Core\\IsIdentical' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsIdentical.php',
+ 'Hamcrest\\Core\\IsInstanceOf' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsInstanceOf.php',
+ 'Hamcrest\\Core\\IsNot' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNot.php',
+ 'Hamcrest\\Core\\IsNull' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNull.php',
+ 'Hamcrest\\Core\\IsSame' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsSame.php',
+ 'Hamcrest\\Core\\IsTypeOf' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsTypeOf.php',
+ 'Hamcrest\\Core\\Set' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Set.php',
+ 'Hamcrest\\Core\\ShortcutCombination' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/ShortcutCombination.php',
+ 'Hamcrest\\Description' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Description.php',
+ 'Hamcrest\\DiagnosingMatcher' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/DiagnosingMatcher.php',
+ 'Hamcrest\\FeatureMatcher' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/FeatureMatcher.php',
+ 'Hamcrest\\Internal\\SelfDescribingValue' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Internal/SelfDescribingValue.php',
+ 'Hamcrest\\Matcher' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matcher.php',
+ 'Hamcrest\\MatcherAssert' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/MatcherAssert.php',
+ 'Hamcrest\\Matchers' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matchers.php',
+ 'Hamcrest\\NullDescription' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/NullDescription.php',
+ 'Hamcrest\\Number\\IsCloseTo' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Number/IsCloseTo.php',
+ 'Hamcrest\\Number\\OrderingComparison' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Number/OrderingComparison.php',
+ 'Hamcrest\\SelfDescribing' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/SelfDescribing.php',
+ 'Hamcrest\\StringDescription' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/StringDescription.php',
+ 'Hamcrest\\Text\\IsEmptyString' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEmptyString.php',
+ 'Hamcrest\\Text\\IsEqualIgnoringCase' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringCase.php',
+ 'Hamcrest\\Text\\IsEqualIgnoringWhiteSpace' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringWhiteSpace.php',
+ 'Hamcrest\\Text\\MatchesPattern' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/MatchesPattern.php',
+ 'Hamcrest\\Text\\StringContains' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContains.php',
+ 'Hamcrest\\Text\\StringContainsIgnoringCase' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsIgnoringCase.php',
+ 'Hamcrest\\Text\\StringContainsInOrder' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsInOrder.php',
+ 'Hamcrest\\Text\\StringEndsWith' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringEndsWith.php',
+ 'Hamcrest\\Text\\StringStartsWith' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringStartsWith.php',
+ 'Hamcrest\\Text\\SubstringMatcher' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/SubstringMatcher.php',
+ 'Hamcrest\\TypeSafeDiagnosingMatcher' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/TypeSafeDiagnosingMatcher.php',
+ 'Hamcrest\\TypeSafeMatcher' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/TypeSafeMatcher.php',
+ 'Hamcrest\\Type\\IsArray' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsArray.php',
+ 'Hamcrest\\Type\\IsBoolean' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsBoolean.php',
+ 'Hamcrest\\Type\\IsCallable' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsCallable.php',
+ 'Hamcrest\\Type\\IsDouble' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsDouble.php',
+ 'Hamcrest\\Type\\IsInteger' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsInteger.php',
+ 'Hamcrest\\Type\\IsNumeric' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsNumeric.php',
+ 'Hamcrest\\Type\\IsObject' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsObject.php',
+ 'Hamcrest\\Type\\IsResource' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsResource.php',
+ 'Hamcrest\\Type\\IsScalar' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsScalar.php',
+ 'Hamcrest\\Type\\IsString' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsString.php',
+ 'Hamcrest\\Util' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Util.php',
+ 'Hamcrest\\Xml\\HasXPath' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest/Xml/HasXPath.php',
+ 'PHPUnit\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php',
+ 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php',
+ 'PHPUnit\\Framework\\AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/AssertionFailedError.php',
+ 'PHPUnit\\Framework\\CodeCoverageException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CodeCoverageException.php',
+ 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php',
+ 'PHPUnit\\Framework\\Constraint\\ArraySubset' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php',
+ 'PHPUnit\\Framework\\Constraint\\Attribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php',
+ 'PHPUnit\\Framework\\Constraint\\Callback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Callback.php',
+ 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php',
+ 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php',
+ 'PHPUnit\\Framework\\Constraint\\Composite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Composite.php',
+ 'PHPUnit\\Framework\\Constraint\\Constraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php',
+ 'PHPUnit\\Framework\\Constraint\\Count' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Count.php',
+ 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php',
+ 'PHPUnit\\Framework\\Constraint\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Exception.php',
+ 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php',
+ 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php',
+ 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php',
+ 'PHPUnit\\Framework\\Constraint\\FileExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php',
+ 'PHPUnit\\Framework\\Constraint\\GreaterThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php',
+ 'PHPUnit\\Framework\\Constraint\\IsAnything' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php',
+ 'PHPUnit\\Framework\\Constraint\\IsEmpty' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php',
+ 'PHPUnit\\Framework\\Constraint\\IsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php',
+ 'PHPUnit\\Framework\\Constraint\\IsFalse' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php',
+ 'PHPUnit\\Framework\\Constraint\\IsFinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php',
+ 'PHPUnit\\Framework\\Constraint\\IsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php',
+ 'PHPUnit\\Framework\\Constraint\\IsInfinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php',
+ 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php',
+ 'PHPUnit\\Framework\\Constraint\\IsJson' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php',
+ 'PHPUnit\\Framework\\Constraint\\IsNan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php',
+ 'PHPUnit\\Framework\\Constraint\\IsNull' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php',
+ 'PHPUnit\\Framework\\Constraint\\IsReadable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php',
+ 'PHPUnit\\Framework\\Constraint\\IsTrue' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php',
+ 'PHPUnit\\Framework\\Constraint\\IsType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsType.php',
+ 'PHPUnit\\Framework\\Constraint\\IsWritable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php',
+ 'PHPUnit\\Framework\\Constraint\\JsonMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php',
+ 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php',
+ 'PHPUnit\\Framework\\Constraint\\LessThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php',
+ 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php',
+ 'PHPUnit\\Framework\\Constraint\\LogicalNot' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php',
+ 'PHPUnit\\Framework\\Constraint\\LogicalOr' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php',
+ 'PHPUnit\\Framework\\Constraint\\LogicalXor' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php',
+ 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php',
+ 'PHPUnit\\Framework\\Constraint\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php',
+ 'PHPUnit\\Framework\\Constraint\\SameSize' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php',
+ 'PHPUnit\\Framework\\Constraint\\StringContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php',
+ 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php',
+ 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php',
+ 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php',
+ 'PHPUnit\\Framework\\Constraint\\TraversableContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php',
+ 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php',
+ 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php',
+ 'PHPUnit\\Framework\\DataProviderTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php',
+ 'PHPUnit\\Framework\\Error\\Deprecated' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Deprecated.php',
+ 'PHPUnit\\Framework\\Error\\Error' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Error.php',
+ 'PHPUnit\\Framework\\Error\\Notice' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Notice.php',
+ 'PHPUnit\\Framework\\Error\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Warning.php',
+ 'PHPUnit\\Framework\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception.php',
+ 'PHPUnit\\Framework\\ExceptionWrapper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php',
+ 'PHPUnit\\Framework\\ExpectationFailedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php',
+ 'PHPUnit\\Framework\\IncompleteTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTest.php',
+ 'PHPUnit\\Framework\\IncompleteTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php',
+ 'PHPUnit\\Framework\\IncompleteTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestError.php',
+ 'PHPUnit\\Framework\\InvalidCoversTargetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php',
+ 'PHPUnit\\Framework\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php',
+ 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/NamespaceMatch.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php',
+ 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php',
+ 'PHPUnit\\Framework\\MockObject\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php',
+ 'PHPUnit\\Framework\\MockObject\\Generator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Generator.php',
+ 'PHPUnit\\Framework\\MockObject\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Invocation/Invocation.php',
+ 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/InvocationMocker.php',
+ 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Invocation/ObjectInvocation.php',
+ 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Invocation/StaticInvocation.php',
+ 'PHPUnit\\Framework\\MockObject\\Invokable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Invokable.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/AnyInvokedCount.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/AnyParameters.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/ConsecutiveParameters.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\DeferredError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/DeferredError.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/Invocation.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtIndex.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtMostCount.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedCount.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedRecorder.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/MethodName.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/Parameters.php',
+ 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher/StatelessInvocation.php',
+ 'PHPUnit\\Framework\\MockObject\\MockBuilder' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php',
+ 'PHPUnit\\Framework\\MockObject\\MockMethod' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockMethod.php',
+ 'PHPUnit\\Framework\\MockObject\\MockMethodSet' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php',
+ 'PHPUnit\\Framework\\MockObject\\MockObject' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/ForwardCompatibility/MockObject.php',
+ 'PHPUnit\\Framework\\MockObject\\RuntimeException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/MatcherCollection.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php',
+ 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php',
+ 'PHPUnit\\Framework\\MockObject\\Verifiable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Verifiable.php',
+ 'PHPUnit\\Framework\\OutputError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/OutputError.php',
+ 'PHPUnit\\Framework\\RiskyTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTest.php',
+ 'PHPUnit\\Framework\\RiskyTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTestError.php',
+ 'PHPUnit\\Framework\\SelfDescribing' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SelfDescribing.php',
+ 'PHPUnit\\Framework\\SkippedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTest.php',
+ 'PHPUnit\\Framework\\SkippedTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestCase.php',
+ 'PHPUnit\\Framework\\SkippedTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestError.php',
+ 'PHPUnit\\Framework\\SkippedTestSuiteError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php',
+ 'PHPUnit\\Framework\\SyntheticError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SyntheticError.php',
+ 'PHPUnit\\Framework\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Test.php',
+ 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestCase.php',
+ 'PHPUnit\\Framework\\TestFailure' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestFailure.php',
+ 'PHPUnit\\Framework\\TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListener.php',
+ 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php',
+ 'PHPUnit\\Framework\\TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestResult.php',
+ 'PHPUnit\\Framework\\TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite.php',
+ 'PHPUnit\\Framework\\TestSuiteIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php',
+ 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php',
+ 'PHPUnit\\Framework\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Warning.php',
+ 'PHPUnit\\Framework\\WarningTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/WarningTestCase.php',
+ 'PHPUnit\\Runner\\AfterIncompleteTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php',
+ 'PHPUnit\\Runner\\AfterLastTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php',
+ 'PHPUnit\\Runner\\AfterRiskyTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php',
+ 'PHPUnit\\Runner\\AfterSkippedTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php',
+ 'PHPUnit\\Runner\\AfterSuccessfulTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php',
+ 'PHPUnit\\Runner\\AfterTestErrorHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php',
+ 'PHPUnit\\Runner\\AfterTestFailureHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php',
+ 'PHPUnit\\Runner\\AfterTestWarningHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php',
+ 'PHPUnit\\Runner\\BaseTestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/BaseTestRunner.php',
+ 'PHPUnit\\Runner\\BeforeFirstTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php',
+ 'PHPUnit\\Runner\\BeforeTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php',
+ 'PHPUnit\\Runner\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Exception.php',
+ 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php',
+ 'PHPUnit\\Runner\\Filter\\Factory' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Factory.php',
+ 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php',
+ 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php',
+ 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php',
+ 'PHPUnit\\Runner\\Hook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/Hook.php',
+ 'PHPUnit\\Runner\\NullTestResultCache' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/NullTestResultCache.php',
+ 'PHPUnit\\Runner\\PhptTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/PhptTestCase.php',
+ 'PHPUnit\\Runner\\ResultCacheExtension' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/ResultCacheExtension.php',
+ 'PHPUnit\\Runner\\StandardTestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php',
+ 'PHPUnit\\Runner\\TestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/TestHook.php',
+ 'PHPUnit\\Runner\\TestListenerAdapter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php',
+ 'PHPUnit\\Runner\\TestResultCache' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestResultCache.php',
+ 'PHPUnit\\Runner\\TestResultCacheInterface' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestResultCacheInterface.php',
+ 'PHPUnit\\Runner\\TestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php',
+ 'PHPUnit\\Runner\\TestSuiteSorter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteSorter.php',
+ 'PHPUnit\\Runner\\Version' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Version.php',
+ 'PHPUnit\\TextUI\\Command' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Command.php',
+ 'PHPUnit\\TextUI\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/ResultPrinter.php',
+ 'PHPUnit\\TextUI\\TestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/TestRunner.php',
+ 'PHPUnit\\Util\\Blacklist' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Blacklist.php',
+ 'PHPUnit\\Util\\Configuration' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Configuration.php',
+ 'PHPUnit\\Util\\ConfigurationGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php',
+ 'PHPUnit\\Util\\ErrorHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ErrorHandler.php',
+ 'PHPUnit\\Util\\FileLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/FileLoader.php',
+ 'PHPUnit\\Util\\Filesystem' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filesystem.php',
+ 'PHPUnit\\Util\\Filter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filter.php',
+ 'PHPUnit\\Util\\Getopt' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Getopt.php',
+ 'PHPUnit\\Util\\GlobalState' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/GlobalState.php',
+ 'PHPUnit\\Util\\InvalidArgumentHelper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php',
+ 'PHPUnit\\Util\\Json' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Json.php',
+ 'PHPUnit\\Util\\Log\\JUnit' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JUnit.php',
+ 'PHPUnit\\Util\\Log\\TeamCity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TeamCity.php',
+ 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php',
+ 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php',
+ 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php',
+ 'PHPUnit\\Util\\Printer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Printer.php',
+ 'PHPUnit\\Util\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/RegularExpression.php',
+ 'PHPUnit\\Util\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Test.php',
+ 'PHPUnit\\Util\\TestDox\\CliTestDoxPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php',
+ 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php',
+ 'PHPUnit\\Util\\TestDox\\NamePrettifier' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php',
+ 'PHPUnit\\Util\\TestDox\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php',
+ 'PHPUnit\\Util\\TestDox\\TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/TestResult.php',
+ 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php',
+ 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php',
+ 'PHPUnit\\Util\\TextTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TextTestListRenderer.php',
+ 'PHPUnit\\Util\\Type' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Type.php',
+ 'PHPUnit\\Util\\XdebugFilterScriptGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XdebugFilterScriptGenerator.php',
+ 'PHPUnit\\Util\\Xml' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Xml.php',
+ 'PHPUnit\\Util\\XmlTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php',
+ 'PHPUnit_Framework_MockObject_MockObject' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockObject.php',
+ 'PHP_Token' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_TokenWithScope' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_TokenWithScopeAndVisibility' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ABSTRACT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AMPERSAND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AND_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ARRAY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ARRAY_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BACKTICK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BAD_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOLEAN_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOLEAN_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOL_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BREAK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CALLABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CARET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CASE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CATCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS_NAME_CONSTANT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLONE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COALESCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMMA' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONCAT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONSTANT_ENCAPSED_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONTINUE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CURLY_OPEN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DEC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DEFAULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIV' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIV_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOC_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOLLAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_QUOTES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELLIPSIS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELSE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELSEIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EMPTY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENCAPSED_AND_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDDECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDFOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDFOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDSWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDWHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_END_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EVAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXCLAMATION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXTENDS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FINAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FINALLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FUNC_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GLOBAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GOTO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_HALT_COMPILER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IMPLEMENTS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INCLUDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INCLUDE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INLINE_HTML' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INSTANCEOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INSTEADOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INTERFACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ISSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_GREATER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_NOT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_NOT_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_SMALLER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_Includes' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LINE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LIST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_XOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_METHOD_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MINUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MINUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MOD_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MUL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NAMESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NEW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NS_SEPARATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NUM_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OBJECT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_TAG_WITH_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PERCENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PIPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PLUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PLUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_POW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_POW_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PRINT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PRIVATE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PROTECTED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PUBLIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_QUESTION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_REQUIRE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_REQUIRE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_RETURN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SEMICOLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SPACESHIP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_START_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STATIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING_VARNAME' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_Stream' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream.php',
+ 'PHP_Token_Stream_CachingFactory' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php',
+ 'PHP_Token_THROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TILDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRAIT_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_UNSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_UNSET_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_USE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_USE_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_VAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_VARIABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XOR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_YIELD' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_YIELD_FROM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PharIo\\Manifest\\Application' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Application.php',
+ 'PharIo\\Manifest\\ApplicationName' => __DIR__ . '/..' . '/phar-io/manifest/src/values/ApplicationName.php',
+ 'PharIo\\Manifest\\Author' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Author.php',
+ 'PharIo\\Manifest\\AuthorCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollection.php',
+ 'PharIo\\Manifest\\AuthorCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollectionIterator.php',
+ 'PharIo\\Manifest\\AuthorElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElement.php',
+ 'PharIo\\Manifest\\AuthorElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElementCollection.php',
+ 'PharIo\\Manifest\\BundledComponent' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponent.php',
+ 'PharIo\\Manifest\\BundledComponentCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollection.php',
+ 'PharIo\\Manifest\\BundledComponentCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php',
+ 'PharIo\\Manifest\\BundlesElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/BundlesElement.php',
+ 'PharIo\\Manifest\\ComponentElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElement.php',
+ 'PharIo\\Manifest\\ComponentElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElementCollection.php',
+ 'PharIo\\Manifest\\ContainsElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ContainsElement.php',
+ 'PharIo\\Manifest\\CopyrightElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/CopyrightElement.php',
+ 'PharIo\\Manifest\\CopyrightInformation' => __DIR__ . '/..' . '/phar-io/manifest/src/values/CopyrightInformation.php',
+ 'PharIo\\Manifest\\ElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ElementCollection.php',
+ 'PharIo\\Manifest\\Email' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Email.php',
+ 'PharIo\\Manifest\\Exception' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/Exception.php',
+ 'PharIo\\Manifest\\ExtElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElement.php',
+ 'PharIo\\Manifest\\ExtElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElementCollection.php',
+ 'PharIo\\Manifest\\Extension' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Extension.php',
+ 'PharIo\\Manifest\\ExtensionElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtensionElement.php',
+ 'PharIo\\Manifest\\InvalidApplicationNameException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php',
+ 'PharIo\\Manifest\\InvalidEmailException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidEmailException.php',
+ 'PharIo\\Manifest\\InvalidUrlException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidUrlException.php',
+ 'PharIo\\Manifest\\Library' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Library.php',
+ 'PharIo\\Manifest\\License' => __DIR__ . '/..' . '/phar-io/manifest/src/values/License.php',
+ 'PharIo\\Manifest\\LicenseElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/LicenseElement.php',
+ 'PharIo\\Manifest\\Manifest' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Manifest.php',
+ 'PharIo\\Manifest\\ManifestDocument' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocument.php',
+ 'PharIo\\Manifest\\ManifestDocumentException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php',
+ 'PharIo\\Manifest\\ManifestDocumentLoadingException' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php',
+ 'PharIo\\Manifest\\ManifestDocumentMapper' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestDocumentMapper.php',
+ 'PharIo\\Manifest\\ManifestDocumentMapperException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php',
+ 'PharIo\\Manifest\\ManifestElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestElement.php',
+ 'PharIo\\Manifest\\ManifestElementException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestElementException.php',
+ 'PharIo\\Manifest\\ManifestLoader' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestLoader.php',
+ 'PharIo\\Manifest\\ManifestLoaderException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php',
+ 'PharIo\\Manifest\\ManifestSerializer' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestSerializer.php',
+ 'PharIo\\Manifest\\PhpElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/PhpElement.php',
+ 'PharIo\\Manifest\\PhpExtensionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpExtensionRequirement.php',
+ 'PharIo\\Manifest\\PhpVersionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpVersionRequirement.php',
+ 'PharIo\\Manifest\\Requirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Requirement.php',
+ 'PharIo\\Manifest\\RequirementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollection.php',
+ 'PharIo\\Manifest\\RequirementCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollectionIterator.php',
+ 'PharIo\\Manifest\\RequiresElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/RequiresElement.php',
+ 'PharIo\\Manifest\\Type' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Type.php',
+ 'PharIo\\Manifest\\Url' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Url.php',
+ 'PharIo\\Version\\AbstractVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/AbstractVersionConstraint.php',
+ 'PharIo\\Version\\AndVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/constraints/AndVersionConstraintGroup.php',
+ 'PharIo\\Version\\AnyVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/AnyVersionConstraint.php',
+ 'PharIo\\Version\\ExactVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/ExactVersionConstraint.php',
+ 'PharIo\\Version\\Exception' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/Exception.php',
+ 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php',
+ 'PharIo\\Version\\InvalidPreReleaseSuffixException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php',
+ 'PharIo\\Version\\InvalidVersionException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/InvalidVersionException.php',
+ 'PharIo\\Version\\OrVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/constraints/OrVersionConstraintGroup.php',
+ 'PharIo\\Version\\PreReleaseSuffix' => __DIR__ . '/..' . '/phar-io/version/src/PreReleaseSuffix.php',
+ 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php',
+ 'PharIo\\Version\\SpecificMajorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php',
+ 'PharIo\\Version\\UnsupportedVersionConstraintException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php',
+ 'PharIo\\Version\\Version' => __DIR__ . '/..' . '/phar-io/version/src/Version.php',
+ 'PharIo\\Version\\VersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/VersionConstraint.php',
+ 'PharIo\\Version\\VersionConstraintParser' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintParser.php',
+ 'PharIo\\Version\\VersionConstraintValue' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintValue.php',
+ 'PharIo\\Version\\VersionNumber' => __DIR__ . '/..' . '/phar-io/version/src/VersionNumber.php',
+ 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage.php',
+ 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Driver.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Xdebug.php',
+ 'SebastianBergmann\\CodeCoverage\\Exception' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/Exception.php',
+ 'SebastianBergmann\\CodeCoverage\\Filter' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Filter.php',
+ 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php',
+ 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/AbstractNode.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Builder.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Iterator.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Clover.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Crap4j.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Facade.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/PHP.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Text' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Text.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Method.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Node.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Project.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Report.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Source.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php',
+ 'SebastianBergmann\\CodeCoverage\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php',
+ 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php',
+ 'SebastianBergmann\\CodeCoverage\\Util' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Util.php',
+ 'SebastianBergmann\\CodeCoverage\\Version' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Version.php',
+ 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => __DIR__ . '/..' . '/sebastian/code-unit-reverse-lookup/src/Wizard.php',
+ 'SebastianBergmann\\Comparator\\ArrayComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ArrayComparator.php',
+ 'SebastianBergmann\\Comparator\\Comparator' => __DIR__ . '/..' . '/sebastian/comparator/src/Comparator.php',
+ 'SebastianBergmann\\Comparator\\ComparisonFailure' => __DIR__ . '/..' . '/sebastian/comparator/src/ComparisonFailure.php',
+ 'SebastianBergmann\\Comparator\\DOMNodeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DOMNodeComparator.php',
+ 'SebastianBergmann\\Comparator\\DateTimeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DateTimeComparator.php',
+ 'SebastianBergmann\\Comparator\\DoubleComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DoubleComparator.php',
+ 'SebastianBergmann\\Comparator\\ExceptionComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ExceptionComparator.php',
+ 'SebastianBergmann\\Comparator\\Factory' => __DIR__ . '/..' . '/sebastian/comparator/src/Factory.php',
+ 'SebastianBergmann\\Comparator\\MockObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/MockObjectComparator.php',
+ 'SebastianBergmann\\Comparator\\NumericComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/NumericComparator.php',
+ 'SebastianBergmann\\Comparator\\ObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ObjectComparator.php',
+ 'SebastianBergmann\\Comparator\\ResourceComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ResourceComparator.php',
+ 'SebastianBergmann\\Comparator\\ScalarComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ScalarComparator.php',
+ 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/SplObjectStorageComparator.php',
+ 'SebastianBergmann\\Comparator\\TypeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/TypeComparator.php',
+ 'SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php',
+ 'SebastianBergmann\\Diff\\ConfigurationException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/ConfigurationException.php',
+ 'SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php',
+ 'SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php',
+ 'SebastianBergmann\\Diff\\Exception' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/Exception.php',
+ 'SebastianBergmann\\Diff\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/InvalidArgumentException.php',
+ 'SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php',
+ 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php',
+ 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php',
+ 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php',
+ 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php',
+ 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php',
+ 'SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php',
+ 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php',
+ 'SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php',
+ 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php',
+ 'SebastianBergmann\\Environment\\Console' => __DIR__ . '/..' . '/sebastian/environment/src/Console.php',
+ 'SebastianBergmann\\Environment\\OperatingSystem' => __DIR__ . '/..' . '/sebastian/environment/src/OperatingSystem.php',
+ 'SebastianBergmann\\Environment\\Runtime' => __DIR__ . '/..' . '/sebastian/environment/src/Runtime.php',
+ 'SebastianBergmann\\Exporter\\Exporter' => __DIR__ . '/..' . '/sebastian/exporter/src/Exporter.php',
+ 'SebastianBergmann\\FileIterator\\Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php',
+ 'SebastianBergmann\\FileIterator\\Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php',
+ 'SebastianBergmann\\FileIterator\\Iterator' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Iterator.php',
+ 'SebastianBergmann\\GlobalState\\Blacklist' => __DIR__ . '/..' . '/sebastian/global-state/src/Blacklist.php',
+ 'SebastianBergmann\\GlobalState\\CodeExporter' => __DIR__ . '/..' . '/sebastian/global-state/src/CodeExporter.php',
+ 'SebastianBergmann\\GlobalState\\Exception' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/Exception.php',
+ 'SebastianBergmann\\GlobalState\\Restorer' => __DIR__ . '/..' . '/sebastian/global-state/src/Restorer.php',
+ 'SebastianBergmann\\GlobalState\\RuntimeException' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/RuntimeException.php',
+ 'SebastianBergmann\\GlobalState\\Snapshot' => __DIR__ . '/..' . '/sebastian/global-state/src/Snapshot.php',
+ 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Enumerator.php',
+ 'SebastianBergmann\\ObjectEnumerator\\Exception' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Exception.php',
+ 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\ObjectReflector\\Exception' => __DIR__ . '/..' . '/sebastian/object-reflector/src/Exception.php',
+ 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-reflector/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => __DIR__ . '/..' . '/sebastian/object-reflector/src/ObjectReflector.php',
+ 'SebastianBergmann\\RecursionContext\\Context' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Context.php',
+ 'SebastianBergmann\\RecursionContext\\Exception' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Exception.php',
+ 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/recursion-context/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => __DIR__ . '/..' . '/sebastian/resource-operations/src/ResourceOperations.php',
+ 'SebastianBergmann\\Timer\\Exception' => __DIR__ . '/..' . '/phpunit/php-timer/src/Exception.php',
+ 'SebastianBergmann\\Timer\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-timer/src/RuntimeException.php',
+ 'SebastianBergmann\\Timer\\Timer' => __DIR__ . '/..' . '/phpunit/php-timer/src/Timer.php',
+ 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php',
+ 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php',
+ 'TheSeer\\Tokenizer\\Exception' => __DIR__ . '/..' . '/theseer/tokenizer/src/Exception.php',
+ 'TheSeer\\Tokenizer\\NamespaceUri' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUri.php',
+ 'TheSeer\\Tokenizer\\NamespaceUriException' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUriException.php',
+ 'TheSeer\\Tokenizer\\Token' => __DIR__ . '/..' . '/theseer/tokenizer/src/Token.php',
+ 'TheSeer\\Tokenizer\\TokenCollection' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollection.php',
+ 'TheSeer\\Tokenizer\\TokenCollectionException' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollectionException.php',
+ 'TheSeer\\Tokenizer\\Tokenizer' => __DIR__ . '/..' . '/theseer/tokenizer/src/Tokenizer.php',
+ 'TheSeer\\Tokenizer\\XMLSerializer' => __DIR__ . '/..' . '/theseer/tokenizer/src/XMLSerializer.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInit92ac2e15ce8f444fc54507a43b3e6bb1::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit92ac2e15ce8f444fc54507a43b3e6bb1::$prefixDirsPsr4;
+ $loader->prefixesPsr0 = ComposerStaticInit92ac2e15ce8f444fc54507a43b3e6bb1::$prefixesPsr0;
+ $loader->classMap = ComposerStaticInit92ac2e15ce8f444fc54507a43b3e6bb1::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
new file mode 100644
index 0000000..9f1554c
--- /dev/null
+++ b/vendor/composer/installed.json
@@ -0,0 +1,1703 @@
+[
+ {
+ "name": "composer/installers",
+ "version": "v1.6.0",
+ "version_normalized": "1.6.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/installers.git",
+ "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b",
+ "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0"
+ },
+ "replace": {
+ "roundcube/plugin-installer": "*",
+ "shama/baton": "*"
+ },
+ "require-dev": {
+ "composer/composer": "1.0.*@dev",
+ "phpunit/phpunit": "^4.8.36"
+ },
+ "time": "2018-08-27T06:10:37+00:00",
+ "type": "composer-plugin",
+ "extra": {
+ "class": "Composer\\Installers\\Plugin",
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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",
+ "Mautic",
+ "Maya",
+ "OXID",
+ "Plentymarkets",
+ "Porto",
+ "RadPHP",
+ "SMF",
+ "Thelia",
+ "WolfCMS",
+ "agl",
+ "aimeos",
+ "annotatecms",
+ "attogram",
+ "bitrix",
+ "cakephp",
+ "chef",
+ "cockpit",
+ "codeigniter",
+ "concrete5",
+ "croogo",
+ "dokuwiki",
+ "drupal",
+ "eZ Platform",
+ "elgg",
+ "expressionengine",
+ "fuelphp",
+ "grav",
+ "installer",
+ "itop",
+ "joomla",
+ "kohana",
+ "laravel",
+ "lavalite",
+ "lithium",
+ "magento",
+ "majima",
+ "mako",
+ "mediawiki",
+ "modulework",
+ "modx",
+ "moodle",
+ "osclass",
+ "phpbb",
+ "piwik",
+ "ppi",
+ "puppet",
+ "pxcms",
+ "reindex",
+ "roundcube",
+ "shopware",
+ "silverstripe",
+ "sydes",
+ "symfony",
+ "typo3",
+ "wordpress",
+ "yawik",
+ "zend",
+ "zikula"
+ ]
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.1.0",
+ "version_normalized": "1.1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2"
+ },
+ "time": "2017-07-22T11:58:36+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ]
+ },
+ {
+ "name": "hamcrest/hamcrest-php",
+ "version": "v2.0.0",
+ "version_normalized": "2.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/hamcrest/hamcrest-php.git",
+ "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad",
+ "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3|^7.0"
+ },
+ "replace": {
+ "cordoval/hamcrest-php": "*",
+ "davedevelopment/hamcrest-php": "*",
+ "kodova/hamcrest-php": "*"
+ },
+ "require-dev": {
+ "phpunit/php-file-iterator": "1.3.3",
+ "phpunit/phpunit": "~4.0",
+ "satooshi/php-coveralls": "^1.0"
+ },
+ "time": "2016-01-20T08:20:44+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "hamcrest"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD"
+ ],
+ "description": "This is the PHP port of Hamcrest Matchers",
+ "keywords": [
+ "test"
+ ]
+ },
+ {
+ "name": "mockery/mockery",
+ "version": "1.2.0",
+ "version_normalized": "1.2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/mockery/mockery.git",
+ "reference": "100633629bf76d57430b86b7098cd6beb996a35a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/mockery/mockery/zipball/100633629bf76d57430b86b7098cd6beb996a35a",
+ "reference": "100633629bf76d57430b86b7098cd6beb996a35a",
+ "shasum": ""
+ },
+ "require": {
+ "hamcrest/hamcrest-php": "~2.0",
+ "lib-pcre": ">=7.0",
+ "php": ">=5.6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5.7.10|~6.5|~7.0"
+ },
+ "time": "2018-10-02T21:52:37+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Mockery": "library/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Pádraic Brady",
+ "email": "padraic.brady@gmail.com",
+ "homepage": "http://blog.astrumfutura.com"
+ },
+ {
+ "name": "Dave Marshall",
+ "email": "dave.marshall@atstsolutions.co.uk",
+ "homepage": "http://davedevelopment.co.uk"
+ }
+ ],
+ "description": "Mockery is a simple yet flexible PHP mock object framework",
+ "homepage": "https://github.com/mockery/mockery",
+ "keywords": [
+ "BDD",
+ "TDD",
+ "library",
+ "mock",
+ "mock objects",
+ "mockery",
+ "stub",
+ "test",
+ "test double",
+ "testing"
+ ]
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.8.1",
+ "version_normalized": "1.8.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "replace": {
+ "myclabs/deep-copy": "self.version"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.0",
+ "doctrine/common": "^2.6",
+ "phpunit/phpunit": "^7.1"
+ },
+ "time": "2018-06-11T23:09:50+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "phar-io/manifest",
+ "version": "1.0.3",
+ "version_normalized": "1.0.3.0",
+ "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"
+ },
+ "time": "2018-07-08T19:23:20+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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)"
+ },
+ {
+ "name": "phar-io/version",
+ "version": "2.0.1",
+ "version_normalized": "2.0.1.0",
+ "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"
+ },
+ "time": "2018-07-08T19:19:57+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "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"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "1.0.1",
+ "version_normalized": "1.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "time": "2017-09-11T18:02:19+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "4.3.0",
+ "version_normalized": "4.3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0",
+ "phpdocumentor/type-resolver": "^0.4.0",
+ "webmozart/assert": "^1.0"
+ },
+ "require-dev": {
+ "doctrine/instantiator": "~1.0.5",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.4"
+ },
+ "time": "2017-11-30T07:14:17+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock."
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "0.4.0",
+ "version_normalized": "0.4.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^5.2||^4.8.24"
+ },
+ "time": "2017-07-14T14:27:02+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ]
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "1.8.0",
+ "version_normalized": "1.8.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "sebastian/comparator": "^1.1|^2.0|^3.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^2.5|^3.2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+ },
+ "time": "2018-08-05T17:53:17+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.8.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "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"
+ ]
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "6.1.3",
+ "version_normalized": "6.1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4d3ae9b21a7d7e440bd0cf65565533117976859f",
+ "reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f",
+ "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"
+ },
+ "time": "2018-10-23T05:59:32+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.1-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "2.0.2",
+ "version_normalized": "2.0.2.0",
+ "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"
+ },
+ "time": "2018-09-13T20:33:42+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.1",
+ "version_normalized": "1.2.1.0",
+ "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"
+ },
+ "time": "2015-06-21T13:50:34+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "2.0.0",
+ "version_normalized": "2.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f",
+ "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "time": "2018-02-01T13:07:23+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "3.0.0",
+ "version_normalized": "3.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace",
+ "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "time": "2018-02-01T13:16:43+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "7.4.3",
+ "version_normalized": "7.4.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "c151651fb6ed264038d486ea262e243af72e5e64"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c151651fb6ed264038d486ea262e243af72e5e64",
+ "reference": "c151651fb6ed264038d486ea262e243af72e5e64",
+ "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.0",
+ "sebastian/comparator": "^3.0",
+ "sebastian/diff": "^3.0",
+ "sebastian/environment": "^3.1 || ^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"
+ },
+ "time": "2018-10-23T05:57:41+00:00",
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.4-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.1",
+ "version_normalized": "1.0.1.0",
+ "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"
+ },
+ "time": "2017-03-04T06:30:41+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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/"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "3.0.2",
+ "version_normalized": "3.0.2.0",
+ "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"
+ },
+ "time": "2018-07-12T15:12:46+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "3.0.1",
+ "version_normalized": "3.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "366541b989927187c4ca70490a35615d3fef2dce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce",
+ "reference": "366541b989927187c4ca70490a35615d3fef2dce",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0",
+ "symfony/process": "^2 || ^3.3 || ^4"
+ },
+ "time": "2018-06-10T07:54:39+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "3.1.0",
+ "version_normalized": "3.1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
+ "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.1"
+ },
+ "time": "2017-07-01T08:51:00+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "3.1.0",
+ "version_normalized": "3.1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "234199f4528de6d12aaa58b612e98f7d36adb937"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937",
+ "reference": "234199f4528de6d12aaa58b612e98f7d36adb937",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "sebastian/recursion-context": "^3.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^6.0"
+ },
+ "time": "2017-04-03T13:19:02+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ]
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "2.0.0",
+ "version_normalized": "2.0.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": "*"
+ },
+ "time": "2017-04-27T15:39:26+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "3.0.3",
+ "version_normalized": "3.0.3.0",
+ "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"
+ },
+ "time": "2017-08-03T12:35:26+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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/"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "1.1.1",
+ "version_normalized": "1.1.1.0",
+ "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"
+ },
+ "time": "2017-03-29T09:07:27+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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/"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "3.0.0",
+ "version_normalized": "3.0.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"
+ },
+ "time": "2017-03-03T06:23:57+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "2.0.1",
+ "version_normalized": "2.0.1.0",
+ "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"
+ },
+ "time": "2018-10-04T04:07:39+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "2.0.1",
+ "version_normalized": "2.0.1.0",
+ "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"
+ },
+ "time": "2016-10-03T07:35:21+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.1.0",
+ "version_normalized": "1.1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b",
+ "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.0"
+ },
+ "time": "2017-04-07T12:08:54+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "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"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.3.0",
+ "version_normalized": "1.3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "time": "2018-01-29T19:49:41+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "installation-source": "dist",
+ "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"
+ ]
+ }
+]
diff --git a/vendor/composer/installers/LICENSE b/vendor/composer/installers/LICENSE
new file mode 100644
index 0000000..85f97fc
--- /dev/null
+++ b/vendor/composer/installers/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Kyle Robinson Young
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/vendor/composer/installers/composer.json b/vendor/composer/installers/composer.json
new file mode 100644
index 0000000..6de4085
--- /dev/null
+++ b/vendor/composer/installers/composer.json
@@ -0,0 +1,105 @@
+{
+ "name": "composer/installers",
+ "type": "composer-plugin",
+ "license": "MIT",
+ "description": "A multi-framework Composer library installer",
+ "keywords": [
+ "installer",
+ "Aimeos",
+ "AGL",
+ "AnnotateCms",
+ "Attogram",
+ "Bitrix",
+ "CakePHP",
+ "Chef",
+ "Cockpit",
+ "CodeIgniter",
+ "concrete5",
+ "Craft",
+ "Croogo",
+ "DokuWiki",
+ "Dolibarr",
+ "Drupal",
+ "Elgg",
+ "Eliasis",
+ "ExpressionEngine",
+ "eZ Platform",
+ "FuelPHP",
+ "Grav",
+ "Hurad",
+ "ImageCMS",
+ "iTop",
+ "Joomla",
+ "Kanboard",
+ "Kohana",
+ "Lan Management System",
+ "Laravel",
+ "Lavalite",
+ "Lithium",
+ "Magento",
+ "majima",
+ "Mako",
+ "Mautic",
+ "Maya",
+ "MODX",
+ "MODX Evo",
+ "MediaWiki",
+ "OXID",
+ "osclass",
+ "MODULEWork",
+ "Moodle",
+ "Piwik",
+ "pxcms",
+ "phpBB",
+ "Plentymarkets",
+ "PPI",
+ "Puppet",
+ "Porto",
+ "RadPHP",
+ "ReIndex",
+ "Roundcube",
+ "shopware",
+ "SilverStripe",
+ "SMF",
+ "SyDES",
+ "symfony",
+ "Thelia",
+ "TYPO3",
+ "WolfCMS",
+ "WordPress",
+ "YAWIK",
+ "Zend",
+ "Zikula"
+ ],
+ "homepage": "https://composer.github.io/installers/",
+ "authors": [
+ {
+ "name": "Kyle Robinson Young",
+ "email": "kyle@dontkry.com",
+ "homepage": "https://github.com/shama"
+ }
+ ],
+ "autoload": {
+ "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" }
+ },
+ "extra": {
+ "class": "Composer\\Installers\\Plugin",
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "replace": {
+ "shama/baton": "*",
+ "roundcube/plugin-installer": "*"
+ },
+ "require": {
+ "composer-plugin-api": "^1.0"
+ },
+ "require-dev": {
+ "composer/composer": "1.0.*@dev",
+ "phpunit/phpunit": "^4.8.36"
+ },
+ "scripts": {
+ "test": "phpunit"
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AglInstaller.php b/vendor/composer/installers/src/Composer/Installers/AglInstaller.php
new file mode 100644
index 0000000..01b8a41
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AglInstaller.php
@@ -0,0 +1,21 @@
+ 'More/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
+ return strtoupper($matches[1]);
+ }, $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php b/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php
new file mode 100644
index 0000000..79a0e95
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php
@@ -0,0 +1,9 @@
+ 'ext/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php
new file mode 100644
index 0000000..89d7ad9
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php
@@ -0,0 +1,11 @@
+ 'addons/modules/{$name}/',
+ 'component' => 'addons/components/{$name}/',
+ 'service' => 'addons/services/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php b/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php
new file mode 100644
index 0000000..22dad1b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php
@@ -0,0 +1,49 @@
+ 'Modules/{$name}/',
+ 'theme' => 'Themes/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type asgard-module, cut off a trailing '-plugin' if present.
+ *
+ * For package type asgard-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'asgard-module') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'asgard-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php b/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php
new file mode 100644
index 0000000..d62fd8f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php
new file mode 100644
index 0000000..7082bf2
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php
@@ -0,0 +1,136 @@
+composer = $composer;
+ $this->package = $package;
+ $this->io = $io;
+ }
+
+ /**
+ * Return the install path based on package type.
+ *
+ * @param PackageInterface $package
+ * @param string $frameworkType
+ * @return string
+ */
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+ $type = $this->package->getType();
+
+ $prettyName = $this->package->getPrettyName();
+ if (strpos($prettyName, '/') !== false) {
+ list($vendor, $name) = explode('/', $prettyName);
+ } else {
+ $vendor = '';
+ $name = $prettyName;
+ }
+
+ $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
+
+ $extra = $package->getExtra();
+ if (!empty($extra['installer-name'])) {
+ $availableVars['name'] = $extra['installer-name'];
+ }
+
+ if ($this->composer->getPackage()) {
+ $extra = $this->composer->getPackage()->getExtra();
+ if (!empty($extra['installer-paths'])) {
+ $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
+ if ($customPath !== false) {
+ return $this->templatePath($customPath, $availableVars);
+ }
+ }
+ }
+
+ $packageType = substr($type, strlen($frameworkType) + 1);
+ $locations = $this->getLocations();
+ if (!isset($locations[$packageType])) {
+ throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
+ }
+
+ return $this->templatePath($locations[$packageType], $availableVars);
+ }
+
+ /**
+ * For an installer to override to modify the vars per installer.
+ *
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ return $vars;
+ }
+
+ /**
+ * Gets the installer's locations
+ *
+ * @return array
+ */
+ public function getLocations()
+ {
+ return $this->locations;
+ }
+
+ /**
+ * Replace vars in a path
+ *
+ * @param string $path
+ * @param array $vars
+ * @return string
+ */
+ protected function templatePath($path, array $vars = array())
+ {
+ if (strpos($path, '{') !== false) {
+ extract($vars);
+ preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
+ if (!empty($matches[1])) {
+ foreach ($matches[1] as $var) {
+ $path = str_replace('{$' . $var . '}', $$var, $path);
+ }
+ }
+ }
+
+ return $path;
+ }
+
+ /**
+ * Search through a passed paths array for a custom install path.
+ *
+ * @param array $paths
+ * @param string $name
+ * @param string $type
+ * @param string $vendor = NULL
+ * @return string
+ */
+ protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL)
+ {
+ foreach ($paths as $path => $names) {
+ if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
+ return $path;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php b/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php
new file mode 100644
index 0000000..e80cd1e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php
@@ -0,0 +1,126 @@
+.`.
+ * - `bitrix-d7-component` — copy the component to directory `bitrix/components//`.
+ * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/_`.
+ *
+ * You can set custom path to directory with Bitrix kernel in `composer.json`:
+ *
+ * ```json
+ * {
+ * "extra": {
+ * "bitrix-dir": "s1/bitrix"
+ * }
+ * }
+ * ```
+ *
+ * @author Nik Samokhvalov
+ * @author Denis Kulichkin
+ */
+class BitrixInstaller extends BaseInstaller
+{
+ protected $locations = array(
+ 'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
+ 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
+ 'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
+ 'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/',
+ 'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/',
+ 'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/',
+ );
+
+ /**
+ * @var array Storage for informations about duplicates at all the time of installation packages.
+ */
+ private static $checkedDuplicates = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($this->composer->getPackage()) {
+ $extra = $this->composer->getPackage()->getExtra();
+
+ if (isset($extra['bitrix-dir'])) {
+ $vars['bitrix_dir'] = $extra['bitrix-dir'];
+ }
+ }
+
+ if (!isset($vars['bitrix_dir'])) {
+ $vars['bitrix_dir'] = 'bitrix';
+ }
+
+ return parent::inflectPackageVars($vars);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function templatePath($path, array $vars = array())
+ {
+ $templatePath = parent::templatePath($path, $vars);
+ $this->checkDuplicates($templatePath, $vars);
+
+ return $templatePath;
+ }
+
+ /**
+ * Duplicates search packages.
+ *
+ * @param string $path
+ * @param array $vars
+ */
+ protected function checkDuplicates($path, array $vars = array())
+ {
+ $packageType = substr($vars['type'], strlen('bitrix') + 1);
+ $localDir = explode('/', $vars['bitrix_dir']);
+ array_pop($localDir);
+ $localDir[] = 'local';
+ $localDir = implode('/', $localDir);
+
+ $oldPath = str_replace(
+ array('{$bitrix_dir}', '{$name}'),
+ array($localDir, $vars['name']),
+ $this->locations[$packageType]
+ );
+
+ if (in_array($oldPath, static::$checkedDuplicates)) {
+ return;
+ }
+
+ if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) {
+
+ $this->io->writeError(' Duplication of packages: ');
+ $this->io->writeError(' Package ' . $oldPath . ' will be called instead package ' . $path . ' ');
+
+ while (true) {
+ switch ($this->io->ask(' Delete ' . $oldPath . ' [y,n,?]? ', '?')) {
+ case 'y':
+ $fs = new Filesystem();
+ $fs->removeDirectory($oldPath);
+ break 2;
+
+ case 'n':
+ break 2;
+
+ case '?':
+ default:
+ $this->io->writeError(array(
+ ' y - delete package ' . $oldPath . ' and to continue with the installation',
+ ' n - don\'t delete and to continue with the installation',
+ ));
+ $this->io->writeError(' ? - print help');
+ break;
+ }
+ }
+ }
+
+ static::$checkedDuplicates[] = $oldPath;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php b/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php
new file mode 100644
index 0000000..da3aad2
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php
@@ -0,0 +1,9 @@
+ 'Packages/{$vendor}/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php
new file mode 100644
index 0000000..6352beb
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php
@@ -0,0 +1,82 @@
+ 'Plugin/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
+ return $vars;
+ }
+
+ $nameParts = explode('/', $vars['name']);
+ foreach ($nameParts as &$value) {
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
+ $value = str_replace(array('-', '_'), ' ', $value);
+ $value = str_replace(' ', '', ucwords($value));
+ }
+ $vars['name'] = implode('/', $nameParts);
+
+ return $vars;
+ }
+
+ /**
+ * Change the default plugin location when cakephp >= 3.0
+ */
+ public function getLocations()
+ {
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
+ $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
+ }
+ return $this->locations;
+ }
+
+ /**
+ * Check if CakePHP version matches against a version
+ *
+ * @param string $matcher
+ * @param string $version
+ * @return bool
+ */
+ protected function matchesCakeVersion($matcher, $version)
+ {
+ if (class_exists('Composer\Semver\Constraint\MultiConstraint')) {
+ $multiClass = 'Composer\Semver\Constraint\MultiConstraint';
+ $constraintClass = 'Composer\Semver\Constraint\Constraint';
+ } else {
+ $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint';
+ $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint';
+ }
+
+ $repositoryManager = $this->composer->getRepositoryManager();
+ if ($repositoryManager) {
+ $repos = $repositoryManager->getLocalRepository();
+ if (!$repos) {
+ return false;
+ }
+ $cake3 = new $multiClass(array(
+ new $constraintClass($matcher, $version),
+ new $constraintClass('!=', '9999999-dev'),
+ ));
+ $pool = new Pool('dev');
+ $pool->addRepository($repos);
+ $packages = $pool->whatProvides('cakephp/cakephp');
+ foreach ($packages as $package) {
+ $installed = new $constraintClass('=', $package->getVersion());
+ if ($cake3->matches($installed)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php b/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php
new file mode 100644
index 0000000..ab2f9aa
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php
@@ -0,0 +1,11 @@
+ 'Chef/{$vendor}/{$name}/',
+ 'role' => 'Chef/roles/{$name}/',
+ );
+}
+
diff --git a/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php b/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php
new file mode 100644
index 0000000..6673aea
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php
@@ -0,0 +1,9 @@
+ 'ext/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php b/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php
new file mode 100644
index 0000000..c887815
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php
@@ -0,0 +1,10 @@
+ 'CCF/orbit/{$name}/',
+ 'theme' => 'CCF/app/themes/{$name}/',
+ );
+}
\ No newline at end of file
diff --git a/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php
new file mode 100644
index 0000000..c7816df
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php
@@ -0,0 +1,34 @@
+ 'cockpit/modules/addons/{$name}/',
+ );
+
+ /**
+ * Format module name.
+ *
+ * Strip `module-` prefix from package name.
+ *
+ * @param array @vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] == 'cockpit-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ return $vars;
+ }
+
+ public function inflectModuleVars($vars)
+ {
+ $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php b/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php
new file mode 100644
index 0000000..3b4a4ec
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php
@@ -0,0 +1,11 @@
+ 'application/libraries/{$name}/',
+ 'third-party' => 'application/third_party/{$name}/',
+ 'module' => 'application/modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php
new file mode 100644
index 0000000..5c01baf
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php
@@ -0,0 +1,13 @@
+ 'concrete/',
+ 'block' => 'application/blocks/{$name}/',
+ 'package' => 'packages/{$name}/',
+ 'theme' => 'application/themes/{$name}/',
+ 'update' => 'updates/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php b/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php
new file mode 100644
index 0000000..d37a77a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php
@@ -0,0 +1,35 @@
+ 'craft/plugins/{$name}/',
+ );
+
+ /**
+ * Strip `craft-` prefix and/or `-plugin` suffix from package names
+ *
+ * @param array $vars
+ *
+ * @return array
+ */
+ final public function inflectPackageVars($vars)
+ {
+ return $this->inflectPluginVars($vars);
+ }
+
+ private function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']);
+ $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php b/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php
new file mode 100644
index 0000000..d94219d
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php
@@ -0,0 +1,21 @@
+ 'Plugin/{$name}/',
+ 'theme' => 'View/Themed/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php b/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php
new file mode 100644
index 0000000..f4837a6
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php
@@ -0,0 +1,10 @@
+ 'app/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php
new file mode 100644
index 0000000..cfd638d
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php
@@ -0,0 +1,50 @@
+ 'lib/plugins/{$name}/',
+ 'template' => 'lib/tpl/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type dokuwiki-plugin, cut off a trailing '-plugin',
+ * or leading dokuwiki_ if present.
+ *
+ * For package type dokuwiki-template, cut off a trailing '-template' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+
+ if ($vars['type'] === 'dokuwiki-plugin') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'dokuwiki-template') {
+ return $this->inflectTemplateVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectTemplateVars($vars)
+ {
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
+
+ return $vars;
+ }
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php b/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php
new file mode 100644
index 0000000..21f7e8e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php
@@ -0,0 +1,16 @@
+
+ */
+class DolibarrInstaller extends BaseInstaller
+{
+ //TODO: Add support for scripts and themes
+ protected $locations = array(
+ 'module' => 'htdocs/custom/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php b/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php
new file mode 100644
index 0000000..fef7c52
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php
@@ -0,0 +1,16 @@
+ 'core/',
+ 'module' => 'modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ 'library' => 'libraries/{$name}/',
+ 'profile' => 'profiles/{$name}/',
+ 'drush' => 'drush/{$name}/',
+ 'custom-theme' => 'themes/custom/{$name}/',
+ 'custom-module' => 'modules/custom/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php b/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php
new file mode 100644
index 0000000..c0bb609
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php
@@ -0,0 +1,9 @@
+ 'mod/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php b/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php
new file mode 100644
index 0000000..6f3dc97
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php
@@ -0,0 +1,12 @@
+ 'components/{$name}/',
+ 'module' => 'modules/{$name}/',
+ 'plugin' => 'plugins/{$name}/',
+ 'template' => 'templates/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php b/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php
new file mode 100644
index 0000000..d5321a8
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php
@@ -0,0 +1,29 @@
+ 'system/expressionengine/third_party/{$name}/',
+ 'theme' => 'themes/third_party/{$name}/',
+ );
+
+ private $ee3Locations = array(
+ 'addon' => 'system/user/addons/{$name}/',
+ 'theme' => 'themes/user/{$name}/',
+ );
+
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+
+ $version = "{$frameworkType}Locations";
+ $this->locations = $this->$version;
+
+ return parent::getInstallPath($package, $frameworkType);
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php b/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php
new file mode 100644
index 0000000..f30ebcc
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php
@@ -0,0 +1,10 @@
+ 'web/assets/ezplatform/',
+ 'assets' => 'web/assets/ezplatform/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php b/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php
new file mode 100644
index 0000000..6eba2e3
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php
@@ -0,0 +1,11 @@
+ 'fuel/app/modules/{$name}/',
+ 'package' => 'fuel/packages/{$name}/',
+ 'theme' => 'fuel/app/themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php b/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php
new file mode 100644
index 0000000..29d980b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php
@@ -0,0 +1,9 @@
+ 'components/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/GravInstaller.php b/vendor/composer/installers/src/Composer/Installers/GravInstaller.php
new file mode 100644
index 0000000..dbe63e0
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/GravInstaller.php
@@ -0,0 +1,30 @@
+ 'user/plugins/{$name}/',
+ 'theme' => 'user/themes/{$name}/',
+ );
+
+ /**
+ * Format package name
+ *
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $restrictedWords = implode('|', array_keys($this->locations));
+
+ $vars['name'] = strtolower($vars['name']);
+ $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
+ '$1',
+ $vars['name']
+ );
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php b/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php
new file mode 100644
index 0000000..8fe017f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php
@@ -0,0 +1,25 @@
+ 'plugins/{$name}/',
+ 'theme' => 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $nameParts = explode('/', $vars['name']);
+ foreach ($nameParts as &$value) {
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
+ $value = str_replace(array('-', '_'), ' ', $value);
+ $value = str_replace(' ', '', ucwords($value));
+ }
+ $vars['name'] = implode('/', $nameParts);
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php
new file mode 100644
index 0000000..5e2142e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php
@@ -0,0 +1,11 @@
+ 'templates/{$name}/',
+ 'module' => 'application/modules/{$name}/',
+ 'library' => 'application/libraries/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/Installer.php b/vendor/composer/installers/src/Composer/Installers/Installer.php
new file mode 100644
index 0000000..352cb7f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/Installer.php
@@ -0,0 +1,274 @@
+ 'AimeosInstaller',
+ 'asgard' => 'AsgardInstaller',
+ 'attogram' => 'AttogramInstaller',
+ 'agl' => 'AglInstaller',
+ 'annotatecms' => 'AnnotateCmsInstaller',
+ 'bitrix' => 'BitrixInstaller',
+ 'bonefish' => 'BonefishInstaller',
+ 'cakephp' => 'CakePHPInstaller',
+ 'chef' => 'ChefInstaller',
+ 'civicrm' => 'CiviCrmInstaller',
+ 'ccframework' => 'ClanCatsFrameworkInstaller',
+ 'cockpit' => 'CockpitInstaller',
+ 'codeigniter' => 'CodeIgniterInstaller',
+ 'concrete5' => 'Concrete5Installer',
+ 'craft' => 'CraftInstaller',
+ 'croogo' => 'CroogoInstaller',
+ 'dokuwiki' => 'DokuWikiInstaller',
+ 'dolibarr' => 'DolibarrInstaller',
+ 'decibel' => 'DecibelInstaller',
+ 'drupal' => 'DrupalInstaller',
+ 'elgg' => 'ElggInstaller',
+ 'eliasis' => 'EliasisInstaller',
+ 'ee3' => 'ExpressionEngineInstaller',
+ 'ee2' => 'ExpressionEngineInstaller',
+ 'ezplatform' => 'EzPlatformInstaller',
+ 'fuel' => 'FuelInstaller',
+ 'fuelphp' => 'FuelphpInstaller',
+ 'grav' => 'GravInstaller',
+ 'hurad' => 'HuradInstaller',
+ 'imagecms' => 'ImageCMSInstaller',
+ 'itop' => 'ItopInstaller',
+ 'joomla' => 'JoomlaInstaller',
+ 'kanboard' => 'KanboardInstaller',
+ 'kirby' => 'KirbyInstaller',
+ 'kodicms' => 'KodiCMSInstaller',
+ 'kohana' => 'KohanaInstaller',
+ 'lms' => 'LanManagementSystemInstaller',
+ 'laravel' => 'LaravelInstaller',
+ 'lavalite' => 'LavaLiteInstaller',
+ 'lithium' => 'LithiumInstaller',
+ 'magento' => 'MagentoInstaller',
+ 'majima' => 'MajimaInstaller',
+ 'mako' => 'MakoInstaller',
+ 'maya' => 'MayaInstaller',
+ 'mautic' => 'MauticInstaller',
+ 'mediawiki' => 'MediaWikiInstaller',
+ 'microweber' => 'MicroweberInstaller',
+ 'modulework' => 'MODULEWorkInstaller',
+ 'modx' => 'ModxInstaller',
+ 'modxevo' => 'MODXEvoInstaller',
+ 'moodle' => 'MoodleInstaller',
+ 'october' => 'OctoberInstaller',
+ 'ontowiki' => 'OntoWikiInstaller',
+ 'oxid' => 'OxidInstaller',
+ 'osclass' => 'OsclassInstaller',
+ 'pxcms' => 'PxcmsInstaller',
+ 'phpbb' => 'PhpBBInstaller',
+ 'pimcore' => 'PimcoreInstaller',
+ 'piwik' => 'PiwikInstaller',
+ 'plentymarkets'=> 'PlentymarketsInstaller',
+ 'ppi' => 'PPIInstaller',
+ 'puppet' => 'PuppetInstaller',
+ 'radphp' => 'RadPHPInstaller',
+ 'phifty' => 'PhiftyInstaller',
+ 'porto' => 'PortoInstaller',
+ 'redaxo' => 'RedaxoInstaller',
+ 'reindex' => 'ReIndexInstaller',
+ 'roundcube' => 'RoundcubeInstaller',
+ 'shopware' => 'ShopwareInstaller',
+ 'sitedirect' => 'SiteDirectInstaller',
+ 'silverstripe' => 'SilverStripeInstaller',
+ 'smf' => 'SMFInstaller',
+ 'sydes' => 'SyDESInstaller',
+ 'symfony1' => 'Symfony1Installer',
+ 'thelia' => 'TheliaInstaller',
+ 'tusk' => 'TuskInstaller',
+ 'typo3-cms' => 'TYPO3CmsInstaller',
+ 'typo3-flow' => 'TYPO3FlowInstaller',
+ 'userfrosting' => 'UserFrostingInstaller',
+ 'vanilla' => 'VanillaInstaller',
+ 'whmcs' => 'WHMCSInstaller',
+ 'wolfcms' => 'WolfCMSInstaller',
+ 'wordpress' => 'WordPressInstaller',
+ 'yawik' => 'YawikInstaller',
+ 'zend' => 'ZendInstaller',
+ 'zikula' => 'ZikulaInstaller',
+ 'prestashop' => 'PrestashopInstaller'
+ );
+
+ /**
+ * Installer constructor.
+ *
+ * Disables installers specified in main composer extra installer-disable
+ * list
+ *
+ * @param IOInterface $io
+ * @param Composer $composer
+ * @param string $type
+ * @param Filesystem|null $filesystem
+ * @param BinaryInstaller|null $binaryInstaller
+ */
+ public function __construct(
+ IOInterface $io,
+ Composer $composer,
+ $type = 'library',
+ Filesystem $filesystem = null,
+ BinaryInstaller $binaryInstaller = null
+ ) {
+ parent::__construct($io, $composer, $type, $filesystem,
+ $binaryInstaller);
+ $this->removeDisabledInstallers();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getInstallPath(PackageInterface $package)
+ {
+ $type = $package->getType();
+ $frameworkType = $this->findFrameworkType($type);
+
+ if ($frameworkType === false) {
+ throw new \InvalidArgumentException(
+ 'Sorry the package type of this package is not yet supported.'
+ );
+ }
+
+ $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
+ $installer = new $class($package, $this->composer, $this->getIO());
+
+ return $installer->getInstallPath($package, $frameworkType);
+ }
+
+ public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
+ {
+ parent::uninstall($repo, $package);
+ $installPath = $this->getPackageBasePath($package);
+ $this->io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? 'deleted ' : 'not deleted '));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supports($packageType)
+ {
+ $frameworkType = $this->findFrameworkType($packageType);
+
+ if ($frameworkType === false) {
+ return false;
+ }
+
+ $locationPattern = $this->getLocationPattern($frameworkType);
+
+ return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
+ }
+
+ /**
+ * Finds a supported framework type if it exists and returns it
+ *
+ * @param string $type
+ * @return string
+ */
+ protected function findFrameworkType($type)
+ {
+ $frameworkType = false;
+
+ krsort($this->supportedTypes);
+
+ foreach ($this->supportedTypes as $key => $val) {
+ if ($key === substr($type, 0, strlen($key))) {
+ $frameworkType = substr($type, 0, strlen($key));
+ break;
+ }
+ }
+
+ return $frameworkType;
+ }
+
+ /**
+ * Get the second part of the regular expression to check for support of a
+ * package type
+ *
+ * @param string $frameworkType
+ * @return string
+ */
+ protected function getLocationPattern($frameworkType)
+ {
+ $pattern = false;
+ if (!empty($this->supportedTypes[$frameworkType])) {
+ $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
+ /** @var BaseInstaller $framework */
+ $framework = new $frameworkClass(null, $this->composer, $this->getIO());
+ $locations = array_keys($framework->getLocations());
+ $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
+ }
+
+ return $pattern ? : '(\w+)';
+ }
+
+ /**
+ * Get I/O object
+ *
+ * @return IOInterface
+ */
+ private function getIO()
+ {
+ return $this->io;
+ }
+
+ /**
+ * Look for installers set to be disabled in composer's extra config and
+ * remove them from the list of supported installers.
+ *
+ * Globals:
+ * - true, "all", and "*" - disable all installers.
+ * - false - enable all installers (useful with
+ * wikimedia/composer-merge-plugin or similar)
+ *
+ * @return void
+ */
+ protected function removeDisabledInstallers()
+ {
+ $extra = $this->composer->getPackage()->getExtra();
+
+ if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) {
+ // No installers are disabled
+ return;
+ }
+
+ // Get installers to disable
+ $disable = $extra['installer-disable'];
+
+ // Ensure $disabled is an array
+ if (!is_array($disable)) {
+ $disable = array($disable);
+ }
+
+ // Check which installers should be disabled
+ $all = array(true, "all", "*");
+ $intersect = array_intersect($all, $disable);
+ if (!empty($intersect)) {
+ // Disable all installers
+ $this->supportedTypes = array();
+ } else {
+ // Disable specified installers
+ foreach ($disable as $key => $installer) {
+ if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
+ unset($this->supportedTypes[$installer]);
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php b/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php
new file mode 100644
index 0000000..c6c1b33
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php
@@ -0,0 +1,9 @@
+ 'extensions/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php b/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php
new file mode 100644
index 0000000..9ee7759
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php
@@ -0,0 +1,15 @@
+ 'components/{$name}/',
+ 'module' => 'modules/{$name}/',
+ 'template' => 'templates/{$name}/',
+ 'plugin' => 'plugins/{$name}/',
+ 'library' => 'libraries/{$name}/',
+ );
+
+ // TODO: Add inflector for mod_ and com_ names
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php b/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php
new file mode 100644
index 0000000..9cb7b8c
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php
@@ -0,0 +1,18 @@
+ 'plugins/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php b/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php
new file mode 100644
index 0000000..36b2f84
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php
@@ -0,0 +1,11 @@
+ 'site/plugins/{$name}/',
+ 'field' => 'site/fields/{$name}/',
+ 'tag' => 'site/tags/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php
new file mode 100644
index 0000000..7143e23
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php
@@ -0,0 +1,10 @@
+ 'cms/plugins/{$name}/',
+ 'media' => 'cms/media/vendor/{$name}/'
+ );
+}
\ No newline at end of file
diff --git a/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php b/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php
new file mode 100644
index 0000000..dcd6d26
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php b/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php
new file mode 100644
index 0000000..903143a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php
@@ -0,0 +1,27 @@
+ 'plugins/{$name}/',
+ 'template' => 'templates/{$name}/',
+ 'document-template' => 'documents/templates/{$name}/',
+ 'userpanel-module' => 'userpanel/modules/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php b/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php
new file mode 100644
index 0000000..be4d53a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php
@@ -0,0 +1,9 @@
+ 'libraries/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php
new file mode 100644
index 0000000..412c0b5
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php
@@ -0,0 +1,10 @@
+ 'packages/{$vendor}/{$name}/',
+ 'theme' => 'public/themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php b/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php
new file mode 100644
index 0000000..47bbd4c
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php
@@ -0,0 +1,10 @@
+ 'libraries/{$name}/',
+ 'source' => 'libraries/_source/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php b/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php
new file mode 100644
index 0000000..9c2e9fb
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php b/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php
new file mode 100644
index 0000000..5a66460
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php
@@ -0,0 +1,16 @@
+ 'assets/snippets/{$name}/',
+ 'plugin' => 'assets/plugins/{$name}/',
+ 'module' => 'assets/modules/{$name}/',
+ 'template' => 'assets/templates/{$name}/',
+ 'lib' => 'assets/lib/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php b/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php
new file mode 100644
index 0000000..cf18e94
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php
@@ -0,0 +1,11 @@
+ 'app/design/frontend/{$name}/',
+ 'skin' => 'skin/frontend/default/{$name}/',
+ 'library' => 'lib/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php b/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php
new file mode 100644
index 0000000..e463756
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php
@@ -0,0 +1,37 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Transforms the names
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ return $this->correctPluginName($vars);
+ }
+
+ /**
+ * Change hyphenated names to camelcase
+ * @param array $vars
+ * @return array
+ */
+ private function correctPluginName($vars)
+ {
+ $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, $vars['name']);
+ $vars['name'] = ucfirst($camelCasedName);
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php b/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php
new file mode 100644
index 0000000..ca3cfac
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php
@@ -0,0 +1,9 @@
+ 'app/packages/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php b/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php
new file mode 100644
index 0000000..3e1ce2b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php
@@ -0,0 +1,25 @@
+ 'plugins/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format package name of mautic-plugins to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] == 'mautic-plugin') {
+ $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, ucfirst($vars['name']));
+ }
+
+ return $vars;
+ }
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php b/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php
new file mode 100644
index 0000000..30a9167
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php
@@ -0,0 +1,33 @@
+ 'modules/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type maya-module, cut off a trailing '-module' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'maya-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectModuleVars($vars)
+ {
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php
new file mode 100644
index 0000000..f5a8957
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php
@@ -0,0 +1,51 @@
+ 'core/',
+ 'extension' => 'extensions/{$name}/',
+ 'skin' => 'skins/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform
+ * to CamelCase keeping existing uppercase chars.
+ *
+ * For package type mediawiki-skin, cut off a trailing '-skin' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+
+ if ($vars['type'] === 'mediawiki-extension') {
+ return $this->inflectExtensionVars($vars);
+ }
+
+ if ($vars['type'] === 'mediawiki-skin') {
+ return $this->inflectSkinVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectExtensionVars($vars)
+ {
+ $vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
+ $vars['name'] = str_replace('-', ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectSkinVars($vars)
+ {
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php b/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php
new file mode 100644
index 0000000..4bbbec8
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php
@@ -0,0 +1,111 @@
+ 'userfiles/modules/{$name}/',
+ 'module-skin' => 'userfiles/modules/{$name}/templates/',
+ 'template' => 'userfiles/templates/{$name}/',
+ 'element' => 'userfiles/elements/{$name}/',
+ 'vendor' => 'vendor/{$name}/',
+ 'components' => 'components/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type microweber-module, cut off a trailing '-module' if present
+ *
+ * For package type microweber-template, cut off a trailing '-template' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'microweber-template') {
+ return $this->inflectTemplateVars($vars);
+ }
+ if ($vars['type'] === 'microweber-templates') {
+ return $this->inflectTemplatesVars($vars);
+ }
+ if ($vars['type'] === 'microweber-core') {
+ return $this->inflectCoreVars($vars);
+ }
+ if ($vars['type'] === 'microweber-adapter') {
+ return $this->inflectCoreVars($vars);
+ }
+ if ($vars['type'] === 'microweber-module') {
+ return $this->inflectModuleVars($vars);
+ }
+ if ($vars['type'] === 'microweber-modules') {
+ return $this->inflectModulesVars($vars);
+ }
+ if ($vars['type'] === 'microweber-skin') {
+ return $this->inflectSkinVars($vars);
+ }
+ if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
+ return $this->inflectElementVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectTemplateVars($vars)
+ {
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/template-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectTemplatesVars($vars)
+ {
+ $vars['name'] = preg_replace('/-templates$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/templates-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectCoreVars($vars)
+ {
+ $vars['name'] = preg_replace('/-providers$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-provider$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-adapter$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectModuleVars($vars)
+ {
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/module-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectModulesVars($vars)
+ {
+ $vars['name'] = preg_replace('/-modules$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/modules-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectSkinVars($vars)
+ {
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/skin-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectElementVars($vars)
+ {
+ $vars['name'] = preg_replace('/-elements$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/elements-$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-element$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/element-$/', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php b/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php
new file mode 100644
index 0000000..0ee140a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php
@@ -0,0 +1,12 @@
+ 'core/packages/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php
new file mode 100644
index 0000000..a89c82f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php
@@ -0,0 +1,57 @@
+ 'mod/{$name}/',
+ 'admin_report' => 'admin/report/{$name}/',
+ 'atto' => 'lib/editor/atto/plugins/{$name}/',
+ 'tool' => 'admin/tool/{$name}/',
+ 'assignment' => 'mod/assignment/type/{$name}/',
+ 'assignsubmission' => 'mod/assign/submission/{$name}/',
+ 'assignfeedback' => 'mod/assign/feedback/{$name}/',
+ 'auth' => 'auth/{$name}/',
+ 'availability' => 'availability/condition/{$name}/',
+ 'block' => 'blocks/{$name}/',
+ 'booktool' => 'mod/book/tool/{$name}/',
+ 'cachestore' => 'cache/stores/{$name}/',
+ 'cachelock' => 'cache/locks/{$name}/',
+ 'calendartype' => 'calendar/type/{$name}/',
+ 'format' => 'course/format/{$name}/',
+ 'coursereport' => 'course/report/{$name}/',
+ 'datafield' => 'mod/data/field/{$name}/',
+ 'datapreset' => 'mod/data/preset/{$name}/',
+ 'editor' => 'lib/editor/{$name}/',
+ 'enrol' => 'enrol/{$name}/',
+ 'filter' => 'filter/{$name}/',
+ 'gradeexport' => 'grade/export/{$name}/',
+ 'gradeimport' => 'grade/import/{$name}/',
+ 'gradereport' => 'grade/report/{$name}/',
+ 'gradingform' => 'grade/grading/form/{$name}/',
+ 'local' => 'local/{$name}/',
+ 'logstore' => 'admin/tool/log/store/{$name}/',
+ 'ltisource' => 'mod/lti/source/{$name}/',
+ 'ltiservice' => 'mod/lti/service/{$name}/',
+ 'message' => 'message/output/{$name}/',
+ 'mnetservice' => 'mnet/service/{$name}/',
+ 'plagiarism' => 'plagiarism/{$name}/',
+ 'portfolio' => 'portfolio/{$name}/',
+ 'qbehaviour' => 'question/behaviour/{$name}/',
+ 'qformat' => 'question/format/{$name}/',
+ 'qtype' => 'question/type/{$name}/',
+ 'quizaccess' => 'mod/quiz/accessrule/{$name}/',
+ 'quiz' => 'mod/quiz/report/{$name}/',
+ 'report' => 'report/{$name}/',
+ 'repository' => 'repository/{$name}/',
+ 'scormreport' => 'mod/scorm/report/{$name}/',
+ 'search' => 'search/engine/{$name}/',
+ 'theme' => 'theme/{$name}/',
+ 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
+ 'profilefield' => 'user/profile/field/{$name}/',
+ 'webservice' => 'webservice/{$name}/',
+ 'workshopallocation' => 'mod/workshop/allocation/{$name}/',
+ 'workshopeval' => 'mod/workshop/eval/{$name}/',
+ 'workshopform' => 'mod/workshop/form/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php b/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php
new file mode 100644
index 0000000..08d5dc4
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php
@@ -0,0 +1,47 @@
+ 'modules/{$name}/',
+ 'plugin' => 'plugins/{$vendor}/{$name}/',
+ 'theme' => 'themes/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type october-plugin, cut off a trailing '-plugin' if present.
+ *
+ * For package type october-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'october-plugin') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'october-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']);
+ $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php
new file mode 100644
index 0000000..5dd3438
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php
@@ -0,0 +1,24 @@
+ 'extensions/{$name}/',
+ 'theme' => 'extensions/themes/{$name}/',
+ 'translation' => 'extensions/translations/{$name}/',
+ );
+
+ /**
+ * Format package name to lower case and remove ".ontowiki" suffix
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower($vars['name']);
+ $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-translation$/', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php b/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php
new file mode 100644
index 0000000..3ca7954
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php
@@ -0,0 +1,14 @@
+ 'oc-content/plugins/{$name}/',
+ 'theme' => 'oc-content/themes/{$name}/',
+ 'language' => 'oc-content/languages/{$name}/',
+ );
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php
new file mode 100644
index 0000000..49940ff
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php
@@ -0,0 +1,59 @@
+.+)\/.+/';
+
+ protected $locations = array(
+ 'module' => 'modules/{$name}/',
+ 'theme' => 'application/views/{$name}/',
+ 'out' => 'out/{$name}/',
+ );
+
+ /**
+ * getInstallPath
+ *
+ * @param PackageInterface $package
+ * @param string $frameworkType
+ * @return void
+ */
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+ $installPath = parent::getInstallPath($package, $frameworkType);
+ $type = $this->package->getType();
+ if ($type === 'oxid-module') {
+ $this->prepareVendorDirectory($installPath);
+ }
+ return $installPath;
+ }
+
+ /**
+ * prepareVendorDirectory
+ *
+ * Makes sure there is a vendormetadata.php file inside
+ * the vendor folder if there is a vendor folder.
+ *
+ * @param string $installPath
+ * @return void
+ */
+ protected function prepareVendorDirectory($installPath)
+ {
+ $matches = '';
+ $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches);
+ if (!$hasVendorDirectory) {
+ return;
+ }
+
+ $vendorDirectory = $matches['vendor'];
+ $vendorPath = getcwd() . '/modules/' . $vendorDirectory;
+ if (!file_exists($vendorPath)) {
+ mkdir($vendorPath, 0755, true);
+ }
+
+ $vendorMetaDataPath = $vendorPath . '/vendormetadata.php';
+ touch($vendorMetaDataPath);
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php b/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php
new file mode 100644
index 0000000..170136f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php b/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php
new file mode 100644
index 0000000..4e59a8a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php
@@ -0,0 +1,11 @@
+ 'bundles/{$name}/',
+ 'library' => 'libraries/{$name}/',
+ 'framework' => 'frameworks/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php b/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php
new file mode 100644
index 0000000..deb2b77
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php
@@ -0,0 +1,11 @@
+ 'ext/{$vendor}/{$name}/',
+ 'language' => 'language/{$name}/',
+ 'style' => 'styles/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php b/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php
new file mode 100644
index 0000000..4781fa6
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php
@@ -0,0 +1,21 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php b/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php
new file mode 100644
index 0000000..c17f457
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php
@@ -0,0 +1,32 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php b/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php
new file mode 100644
index 0000000..903e55f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php
@@ -0,0 +1,29 @@
+ '{$name}/'
+ );
+
+ /**
+ * Remove hyphen, "plugin" and format to camelcase
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = explode("-", $vars['name']);
+ foreach ($vars['name'] as $key => $name) {
+ $vars['name'][$key] = ucfirst($vars['name'][$key]);
+ if (strcasecmp($name, "Plugin") == 0) {
+ unset($vars['name'][$key]);
+ }
+ }
+ $vars['name'] = implode("",$vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/Plugin.php b/vendor/composer/installers/src/Composer/Installers/Plugin.php
new file mode 100644
index 0000000..5eb04af
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/Plugin.php
@@ -0,0 +1,17 @@
+getInstallationManager()->addInstaller($installer);
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php b/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php
new file mode 100644
index 0000000..dbf85e6
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php
@@ -0,0 +1,9 @@
+ 'app/Containers/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php b/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php
new file mode 100644
index 0000000..4c8421e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php
@@ -0,0 +1,10 @@
+ 'modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php b/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php
new file mode 100644
index 0000000..77cc3dd
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php
@@ -0,0 +1,11 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php
new file mode 100644
index 0000000..6551058
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php
@@ -0,0 +1,63 @@
+ 'app/Modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'pxcms-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ if ($vars['type'] === 'pxcms-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ /**
+ * For package type pxcms-module, cut off a trailing '-plugin' if present.
+ *
+ * return string
+ */
+ protected function inflectModuleVars($vars)
+ {
+ $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
+ $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module-
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module
+ $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
+ $vars['name'] = ucwords($vars['name']); // make module name camelcased
+
+ return $vars;
+ }
+
+
+ /**
+ * For package type pxcms-module, cut off a trailing '-plugin' if present.
+ *
+ * return string
+ */
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
+ $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme-
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme
+ $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
+ $vars['name'] = ucwords($vars['name']); // make module name camelcased
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php
new file mode 100644
index 0000000..0f78b5c
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php
@@ -0,0 +1,24 @@
+ 'src/{$name}/'
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $nameParts = explode('/', $vars['name']);
+ foreach ($nameParts as &$value) {
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
+ $value = str_replace(array('-', '_'), ' ', $value);
+ $value = str_replace(' ', '', ucwords($value));
+ }
+ $vars['name'] = implode('/', $nameParts);
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php b/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php
new file mode 100644
index 0000000..252c733
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php
@@ -0,0 +1,10 @@
+ 'themes/{$name}/',
+ 'plugin' => 'plugins/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php b/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php
new file mode 100644
index 0000000..0954457
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php
@@ -0,0 +1,10 @@
+ 'redaxo/include/addons/{$name}/',
+ 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php b/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php
new file mode 100644
index 0000000..d8d795b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php
@@ -0,0 +1,22 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Lowercase name and changes the name to a underscores
+ *
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php b/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php
new file mode 100644
index 0000000..1acd3b1
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php
@@ -0,0 +1,10 @@
+ 'Sources/{$name}/',
+ 'theme' => 'Themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php b/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php
new file mode 100644
index 0000000..7d20d27
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php
@@ -0,0 +1,60 @@
+ 'engine/Shopware/Plugins/Local/Backend/{$name}/',
+ 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/',
+ 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/',
+ 'theme' => 'templates/{$name}/',
+ 'plugin' => 'custom/plugins/{$name}/',
+ 'frontend-theme' => 'themes/Frontend/{$name}/',
+ );
+
+ /**
+ * Transforms the names
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'shopware-theme') {
+ return $this->correctThemeName($vars);
+ }
+
+ return $this->correctPluginName($vars);
+ }
+
+ /**
+ * Changes the name to a camelcased combination of vendor and name
+ * @param array $vars
+ * @return array
+ */
+ private function correctPluginName($vars)
+ {
+ $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, $vars['name']);
+
+ $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName);
+
+ return $vars;
+ }
+
+ /**
+ * Changes the name to a underscore separated name
+ * @param array $vars
+ * @return array
+ */
+ private function correctThemeName($vars)
+ {
+ $vars['name'] = str_replace('-', '_', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php b/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php
new file mode 100644
index 0000000..81910e9
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php
@@ -0,0 +1,35 @@
+ '{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Return the install path based on package type.
+ *
+ * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework
+ * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0
+ *
+ * @param PackageInterface $package
+ * @param string $frameworkType
+ * @return string
+ */
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+ if (
+ $package->getName() == 'silverstripe/framework'
+ && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion())
+ && version_compare($package->getVersion(), '2.999.999') < 0
+ ) {
+ return $this->templatePath($this->locations['module'], array('name' => 'sapphire'));
+ }
+
+ return parent::getInstallPath($package, $frameworkType);
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php b/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php
new file mode 100644
index 0000000..762d94c
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php
@@ -0,0 +1,25 @@
+ 'modules/{$vendor}/{$name}/',
+ 'plugin' => 'plugins/{$vendor}/{$name}/'
+ );
+
+ public function inflectPackageVars($vars)
+ {
+ return $this->parseVars($vars);
+ }
+
+ protected function parseVars($vars)
+ {
+ $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor'];
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php
new file mode 100644
index 0000000..83ef9d0
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php
@@ -0,0 +1,49 @@
+ 'app/modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format module name.
+ *
+ * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present.
+ *
+ * @param array @vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] == 'sydes-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ if ($vars['type'] === 'sydes-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ public function inflectModuleVars($vars)
+ {
+ $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']);
+ $vars['name'] = strtolower($vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php b/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php
new file mode 100644
index 0000000..1675c4f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php
@@ -0,0 +1,26 @@
+
+ */
+class Symfony1Installer extends BaseInstaller
+{
+ protected $locations = array(
+ 'plugin' => 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php
new file mode 100644
index 0000000..b1663e8
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php
@@ -0,0 +1,16 @@
+
+ */
+class TYPO3CmsInstaller extends BaseInstaller
+{
+ protected $locations = array(
+ 'extension' => 'typo3conf/ext/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php b/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php
new file mode 100644
index 0000000..42572f4
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php
@@ -0,0 +1,38 @@
+ 'Packages/Application/{$name}/',
+ 'framework' => 'Packages/Framework/{$name}/',
+ 'plugin' => 'Packages/Plugins/{$name}/',
+ 'site' => 'Packages/Sites/{$name}/',
+ 'boilerplate' => 'Packages/Boilerplates/{$name}/',
+ 'build' => 'Build/{$name}/',
+ );
+
+ /**
+ * Modify the package name to be a TYPO3 Flow style key.
+ *
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $autoload = $this->package->getAutoload();
+ if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) {
+ $namespace = key($autoload['psr-0']);
+ $vars['name'] = str_replace('\\', '.', $namespace);
+ }
+ if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) {
+ $namespace = key($autoload['psr-4']);
+ $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.');
+ }
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php b/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php
new file mode 100644
index 0000000..158af52
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php
@@ -0,0 +1,12 @@
+ 'local/modules/{$name}/',
+ 'frontoffice-template' => 'templates/frontOffice/{$name}/',
+ 'backoffice-template' => 'templates/backOffice/{$name}/',
+ 'email-template' => 'templates/email/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php b/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php
new file mode 100644
index 0000000..7c0113b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php
@@ -0,0 +1,14 @@
+
+ */
+ class TuskInstaller extends BaseInstaller
+ {
+ protected $locations = array(
+ 'task' => '.tusk/tasks/{$name}/',
+ 'command' => '.tusk/commands/{$name}/',
+ 'asset' => 'assets/tusk/{$name}/',
+ );
+ }
diff --git a/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php b/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php
new file mode 100644
index 0000000..fcb414a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php
@@ -0,0 +1,9 @@
+ 'app/sprinkles/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php b/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php
new file mode 100644
index 0000000..24ca645
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php
@@ -0,0 +1,10 @@
+ 'plugins/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php b/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php
new file mode 100644
index 0000000..7d90c5e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php
@@ -0,0 +1,49 @@
+ 'src/{$vendor}/{$name}/',
+ 'theme' => 'themes/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type vgmcp-bundle, cut off a trailing '-bundle' if present.
+ *
+ * For package type vgmcp-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'vgmcp-bundle') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'vgmcp-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php b/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php
new file mode 100644
index 0000000..2cbb4a4
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php
@@ -0,0 +1,10 @@
+ 'modules/gateways/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php
new file mode 100644
index 0000000..cb38788
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php
@@ -0,0 +1,9 @@
+ 'wolf/plugins/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php b/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php
new file mode 100644
index 0000000..91c46ad
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php
@@ -0,0 +1,12 @@
+ 'wp-content/plugins/{$name}/',
+ 'theme' => 'wp-content/themes/{$name}/',
+ 'muplugin' => 'wp-content/mu-plugins/{$name}/',
+ 'dropin' => 'wp-content/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php b/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php
new file mode 100644
index 0000000..27f429f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php
@@ -0,0 +1,32 @@
+ 'module/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
\ No newline at end of file
diff --git a/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php b/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php
new file mode 100644
index 0000000..bde9bc8
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php
@@ -0,0 +1,11 @@
+ 'library/{$name}/',
+ 'extra' => 'extras/library/{$name}/',
+ 'module' => 'module/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php b/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php
new file mode 100644
index 0000000..56cdf5d
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php
@@ -0,0 +1,10 @@
+ 'modules/{$vendor}-{$name}/',
+ 'theme' => 'themes/{$vendor}-{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/bootstrap.php b/vendor/composer/installers/src/bootstrap.php
new file mode 100644
index 0000000..0de276e
--- /dev/null
+++ b/vendor/composer/installers/src/bootstrap.php
@@ -0,0 +1,13 @@
+instantiate(\My\ClassName\Here::class);
+```
+
+## Contributing
+
+Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out!
+
+## Credits
+
+This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which
+has been donated to the doctrine organization, and which is now deprecated in favour of this package.
diff --git a/vendor/doctrine/instantiator/composer.json b/vendor/doctrine/instantiator/composer.json
new file mode 100644
index 0000000..403ee8e
--- /dev/null
+++ b/vendor/doctrine/instantiator/composer.json
@@ -0,0 +1,45 @@
+{
+ "name": "doctrine/instantiator",
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "type": "library",
+ "license": "MIT",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "instantiate",
+ "constructor"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "ext-phar": "*",
+ "ext-pdo": "*",
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2",
+ "athletic/athletic": "~0.1.8"
+ },
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "autoload-dev": {
+ "psr-0": {
+ "DoctrineTest\\InstantiatorPerformance\\": "tests",
+ "DoctrineTest\\InstantiatorTest\\": "tests",
+ "DoctrineTest\\InstantiatorTestAsset\\": "tests"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ }
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..3065375
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php
@@ -0,0 +1,29 @@
+.
+ */
+
+namespace Doctrine\Instantiator\Exception;
+
+/**
+ * Base exception marker interface for the instantiator component
+ *
+ * @author Marco Pivetta
+ */
+interface ExceptionInterface
+{
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..cb57aa8
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php
@@ -0,0 +1,52 @@
+.
+ */
+
+namespace Doctrine\Instantiator\Exception;
+
+use InvalidArgumentException as BaseInvalidArgumentException;
+use ReflectionClass;
+
+/**
+ * Exception for invalid arguments provided to the instantiator
+ *
+ * @author Marco Pivetta
+ */
+class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface
+{
+ public static function fromNonExistingClass(string $className) : self
+ {
+ if (interface_exists($className)) {
+ return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className));
+ }
+
+ if (PHP_VERSION_ID >= 50400 && trait_exists($className)) {
+ return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className));
+ }
+
+ return new self(sprintf('The provided class "%s" does not exist', $className));
+ }
+
+ public static function fromAbstractClass(ReflectionClass $reflectionClass) : self
+ {
+ return new self(sprintf(
+ 'The provided class "%s" is abstract, and can not be instantiated',
+ $reflectionClass->getName()
+ ));
+ }
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php
new file mode 100644
index 0000000..2b704b9
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php
@@ -0,0 +1,66 @@
+.
+ */
+
+namespace Doctrine\Instantiator\Exception;
+
+use Exception;
+use ReflectionClass;
+use UnexpectedValueException as BaseUnexpectedValueException;
+
+/**
+ * Exception for given parameters causing invalid/unexpected state on instantiation
+ *
+ * @author Marco Pivetta
+ */
+class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface
+{
+ public static function fromSerializationTriggeredException(
+ ReflectionClass $reflectionClass,
+ Exception $exception
+ ) : self {
+ return new self(
+ sprintf(
+ 'An exception was raised while trying to instantiate an instance of "%s" via un-serialization',
+ $reflectionClass->getName()
+ ),
+ 0,
+ $exception
+ );
+ }
+
+ public static function fromUncleanUnSerialization(
+ ReflectionClass $reflectionClass,
+ string $errorString,
+ int $errorCode,
+ string $errorFile,
+ int $errorLine
+ ) : self {
+ return new self(
+ sprintf(
+ 'Could not produce an instance of "%s" via un-serialization, since an error was triggered '
+ . 'in file "%s" at line "%d"',
+ $reflectionClass->getName(),
+ $errorFile,
+ $errorLine
+ ),
+ 0,
+ new Exception($errorString, $errorCode)
+ );
+ }
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php
new file mode 100644
index 0000000..69fe65d
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php
@@ -0,0 +1,216 @@
+.
+ */
+
+namespace Doctrine\Instantiator;
+
+use Doctrine\Instantiator\Exception\InvalidArgumentException;
+use Doctrine\Instantiator\Exception\UnexpectedValueException;
+use Exception;
+use ReflectionClass;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Marco Pivetta
+ */
+final class Instantiator implements InstantiatorInterface
+{
+ /**
+ * Markers used internally by PHP to define whether {@see \unserialize} should invoke
+ * the method {@see \Serializable::unserialize()} when dealing with classes implementing
+ * the {@see \Serializable} interface.
+ */
+ const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C';
+ const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O';
+
+ /**
+ * @var \callable[] used to instantiate specific classes, indexed by class name
+ */
+ private static $cachedInstantiators = [];
+
+ /**
+ * @var object[] of objects that can directly be cloned, indexed by class name
+ */
+ private static $cachedCloneables = [];
+
+ /**
+ * {@inheritDoc}
+ */
+ public function instantiate($className)
+ {
+ if (isset(self::$cachedCloneables[$className])) {
+ return clone self::$cachedCloneables[$className];
+ }
+
+ if (isset(self::$cachedInstantiators[$className])) {
+ $factory = self::$cachedInstantiators[$className];
+
+ return $factory();
+ }
+
+ return $this->buildAndCacheFromFactory($className);
+ }
+
+ /**
+ * Builds the requested object and caches it in static properties for performance
+ *
+ * @return object
+ */
+ private function buildAndCacheFromFactory(string $className)
+ {
+ $factory = self::$cachedInstantiators[$className] = $this->buildFactory($className);
+ $instance = $factory();
+
+ if ($this->isSafeToClone(new ReflectionClass($instance))) {
+ self::$cachedCloneables[$className] = clone $instance;
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Builds a callable capable of instantiating the given $className without
+ * invoking its constructor.
+ *
+ * @throws InvalidArgumentException
+ * @throws UnexpectedValueException
+ * @throws \ReflectionException
+ */
+ private function buildFactory(string $className) : callable
+ {
+ $reflectionClass = $this->getReflectionClass($className);
+
+ if ($this->isInstantiableViaReflection($reflectionClass)) {
+ return [$reflectionClass, 'newInstanceWithoutConstructor'];
+ }
+
+ $serializedString = sprintf(
+ '%s:%d:"%s":0:{}',
+ self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER,
+ strlen($className),
+ $className
+ );
+
+ $this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString);
+
+ return function () use ($serializedString) {
+ return unserialize($serializedString);
+ };
+ }
+
+ /**
+ * @param string $className
+ *
+ * @return ReflectionClass
+ *
+ * @throws InvalidArgumentException
+ * @throws \ReflectionException
+ */
+ private function getReflectionClass($className) : ReflectionClass
+ {
+ if (! class_exists($className)) {
+ throw InvalidArgumentException::fromNonExistingClass($className);
+ }
+
+ $reflection = new ReflectionClass($className);
+
+ if ($reflection->isAbstract()) {
+ throw InvalidArgumentException::fromAbstractClass($reflection);
+ }
+
+ return $reflection;
+ }
+
+ /**
+ * @param ReflectionClass $reflectionClass
+ * @param string $serializedString
+ *
+ * @throws UnexpectedValueException
+ *
+ * @return void
+ */
+ private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, $serializedString) : void
+ {
+ set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) : void {
+ $error = UnexpectedValueException::fromUncleanUnSerialization(
+ $reflectionClass,
+ $message,
+ $code,
+ $file,
+ $line
+ );
+ });
+
+ $this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
+
+ restore_error_handler();
+
+ if ($error) {
+ throw $error;
+ }
+ }
+
+ /**
+ * @param ReflectionClass $reflectionClass
+ * @param string $serializedString
+ *
+ * @throws UnexpectedValueException
+ *
+ * @return void
+ */
+ private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString) : void
+ {
+ try {
+ unserialize($serializedString);
+ } catch (Exception $exception) {
+ restore_error_handler();
+
+ throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception);
+ }
+ }
+
+ private function isInstantiableViaReflection(ReflectionClass $reflectionClass) : bool
+ {
+ return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal());
+ }
+
+ /**
+ * Verifies whether the given class is to be considered internal
+ */
+ private function hasInternalAncestors(ReflectionClass $reflectionClass) : bool
+ {
+ do {
+ if ($reflectionClass->isInternal()) {
+ return true;
+ }
+ } while ($reflectionClass = $reflectionClass->getParentClass());
+
+ return false;
+ }
+
+ /**
+ * Checks if a class is cloneable
+ *
+ * Classes implementing `__clone` cannot be safely cloned, as that may cause side-effects.
+ */
+ private function isSafeToClone(ReflectionClass $reflection) : bool
+ {
+ return $reflection->isCloneable() && ! $reflection->hasMethod('__clone');
+ }
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php
new file mode 100644
index 0000000..b665bea
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php
@@ -0,0 +1,37 @@
+.
+ */
+
+namespace Doctrine\Instantiator;
+
+/**
+ * Instantiator provides utility methods to build objects without invoking their constructors
+ *
+ * @author Marco Pivetta
+ */
+interface InstantiatorInterface
+{
+ /**
+ * @param string $className
+ *
+ * @return object
+ *
+ * @throws \Doctrine\Instantiator\Exception\ExceptionInterface
+ */
+ public function instantiate($className);
+}
diff --git a/vendor/hamcrest/hamcrest-php/.coveralls.yml b/vendor/hamcrest/hamcrest-php/.coveralls.yml
new file mode 100644
index 0000000..f2f9ed5
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/.coveralls.yml
@@ -0,0 +1 @@
+src_dir: hamcrest
diff --git a/vendor/hamcrest/hamcrest-php/.gitignore b/vendor/hamcrest/hamcrest-php/.gitignore
new file mode 100644
index 0000000..22d0d82
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/.gitignore
@@ -0,0 +1 @@
+vendor
diff --git a/vendor/hamcrest/hamcrest-php/.gush.yml b/vendor/hamcrest/hamcrest-php/.gush.yml
new file mode 100644
index 0000000..b7c226d
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/.gush.yml
@@ -0,0 +1,7 @@
+adapter: github
+issue_tracker: github
+meta-header: "Copyright (c) 2009-2015 hamcrest.org"
+table-pr:
+ fixed_tickets: ['Fixed Tickets', '']
+ license: ['License', MIT]
+base: master
diff --git a/vendor/hamcrest/hamcrest-php/.travis.yml b/vendor/hamcrest/hamcrest-php/.travis.yml
new file mode 100644
index 0000000..80b4ed0
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/.travis.yml
@@ -0,0 +1,24 @@
+language: php
+php:
+ - 5.6
+ - 5.5
+ - 5.4
+ - 5.3
+ - hhvm
+ - 7.0
+
+matrix:
+ allow_failures:
+ - php: hhvm
+
+install:
+ - composer update --prefer-source
+
+script:
+ - mkdir -p build/logs
+ - php vendor/bin/phpunit --coverage-clover=build/logs/clover.xml -c tests/phpunit.xml.dist
+
+after_script:
+ - php vendor/bin/coveralls -v
+ - wget https://scrutinizer-ci.com/ocular.phar
+ - php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml
diff --git a/vendor/hamcrest/hamcrest-php/CHANGES.txt b/vendor/hamcrest/hamcrest-php/CHANGES.txt
new file mode 100644
index 0000000..708193b
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/CHANGES.txt
@@ -0,0 +1,167 @@
+== Version 2.0: Released XXX XX 2016 ==
+
+* Removed automatic loading of global functions
+
+== Version 1.1.0: Released Feb 2 2012 ==
+
+Issues Fixed: 121, 138, 147
+
+* Added non-empty matchers to complement the emptiness-matching forms.
+
+ - nonEmptyString()
+ - nonEmptyArray()
+ - nonEmptyTraversable()
+
+* Added ability to pass variable arguments to several array-based matcher
+ factory methods so they work like allOf() et al.
+
+ - anArray()
+ - arrayContainingInAnyOrder(), containsInAnyOrder()
+ - arrayContaining(), contains()
+ - stringContainsInOrder()
+
+* Matchers that accept an array of matchers now also accept variable arguments.
+ Any non-matcher arguments are wrapped by IsEqual.
+
+* Added noneOf() as a shortcut for not(anyOf()).
+
+
+== Version 1.0.0: Released Jan 20 2012 ==
+
+Issues Fixed: 119, 136, 139, 141, 148, 149, 172
+
+* Moved hamcrest.php into Hamcrest folder and renamed to Hamcrest.php.
+ This is more in line with PEAR packaging standards.
+
+* Renamed callable() to callableValue() for compatibility with PHP 5.4.
+
+* Added Hamcrest_Text_StringContainsIgnoringCase to assert using stripos().
+
+ assertThat('fOObAr', containsStringIgnoringCase('oba'));
+ assertThat('fOObAr', containsString('oba')->ignoringCase());
+
+* Fixed Hamcrest_Core_IsInstanceOf to return false for native types.
+
+* Moved string-based matchers to Hamcrest_Text package.
+ StringContains, StringEndsWith, StringStartsWith, and SubstringMatcher
+
+* Hamcrest.php and Hamcrest_Matchers.php are now built from @factory doctags.
+ Added @factory doctag to every static factory method.
+
+* Hamcrest_Matchers and Hamcrest.php now import each matcher as-needed
+ and Hamcrest.php calls the matchers directly instead of Hamcrest_Matchers.
+
+
+== Version 0.3.0: Released Jul 26 2010 ==
+
+* Added running count to Hamcrest_MatcherAssert with methods to get and reset it.
+ This can be used by unit testing frameworks for reporting.
+
+* Added Hamcrest_Core_HasToString to assert return value of toString() or __toString().
+
+ assertThat($anObject, hasToString('foo'));
+
+* Added Hamcrest_Type_IsScalar to assert is_scalar().
+ Matches values of type bool, int, float, double, and string.
+
+ assertThat($count, scalarValue());
+ assertThat('foo', scalarValue());
+
+* Added Hamcrest_Collection package.
+
+ - IsEmptyTraversable
+ - IsTraversableWithSize
+
+ assertThat($iterator, emptyTraversable());
+ assertThat($iterator, traversableWithSize(5));
+
+* Added Hamcrest_Xml_HasXPath to assert XPath expressions or the content of nodes in an XML/HTML DOM.
+
+ assertThat($dom, hasXPath('books/book/title'));
+ assertThat($dom, hasXPath('books/book[contains(title, "Alice")]', 3));
+ assertThat($dom, hasXPath('books/book/title', 'Alice in Wonderland'));
+ assertThat($dom, hasXPath('count(books/book)', greaterThan(10)));
+
+* Added aliases to match the Java API.
+
+ hasEntry() -> hasKeyValuePair()
+ hasValue() -> hasItemInArray()
+ contains() -> arrayContaining()
+ containsInAnyOrder() -> arrayContainingInAnyOrder()
+
+* Added optional subtype to Hamcrest_TypeSafeMatcher to enforce object class or resource type.
+
+* Hamcrest_TypeSafeDiagnosingMatcher now extends Hamcrest_TypeSafeMatcher.
+
+
+== Version 0.2.0: Released Jul 14 2010 ==
+
+Issues Fixed: 109, 111, 114, 115
+
+* Description::appendValues() and appendValueList() accept Iterator and IteratorAggregate. [111]
+ BaseDescription::appendValue() handles IteratorAggregate.
+
+* assertThat() accepts a single boolean parameter and
+ wraps any non-Matcher third parameter with equalTo().
+
+* Removed null return value from assertThat(). [114]
+
+* Fixed wrong variable name in contains(). [109]
+
+* Added Hamcrest_Core_IsSet to assert isset().
+
+ assertThat(array('foo' => 'bar'), set('foo'));
+ assertThat(array('foo' => 'bar'), notSet('bar'));
+
+* Added Hamcrest_Core_IsTypeOf to assert built-in types with gettype(). [115]
+ Types: array, boolean, double, integer, null, object, resource, and string.
+ Note that gettype() returns "double" for float values.
+
+ assertThat($count, typeOf('integer'));
+ assertThat(3.14159, typeOf('double'));
+ assertThat(array('foo', 'bar'), typeOf('array'));
+ assertThat(new stdClass(), typeOf('object'));
+
+* Added type-specific matchers in new Hamcrest_Type package.
+
+ - IsArray
+ - IsBoolean
+ - IsDouble (includes float values)
+ - IsInteger
+ - IsObject
+ - IsResource
+ - IsString
+
+ assertThat($count, integerValue());
+ assertThat(3.14159, floatValue());
+ assertThat('foo', stringValue());
+
+* Added Hamcrest_Type_IsNumeric to assert is_numeric().
+ Matches values of type int and float/double or strings that are formatted as numbers.
+
+ assertThat(5, numericValue());
+ assertThat('-5e+3', numericValue());
+
+* Added Hamcrest_Type_IsCallable to assert is_callable().
+
+ assertThat('preg_match', callable());
+ assertThat(array('SomeClass', 'SomeMethod'), callable());
+ assertThat(array($object, 'SomeMethod'), callable());
+ assertThat($object, callable());
+ assertThat(function ($x, $y) { return $x + $y; }, callable());
+
+* Added Hamcrest_Text_MatchesPattern for regex matching with preg_match().
+
+ assertThat('foobar', matchesPattern('/o+b/'));
+
+* Added aliases:
+ - atLeast() for greaterThanOrEqualTo()
+ - atMost() for lessThanOrEqualTo()
+
+
+== Version 0.1.0: Released Jul 7 2010 ==
+
+* Created PEAR package
+
+* Core matchers
+
diff --git a/vendor/hamcrest/hamcrest-php/LICENSE.txt b/vendor/hamcrest/hamcrest-php/LICENSE.txt
new file mode 100644
index 0000000..91cd329
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/LICENSE.txt
@@ -0,0 +1,27 @@
+BSD License
+
+Copyright (c) 2000-2014, www.hamcrest.org
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer. Redistributions in binary form must reproduce
+the above copyright notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+Neither the name of Hamcrest nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/vendor/hamcrest/hamcrest-php/README.md b/vendor/hamcrest/hamcrest-php/README.md
new file mode 100644
index 0000000..0b07c71
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/README.md
@@ -0,0 +1,53 @@
+This is the PHP port of Hamcrest Matchers
+=========================================
+
+[![Build Status](https://travis-ci.org/hamcrest/hamcrest-php.png?branch=master)](https://travis-ci.org/hamcrest/hamcrest-php)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/hamcrest/hamcrest-php/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/hamcrest/hamcrest-php/?branch=master)
+[![Code Coverage](https://scrutinizer-ci.com/g/hamcrest/hamcrest-php/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/hamcrest/hamcrest-php/?branch=master)
+
+Hamcrest is a matching library originally written for Java, but
+subsequently ported to many other languages. hamcrest-php is the
+official PHP port of Hamcrest and essentially follows a literal
+translation of the original Java API for Hamcrest, with a few
+Exceptions, mostly down to PHP language barriers:
+
+ 1. `instanceOf($theClass)` is actually `anInstanceOf($theClass)`
+
+ 2. `both(containsString('a'))->and(containsString('b'))`
+ is actually `both(containsString('a'))->andAlso(containsString('b'))`
+
+ 3. `either(containsString('a'))->or(containsString('b'))`
+ is actually `either(containsString('a'))->orElse(containsString('b'))`
+
+ 4. Unless it would be non-semantic for a matcher to do so, hamcrest-php
+ allows dynamic typing for it's input, in "the PHP way". Exception are
+ where semantics surrounding the type itself would suggest otherwise,
+ such as stringContains() and greaterThan().
+
+ 5. Several official matchers have not been ported because they don't
+ make sense or don't apply in PHP:
+
+ - `typeCompatibleWith($theClass)`
+ - `eventFrom($source)`
+ - `hasProperty($name)` **
+ - `samePropertyValuesAs($obj)` **
+
+ 6. When most of the collections matchers are finally ported, PHP-specific
+ aliases will probably be created due to a difference in naming
+ conventions between Java's Arrays, Collections, Sets and Maps compared
+ with PHP's Arrays.
+
+---
+** [Unless we consider POPO's (Plain Old PHP Objects) akin to JavaBeans]
+ - The POPO thing is a joke. Java devs coin the term POJO's (Plain Old
+ Java Objects).
+
+
+Usage
+-----
+
+Hamcrest matchers are easy to use as:
+
+```php
+Hamcrest_MatcherAssert::assertThat('a', Hamcrest_Matchers::equalToIgnoringCase('A'));
+```
diff --git a/vendor/hamcrest/hamcrest-php/TODO.txt b/vendor/hamcrest/hamcrest-php/TODO.txt
new file mode 100644
index 0000000..92e1190
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/TODO.txt
@@ -0,0 +1,22 @@
+Still TODO Before Complete for PHP
+----------------------------------
+
+Port:
+
+ - Hamcrest_Collection_*
+ - IsCollectionWithSize
+ - IsEmptyCollection
+ - IsIn
+ - IsTraversableContainingInAnyOrder
+ - IsTraversableContainingInOrder
+ - IsMapContaining (aliases)
+
+Aliasing/Deprecation (questionable):
+
+ - Find and fix any factory methods that start with "is".
+
+Namespaces:
+
+ - Investigate adding PHP 5.3+ namespace support in a way that still permits
+ use in PHP 5.2.
+ - Other than a parallel codebase, I don't see how this could be possible.
diff --git a/vendor/hamcrest/hamcrest-php/composer.json b/vendor/hamcrest/hamcrest-php/composer.json
new file mode 100644
index 0000000..5349f5f
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "hamcrest/hamcrest-php",
+ "type": "library",
+ "description": "This is the PHP port of Hamcrest Matchers",
+ "keywords": ["test"],
+ "license": "BSD",
+ "authors": [
+ ],
+
+ "autoload": {
+ "classmap": ["hamcrest"]
+ },
+ "autoload-dev": {
+ "classmap": ["tests", "generator"]
+ },
+
+ "require": {
+ "php": "^5.3|^7.0"
+ },
+
+ "require-dev": {
+ "satooshi/php-coveralls": "^1.0",
+ "phpunit/php-file-iterator": "1.3.3",
+ "phpunit/phpunit": "~4.0"
+ },
+
+ "replace": {
+ "kodova/hamcrest-php": "*",
+ "davedevelopment/hamcrest-php": "*",
+ "cordoval/hamcrest-php": "*"
+ },
+
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/composer.lock b/vendor/hamcrest/hamcrest-php/composer.lock
new file mode 100644
index 0000000..0581a4e
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/composer.lock
@@ -0,0 +1,1493 @@
+{
+ "_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#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "52d9e3c2e238bdc2aab7f6e1d322e31d",
+ "content-hash": "ed113672807f01f40b4d9809b102dc31",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3,<8.0-DEV"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "~4.0",
+ "squizlabs/php_codesniffer": "~2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "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": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "time": "2015-06-14 21:17:01"
+ },
+ {
+ "name": "guzzle/guzzle",
+ "version": "v3.9.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle3.git",
+ "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9",
+ "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "php": ">=5.3.3",
+ "symfony/event-dispatcher": "~2.1"
+ },
+ "replace": {
+ "guzzle/batch": "self.version",
+ "guzzle/cache": "self.version",
+ "guzzle/common": "self.version",
+ "guzzle/http": "self.version",
+ "guzzle/inflection": "self.version",
+ "guzzle/iterator": "self.version",
+ "guzzle/log": "self.version",
+ "guzzle/parser": "self.version",
+ "guzzle/plugin": "self.version",
+ "guzzle/plugin-async": "self.version",
+ "guzzle/plugin-backoff": "self.version",
+ "guzzle/plugin-cache": "self.version",
+ "guzzle/plugin-cookie": "self.version",
+ "guzzle/plugin-curlauth": "self.version",
+ "guzzle/plugin-error-response": "self.version",
+ "guzzle/plugin-history": "self.version",
+ "guzzle/plugin-log": "self.version",
+ "guzzle/plugin-md5": "self.version",
+ "guzzle/plugin-mock": "self.version",
+ "guzzle/plugin-oauth": "self.version",
+ "guzzle/service": "self.version",
+ "guzzle/stream": "self.version"
+ },
+ "require-dev": {
+ "doctrine/cache": "~1.3",
+ "monolog/monolog": "~1.0",
+ "phpunit/phpunit": "3.7.*",
+ "psr/log": "~1.0",
+ "symfony/class-loader": "~2.1",
+ "zendframework/zend-cache": "2.*,<2.3",
+ "zendframework/zend-log": "2.*,<2.3"
+ },
+ "suggest": {
+ "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Guzzle": "src/",
+ "Guzzle\\Tests": "tests/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Guzzle Community",
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
+ }
+ ],
+ "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "time": "2015-03-18 18:23:50"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "suggest": {
+ "dflydev/markdown": "~1.0",
+ "erusev/parsedown": "~1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "phpDocumentor": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "mike.vanriel@naenius.com"
+ }
+ ],
+ "time": "2015-02-03 12:10:50"
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "v1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7",
+ "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "phpdocumentor/reflection-docblock": "~2.0",
+ "sebastian/comparator": "~1.1"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "~2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "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": "2015-08-13 10:07:40"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "2.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "phpunit/php-file-iterator": "~1.3",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-token-stream": "~1.3",
+ "sebastian/environment": "^1.3.2",
+ "sebastian/version": "~1.0"
+ },
+ "require-dev": {
+ "ext-xdebug": ">=2.1.4",
+ "phpunit/phpunit": "~4"
+ },
+ "suggest": {
+ "ext-dom": "*",
+ "ext-xdebug": ">=2.2.1",
+ "ext-xmlwriter": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.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": "2015-10-06 15:47:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "16a78140ed2fc01b945cfa539665fadc6a038029"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/16a78140ed2fc01b945cfa539665fadc6a038029",
+ "reference": "16a78140ed2fc01b945cfa539665fadc6a038029",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "File/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "http://www.phpunit.de/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "time": "2012-10-11 11:44:38"
+ },
+ {
+ "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-21 13:50:34"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
+ "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
+ "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": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2015-06-21 08:01:12"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "1.4.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
+ "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-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"
+ ],
+ "time": "2015-09-15 10:49:45"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "4.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d6429b0995b24a2d9dfe5587ee3a7071c1161af4",
+ "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-reflection": "*",
+ "ext-spl": "*",
+ "php": ">=5.3.3",
+ "phpspec/prophecy": "~1.3,>=1.3.1",
+ "phpunit/php-code-coverage": "~2.0,>=2.0.11",
+ "phpunit/php-file-iterator": "~1.3.2",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-timer": "~1.0.2",
+ "phpunit/phpunit-mock-objects": "~2.3",
+ "sebastian/comparator": "~1.1",
+ "sebastian/diff": "~1.1",
+ "sebastian/environment": "~1.2",
+ "sebastian/exporter": "~1.2",
+ "sebastian/global-state": "~1.0",
+ "sebastian/version": "~1.0",
+ "symfony/yaml": "~2.0"
+ },
+ "suggest": {
+ "phpunit/php-invoker": "~1.1"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.5.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": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "time": "2015-03-29 09:24:05"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "2.3.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": ">=5.3.3",
+ "phpunit/php-text-template": "~1.2",
+ "sebastian/exporter": "~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ],
+ "time": "2015-10-02 06:51:40"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "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",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2012-12-21 11:40:51"
+ },
+ {
+ "name": "satooshi/php-coveralls",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/satooshi/php-coveralls.git",
+ "reference": "3edbdbdb4f4cfab5cb9ce83655ff81432f2221a6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/3edbdbdb4f4cfab5cb9ce83655ff81432f2221a6",
+ "reference": "3edbdbdb4f4cfab5cb9ce83655ff81432f2221a6",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "guzzle/guzzle": "^2.8|^3.0",
+ "php": ">=5.3.3",
+ "psr/log": "^1.0",
+ "symfony/config": "^2.4|^3.0",
+ "symfony/console": "^2.1|^3.0",
+ "symfony/stopwatch": "^2.2|^3.0",
+ "symfony/yaml": "^2.1|^3.0"
+ },
+ "suggest": {
+ "symfony/http-kernel": "Allows Symfony integration"
+ },
+ "bin": [
+ "bin/coveralls"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Satooshi\\": "src/Satooshi/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kitamura Satoshi",
+ "email": "with.no.parachute@gmail.com",
+ "homepage": "https://www.facebook.com/satooshi.jp"
+ }
+ ],
+ "description": "PHP client library for Coveralls API",
+ "homepage": "https://github.com/satooshi/php-coveralls",
+ "keywords": [
+ "ci",
+ "coverage",
+ "github",
+ "test"
+ ],
+ "time": "2015-12-28 09:07:32"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
+ "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "~1.2",
+ "sebastian/exporter": "~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-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": "http://www.github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "time": "2015-07-26 15:48:44"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-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"
+ ],
+ "time": "2015-12-08 07:14:41"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "1.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "6e7133793a8e5a5714a551a8324337374be209df"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df",
+ "reference": "6e7133793a8e5a5714a551a8324337374be209df",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3.x-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": "2015-12-02 08:37:27"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "7ae5513327cb536431847bcc0c10edba2701064e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
+ "reference": "7ae5513327cb536431847bcc0c10edba2701064e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/recursion-context": "~1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-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"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2015-06-21 07:55:53"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.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": "2015-10-12 03:26:01"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
+ "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "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": "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": "2015-11-11 19:50:13"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "1.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
+ "shasum": ""
+ },
+ "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": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "time": "2015-06-21 13:59:46"
+ },
+ {
+ "name": "symfony/config",
+ "version": "v2.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/config.git",
+ "reference": "17d4b2e64ce1c6ba7caa040f14469b3c44d7f7d2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/config/zipball/17d4b2e64ce1c6ba7caa040f14469b3c44d7f7d2",
+ "reference": "17d4b2e64ce1c6ba7caa040f14469b3c44d7f7d2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9",
+ "symfony/filesystem": "~2.3|~3.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Config\\": ""
+ },
+ "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 Config Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-12-26 13:37:56"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v2.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/2e06a5ccb19dcf9b89f1c6a677a39a8df773635a",
+ "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
+ "symfony/process": "~2.1|~3.0.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-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",
+ "time": "2015-12-22 10:25:57"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v2.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc",
+ "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
+ "symfony/dependency-injection": "~2.6|~3.0.0",
+ "symfony/expression-language": "~2.6|~3.0.0",
+ "symfony/stopwatch": "~2.3|~3.0.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-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",
+ "time": "2015-10-30 20:15:42"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v2.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "a7ad724530a764d70c168d321ac226ba3d2f10fc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/a7ad724530a764d70c168d321ac226ba3d2f10fc",
+ "reference": "a7ad724530a764d70c168d321ac226ba3d2f10fc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "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",
+ "time": "2015-12-22 10:25:57"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/49ff736bd5d41f45240cec77b44967d76e0c3d25",
+ "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-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"
+ ],
+ "time": "2015-11-20 09:19:13"
+ },
+ {
+ "name": "symfony/stopwatch",
+ "version": "v2.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/stopwatch.git",
+ "reference": "5f1e2ebd1044da542d2b9510527836e8be92b1cb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5f1e2ebd1044da542d2b9510527836e8be92b1cb",
+ "reference": "5f1e2ebd1044da542d2b9510527836e8be92b1cb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Stopwatch\\": ""
+ },
+ "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 Stopwatch Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-10-30 20:15:42"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v2.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966",
+ "reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.8-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",
+ "time": "2015-12-26 13:37:56"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=5.3.2"
+ },
+ "platform-dev": []
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/FactoryCall.php b/vendor/hamcrest/hamcrest-php/generator/FactoryCall.php
new file mode 100644
index 0000000..83965b2
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/FactoryCall.php
@@ -0,0 +1,41 @@
+method = $method;
+ $this->name = $name;
+ }
+
+ public function getMethod()
+ {
+ return $this->method;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/FactoryClass.php b/vendor/hamcrest/hamcrest-php/generator/FactoryClass.php
new file mode 100644
index 0000000..0c6bf78
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/FactoryClass.php
@@ -0,0 +1,72 @@
+file = $file;
+ $this->reflector = $class;
+ $this->extractFactoryMethods();
+ }
+
+ public function extractFactoryMethods()
+ {
+ $this->methods = array();
+ foreach ($this->getPublicStaticMethods() as $method) {
+ if ($method->isFactory()) {
+// echo $this->getName() . '::' . $method->getName() . ' : ' . count($method->getCalls()) . PHP_EOL;
+ $this->methods[] = $method;
+ }
+ }
+ }
+
+ public function getPublicStaticMethods()
+ {
+ $methods = array();
+ foreach ($this->reflector->getMethods(ReflectionMethod::IS_STATIC) as $method) {
+ if ($method->isPublic() && $method->getDeclaringClass() == $this->reflector) {
+ $methods[] = new FactoryMethod($this, $method);
+ }
+ }
+ return $methods;
+ }
+
+ public function getFile()
+ {
+ return $this->file;
+ }
+
+ public function getName()
+ {
+ return $this->reflector->name;
+ }
+
+ public function isFactory()
+ {
+ return !empty($this->methods);
+ }
+
+ public function getMethods()
+ {
+ return $this->methods;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/FactoryFile.php b/vendor/hamcrest/hamcrest-php/generator/FactoryFile.php
new file mode 100644
index 0000000..ac3d6c7
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/FactoryFile.php
@@ -0,0 +1,122 @@
+file = $file;
+ $this->indent = $indent;
+ }
+
+ abstract public function addCall(FactoryCall $call);
+
+ abstract public function build();
+
+ public function addFileHeader()
+ {
+ $this->code = '';
+ $this->addPart('file_header');
+ }
+
+ public function addPart($name)
+ {
+ $this->addCode($this->readPart($name));
+ }
+
+ public function addCode($code)
+ {
+ $this->code .= $code;
+ }
+
+ public function readPart($name)
+ {
+ return file_get_contents(__DIR__ . "/parts/$name.txt");
+ }
+
+ public function generateFactoryCall(FactoryCall $call)
+ {
+ $method = $call->getMethod();
+ $code = $method->getComment($this->indent) . PHP_EOL;
+ $code .= $this->generateDeclaration($call->getName(), $method);
+ // $code .= $this->generateImport($method);
+ $code .= $this->generateCall($method);
+ $code .= $this->generateClosing();
+ return $code;
+ }
+
+ public function generateDeclaration($name, FactoryMethod $method)
+ {
+ $code = $this->indent . $this->getDeclarationModifiers()
+ . 'function ' . $name . '('
+ . $this->generateDeclarationArguments($method)
+ . ')' . PHP_EOL . $this->indent . '{' . PHP_EOL;
+ return $code;
+ }
+
+ public function getDeclarationModifiers()
+ {
+ return '';
+ }
+
+ public function generateDeclarationArguments(FactoryMethod $method)
+ {
+ if ($method->acceptsVariableArguments()) {
+ return '/* args... */';
+ } else {
+ return $method->getParameterDeclarations();
+ }
+ }
+
+ public function generateImport(FactoryMethod $method)
+ {
+ return $this->indent . self::INDENT . "require_once '" . $method->getClass()->getFile() . "';" . PHP_EOL;
+ }
+
+ public function generateCall(FactoryMethod $method)
+ {
+ $code = '';
+ if ($method->acceptsVariableArguments()) {
+ $code .= $this->indent . self::INDENT . '$args = func_get_args();' . PHP_EOL;
+ }
+
+ $code .= $this->indent . self::INDENT . 'return ';
+ if ($method->acceptsVariableArguments()) {
+ $code .= 'call_user_func_array(array(\''
+ . '\\' . $method->getClassName() . '\', \''
+ . $method->getName() . '\'), $args);' . PHP_EOL;
+ } else {
+ $code .= '\\' . $method->getClassName() . '::'
+ . $method->getName() . '('
+ . $method->getParameterInvocations() . ');' . PHP_EOL;
+ }
+
+ return $code;
+ }
+
+ public function generateClosing()
+ {
+ return $this->indent . '}' . PHP_EOL;
+ }
+
+ public function write()
+ {
+ file_put_contents($this->file, $this->code);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/FactoryGenerator.php b/vendor/hamcrest/hamcrest-php/generator/FactoryGenerator.php
new file mode 100644
index 0000000..37f80b6
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/FactoryGenerator.php
@@ -0,0 +1,115 @@
+path = $path;
+ $this->factoryFiles = array();
+ }
+
+ public function addFactoryFile(FactoryFile $factoryFile)
+ {
+ $this->factoryFiles[] = $factoryFile;
+ }
+
+ public function generate()
+ {
+ $classes = $this->getClassesWithFactoryMethods();
+ foreach ($classes as $class) {
+ foreach ($class->getMethods() as $method) {
+ foreach ($method->getCalls() as $call) {
+ foreach ($this->factoryFiles as $file) {
+ $file->addCall($call);
+ }
+ }
+ }
+ }
+ }
+
+ public function write()
+ {
+ foreach ($this->factoryFiles as $file) {
+ $file->build();
+ $file->write();
+ }
+ }
+
+ public function getClassesWithFactoryMethods()
+ {
+ $classes = array();
+ $files = $this->getSortedFiles();
+ foreach ($files as $file) {
+ $class = $this->getFactoryClass($file);
+ if ($class !== null) {
+ $classes[] = $class;
+ }
+ }
+
+ return $classes;
+ }
+
+ public function getSortedFiles()
+ {
+ $iter = \File_Iterator_Factory::getFileIterator($this->path, '.php');
+ $files = array();
+ foreach ($iter as $file) {
+ $files[] = $file;
+ }
+ sort($files, SORT_STRING);
+
+ return $files;
+ }
+
+ public function getFactoryClass($file)
+ {
+ $name = $this->getFactoryClassName($file);
+ if ($name !== null) {
+ require_once $file;
+
+ if (class_exists($name)) {
+ $class = new FactoryClass(substr($file, strpos($file, 'Hamcrest/')), new ReflectionClass($name));
+ if ($class->isFactory()) {
+ return $class;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public function getFactoryClassName($file)
+ {
+ $content = file_get_contents($file);
+ if (preg_match('/namespace\s+(.+);/', $content, $namespace)
+ && preg_match('/\n\s*class\s+(\w+)\s+extends\b/', $content, $className)
+ && preg_match('/@factory\b/', $content)
+ ) {
+ return $namespace[1] . '\\' . $className[1];
+ }
+
+ return null;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/FactoryMethod.php b/vendor/hamcrest/hamcrest-php/generator/FactoryMethod.php
new file mode 100644
index 0000000..44f8dc5
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/FactoryMethod.php
@@ -0,0 +1,231 @@
+class = $class;
+ $this->reflector = $reflector;
+ $this->extractCommentWithoutLeadingShashesAndStars();
+ $this->extractFactoryNamesFromComment();
+ $this->extractParameters();
+ }
+
+ public function extractCommentWithoutLeadingShashesAndStars()
+ {
+ $this->comment = explode("\n", $this->reflector->getDocComment());
+ foreach ($this->comment as &$line) {
+ $line = preg_replace('#^\s*(/\\*+|\\*+/|\\*)\s?#', '', $line);
+ }
+ $this->trimLeadingBlankLinesFromComment();
+ $this->trimTrailingBlankLinesFromComment();
+ }
+
+ public function trimLeadingBlankLinesFromComment()
+ {
+ while (count($this->comment) > 0) {
+ $line = array_shift($this->comment);
+ if (trim($line) != '') {
+ array_unshift($this->comment, $line);
+ break;
+ }
+ }
+ }
+
+ public function trimTrailingBlankLinesFromComment()
+ {
+ while (count($this->comment) > 0) {
+ $line = array_pop($this->comment);
+ if (trim($line) != '') {
+ array_push($this->comment, $line);
+ break;
+ }
+ }
+ }
+
+ public function extractFactoryNamesFromComment()
+ {
+ $this->calls = array();
+ for ($i = 0; $i < count($this->comment); $i++) {
+ if ($this->extractFactoryNamesFromLine($this->comment[$i])) {
+ unset($this->comment[$i]);
+ }
+ }
+ $this->trimTrailingBlankLinesFromComment();
+ }
+
+ public function extractFactoryNamesFromLine($line)
+ {
+ if (preg_match('/^\s*@factory(\s+(.+))?$/', $line, $match)) {
+ $this->createCalls(
+ $this->extractFactoryNamesFromAnnotation(
+ isset($match[2]) ? trim($match[2]) : null
+ )
+ );
+ return true;
+ }
+ return false;
+ }
+
+ public function extractFactoryNamesFromAnnotation($value)
+ {
+ $primaryName = $this->reflector->getName();
+ if (empty($value)) {
+ return array($primaryName);
+ }
+ preg_match_all('/(\.{3}|-|[a-zA-Z_][a-zA-Z_0-9]*)/', $value, $match);
+ $names = $match[0];
+ if (in_array('...', $names)) {
+ $this->isVarArgs = true;
+ }
+ if (!in_array('-', $names) && !in_array($primaryName, $names)) {
+ array_unshift($names, $primaryName);
+ }
+ return $names;
+ }
+
+ public function createCalls(array $names)
+ {
+ $names = array_unique($names);
+ foreach ($names as $name) {
+ if ($name != '-' && $name != '...') {
+ $this->calls[] = new FactoryCall($this, $name);
+ }
+ }
+ }
+
+ public function extractParameters()
+ {
+ $this->parameters = array();
+ if (!$this->isVarArgs) {
+ foreach ($this->reflector->getParameters() as $parameter) {
+ $this->parameters[] = new FactoryParameter($this, $parameter);
+ }
+ }
+ }
+
+ public function getParameterDeclarations()
+ {
+ if ($this->isVarArgs || !$this->hasParameters()) {
+ return '';
+ }
+ $params = array();
+ foreach ($this->parameters as /** @var $parameter FactoryParameter */
+ $parameter) {
+ $params[] = $parameter->getDeclaration();
+ }
+ return implode(', ', $params);
+ }
+
+ public function getParameterInvocations()
+ {
+ if ($this->isVarArgs) {
+ return '';
+ }
+ $params = array();
+ foreach ($this->parameters as $parameter) {
+ $params[] = $parameter->getInvocation();
+ }
+ return implode(', ', $params);
+ }
+
+
+ public function getClass()
+ {
+ return $this->class;
+ }
+
+ public function getClassName()
+ {
+ return $this->class->getName();
+ }
+
+ public function getName()
+ {
+ return $this->reflector->name;
+ }
+
+ public function isFactory()
+ {
+ return count($this->calls) > 0;
+ }
+
+ public function getCalls()
+ {
+ return $this->calls;
+ }
+
+ public function acceptsVariableArguments()
+ {
+ return $this->isVarArgs;
+ }
+
+ public function hasParameters()
+ {
+ return !empty($this->parameters);
+ }
+
+ public function getParameters()
+ {
+ return $this->parameters;
+ }
+
+ public function getFullName()
+ {
+ return $this->getClassName() . '::' . $this->getName();
+ }
+
+ public function getCommentText()
+ {
+ return implode(PHP_EOL, $this->comment);
+ }
+
+ public function getComment($indent = '')
+ {
+ $comment = $indent . '/**';
+ foreach ($this->comment as $line) {
+ $comment .= PHP_EOL . rtrim($indent . ' * ' . $line);
+ }
+ $comment .= PHP_EOL . $indent . ' */';
+ return $comment;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/FactoryParameter.php b/vendor/hamcrest/hamcrest-php/generator/FactoryParameter.php
new file mode 100644
index 0000000..93a76b3
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/FactoryParameter.php
@@ -0,0 +1,69 @@
+method = $method;
+ $this->reflector = $reflector;
+ }
+
+ public function getDeclaration()
+ {
+ if ($this->reflector->isArray()) {
+ $code = 'array ';
+ } else {
+ $class = $this->reflector->getClass();
+ if ($class !== null) {
+ $code = '\\' . $class->name . ' ';
+ } else {
+ $code = '';
+ }
+ }
+ $code .= '$' . $this->reflector->name;
+ if ($this->reflector->isOptional()) {
+ $default = $this->reflector->getDefaultValue();
+ if (is_null($default)) {
+ $default = 'null';
+ } elseif (is_bool($default)) {
+ $default = $default ? 'true' : 'false';
+ } elseif (is_string($default)) {
+ $default = "'" . $default . "'";
+ } elseif (is_numeric($default)) {
+ $default = strval($default);
+ } elseif (is_array($default)) {
+ $default = 'array()';
+ } else {
+ echo 'Warning: unknown default type for ' . $this->getMethod()->getFullName() . PHP_EOL;
+ var_dump($default);
+ $default = 'null';
+ }
+ $code .= ' = ' . $default;
+ }
+ return $code;
+ }
+
+ public function getInvocation()
+ {
+ return '$' . $this->reflector->name;
+ }
+
+ public function getMethod()
+ {
+ return $this->method;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/GlobalFunctionFile.php b/vendor/hamcrest/hamcrest-php/generator/GlobalFunctionFile.php
new file mode 100644
index 0000000..5ee1b69
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/GlobalFunctionFile.php
@@ -0,0 +1,42 @@
+functions = '';
+ }
+
+ public function addCall(FactoryCall $call)
+ {
+ $this->functions .= PHP_EOL . $this->generateFactoryCall($call);
+ }
+
+ public function build()
+ {
+ $this->addFileHeader();
+ $this->addPart('functions_imports');
+ $this->addPart('functions_header');
+ $this->addCode($this->functions);
+ $this->addPart('functions_footer');
+ }
+
+ public function generateFactoryCall(FactoryCall $call)
+ {
+ $code = "if (!function_exists('{$call->getName()}')) {";
+ $code.= parent::generateFactoryCall($call);
+ $code.= "}\n";
+
+ return $code;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/StaticMethodFile.php b/vendor/hamcrest/hamcrest-php/generator/StaticMethodFile.php
new file mode 100644
index 0000000..44cec02
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/StaticMethodFile.php
@@ -0,0 +1,38 @@
+methods = '';
+ }
+
+ public function addCall(FactoryCall $call)
+ {
+ $this->methods .= PHP_EOL . $this->generateFactoryCall($call);
+ }
+
+ public function getDeclarationModifiers()
+ {
+ return 'public static ';
+ }
+
+ public function build()
+ {
+ $this->addFileHeader();
+ $this->addPart('matchers_imports');
+ $this->addPart('matchers_header');
+ $this->addCode($this->methods);
+ $this->addPart('matchers_footer');
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/parts/file_header.txt b/vendor/hamcrest/hamcrest-php/generator/parts/file_header.txt
new file mode 100644
index 0000000..7b352e4
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/parts/file_header.txt
@@ -0,0 +1,7 @@
+
+ * //With an identifier
+ * assertThat("assertion identifier", $apple->flavour(), equalTo("tasty"));
+ * //Without an identifier
+ * assertThat($apple->flavour(), equalTo("tasty"));
+ * //Evaluating a boolean expression
+ * assertThat("some error", $a > $b);
+ *
+ */
+ function assertThat()
+ {
+ $args = func_get_args();
+ call_user_func_array(
+ array('Hamcrest\MatcherAssert', 'assertThat'),
+ $args
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/parts/functions_imports.txt b/vendor/hamcrest/hamcrest-php/generator/parts/functions_imports.txt
new file mode 100644
index 0000000..e69de29
diff --git a/vendor/hamcrest/hamcrest-php/generator/parts/matchers_footer.txt b/vendor/hamcrest/hamcrest-php/generator/parts/matchers_footer.txt
new file mode 100644
index 0000000..5c34318
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/parts/matchers_footer.txt
@@ -0,0 +1 @@
+}
diff --git a/vendor/hamcrest/hamcrest-php/generator/parts/matchers_header.txt b/vendor/hamcrest/hamcrest-php/generator/parts/matchers_header.txt
new file mode 100644
index 0000000..4f8bb2b
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/parts/matchers_header.txt
@@ -0,0 +1,7 @@
+
+
+/**
+ * A series of static factories for all hamcrest matchers.
+ */
+class Matchers
+{
diff --git a/vendor/hamcrest/hamcrest-php/generator/parts/matchers_imports.txt b/vendor/hamcrest/hamcrest-php/generator/parts/matchers_imports.txt
new file mode 100644
index 0000000..7dd6849
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/parts/matchers_imports.txt
@@ -0,0 +1,2 @@
+
+namespace Hamcrest;
\ No newline at end of file
diff --git a/vendor/hamcrest/hamcrest-php/generator/run.php b/vendor/hamcrest/hamcrest-php/generator/run.php
new file mode 100644
index 0000000..924d752
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/generator/run.php
@@ -0,0 +1,37 @@
+addFactoryFile(new StaticMethodFile(STATIC_MATCHERS_FILE));
+$generator->addFactoryFile(new GlobalFunctionFile(GLOBAL_FUNCTIONS_FILE));
+$generator->generate();
+$generator->write();
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest.php
new file mode 100644
index 0000000..8a719eb
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest.php
@@ -0,0 +1,805 @@
+
+ * //With an identifier
+ * assertThat("assertion identifier", $apple->flavour(), equalTo("tasty"));
+ * //Without an identifier
+ * assertThat($apple->flavour(), equalTo("tasty"));
+ * //Evaluating a boolean expression
+ * assertThat("some error", $a > $b);
+ *
+ */
+ function assertThat()
+ {
+ $args = func_get_args();
+ call_user_func_array(
+ array('Hamcrest\MatcherAssert', 'assertThat'),
+ $args
+ );
+ }
+}
+
+if (!function_exists('anArray')) { /**
+ * Evaluates to true only if each $matcher[$i] is satisfied by $array[$i].
+ */
+ function anArray(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Arrays\IsArray', 'anArray'), $args);
+ }
+}
+
+if (!function_exists('hasItemInArray')) { /**
+ * Evaluates to true if any item in an array satisfies the given matcher.
+ *
+ * @param mixed $item as a {@link Hamcrest\Matcher} or a value.
+ *
+ * @return \Hamcrest\Arrays\IsArrayContaining
+ */
+ function hasItemInArray($item)
+ {
+ return \Hamcrest\Arrays\IsArrayContaining::hasItemInArray($item);
+ }
+}
+
+if (!function_exists('hasValue')) { /**
+ * Evaluates to true if any item in an array satisfies the given matcher.
+ *
+ * @param mixed $item as a {@link Hamcrest\Matcher} or a value.
+ *
+ * @return \Hamcrest\Arrays\IsArrayContaining
+ */
+ function hasValue($item)
+ {
+ return \Hamcrest\Arrays\IsArrayContaining::hasItemInArray($item);
+ }
+}
+
+if (!function_exists('arrayContainingInAnyOrder')) { /**
+ * An array with elements that match the given matchers.
+ */
+ function arrayContainingInAnyOrder(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);
+ }
+}
+
+if (!function_exists('containsInAnyOrder')) { /**
+ * An array with elements that match the given matchers.
+ */
+ function containsInAnyOrder(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);
+ }
+}
+
+if (!function_exists('arrayContaining')) { /**
+ * An array with elements that match the given matchers in the same order.
+ */
+ function arrayContaining(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInOrder', 'arrayContaining'), $args);
+ }
+}
+
+if (!function_exists('contains')) { /**
+ * An array with elements that match the given matchers in the same order.
+ */
+ function contains(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInOrder', 'arrayContaining'), $args);
+ }
+}
+
+if (!function_exists('hasKeyInArray')) { /**
+ * Evaluates to true if any key in an array matches the given matcher.
+ *
+ * @param mixed $key as a {@link Hamcrest\Matcher} or a value.
+ *
+ * @return \Hamcrest\Arrays\IsArrayContainingKey
+ */
+ function hasKeyInArray($key)
+ {
+ return \Hamcrest\Arrays\IsArrayContainingKey::hasKeyInArray($key);
+ }
+}
+
+if (!function_exists('hasKey')) { /**
+ * Evaluates to true if any key in an array matches the given matcher.
+ *
+ * @param mixed $key as a {@link Hamcrest\Matcher} or a value.
+ *
+ * @return \Hamcrest\Arrays\IsArrayContainingKey
+ */
+ function hasKey($key)
+ {
+ return \Hamcrest\Arrays\IsArrayContainingKey::hasKeyInArray($key);
+ }
+}
+
+if (!function_exists('hasKeyValuePair')) { /**
+ * Test if an array has both an key and value in parity with each other.
+ */
+ function hasKeyValuePair($key, $value)
+ {
+ return \Hamcrest\Arrays\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);
+ }
+}
+
+if (!function_exists('hasEntry')) { /**
+ * Test if an array has both an key and value in parity with each other.
+ */
+ function hasEntry($key, $value)
+ {
+ return \Hamcrest\Arrays\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);
+ }
+}
+
+if (!function_exists('arrayWithSize')) { /**
+ * Does array size satisfy a given matcher?
+ *
+ * @param \Hamcrest\Matcher|int $size as a {@link Hamcrest\Matcher} or a value.
+ *
+ * @return \Hamcrest\Arrays\IsArrayWithSize
+ */
+ function arrayWithSize($size)
+ {
+ return \Hamcrest\Arrays\IsArrayWithSize::arrayWithSize($size);
+ }
+}
+
+if (!function_exists('emptyArray')) { /**
+ * Matches an empty array.
+ */
+ function emptyArray()
+ {
+ return \Hamcrest\Arrays\IsArrayWithSize::emptyArray();
+ }
+}
+
+if (!function_exists('nonEmptyArray')) { /**
+ * Matches an empty array.
+ */
+ function nonEmptyArray()
+ {
+ return \Hamcrest\Arrays\IsArrayWithSize::nonEmptyArray();
+ }
+}
+
+if (!function_exists('emptyTraversable')) { /**
+ * Returns true if traversable is empty.
+ */
+ function emptyTraversable()
+ {
+ return \Hamcrest\Collection\IsEmptyTraversable::emptyTraversable();
+ }
+}
+
+if (!function_exists('nonEmptyTraversable')) { /**
+ * Returns true if traversable is not empty.
+ */
+ function nonEmptyTraversable()
+ {
+ return \Hamcrest\Collection\IsEmptyTraversable::nonEmptyTraversable();
+ }
+}
+
+if (!function_exists('traversableWithSize')) { /**
+ * Does traversable size satisfy a given matcher?
+ */
+ function traversableWithSize($size)
+ {
+ return \Hamcrest\Collection\IsTraversableWithSize::traversableWithSize($size);
+ }
+}
+
+if (!function_exists('allOf')) { /**
+ * Evaluates to true only if ALL of the passed in matchers evaluate to true.
+ */
+ function allOf(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Core\AllOf', 'allOf'), $args);
+ }
+}
+
+if (!function_exists('anyOf')) { /**
+ * Evaluates to true if ANY of the passed in matchers evaluate to true.
+ */
+ function anyOf(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Core\AnyOf', 'anyOf'), $args);
+ }
+}
+
+if (!function_exists('noneOf')) { /**
+ * Evaluates to false if ANY of the passed in matchers evaluate to true.
+ */
+ function noneOf(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Core\AnyOf', 'noneOf'), $args);
+ }
+}
+
+if (!function_exists('both')) { /**
+ * This is useful for fluently combining matchers that must both pass.
+ * For example:
+ *
+ * assertThat($string, both(containsString("a"))->andAlso(containsString("b")));
+ *
+ */
+ function both(\Hamcrest\Matcher $matcher)
+ {
+ return \Hamcrest\Core\CombinableMatcher::both($matcher);
+ }
+}
+
+if (!function_exists('either')) { /**
+ * This is useful for fluently combining matchers where either may pass,
+ * for example:
+ *
+ * assertThat($string, either(containsString("a"))->orElse(containsString("b")));
+ *
+ */
+ function either(\Hamcrest\Matcher $matcher)
+ {
+ return \Hamcrest\Core\CombinableMatcher::either($matcher);
+ }
+}
+
+if (!function_exists('describedAs')) { /**
+ * Wraps an existing matcher and overrides the description when it fails.
+ */
+ function describedAs(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Core\DescribedAs', 'describedAs'), $args);
+ }
+}
+
+if (!function_exists('everyItem')) { /**
+ * @param Matcher $itemMatcher
+ * A matcher to apply to every element in an array.
+ *
+ * @return \Hamcrest\Core\Every
+ * Evaluates to TRUE for a collection in which every item matches $itemMatcher
+ */
+ function everyItem(\Hamcrest\Matcher $itemMatcher)
+ {
+ return \Hamcrest\Core\Every::everyItem($itemMatcher);
+ }
+}
+
+if (!function_exists('hasToString')) { /**
+ * Does array size satisfy a given matcher?
+ */
+ function hasToString($matcher)
+ {
+ return \Hamcrest\Core\HasToString::hasToString($matcher);
+ }
+}
+
+if (!function_exists('is')) { /**
+ * Decorates another Matcher, retaining the behavior but allowing tests
+ * to be slightly more expressive.
+ *
+ * For example: assertThat($cheese, equalTo($smelly))
+ * vs. assertThat($cheese, is(equalTo($smelly)))
+ */
+ function is($value)
+ {
+ return \Hamcrest\Core\Is::is($value);
+ }
+}
+
+if (!function_exists('anything')) { /**
+ * This matcher always evaluates to true.
+ *
+ * @param string $description A meaningful string used when describing itself.
+ *
+ * @return \Hamcrest\Core\IsAnything
+ */
+ function anything($description = 'ANYTHING')
+ {
+ return \Hamcrest\Core\IsAnything::anything($description);
+ }
+}
+
+if (!function_exists('hasItem')) { /**
+ * Test if the value is an array containing this matcher.
+ *
+ * Example:
+ *
+ * assertThat(array('a', 'b'), hasItem(equalTo('b')));
+ * //Convenience defaults to equalTo()
+ * assertThat(array('a', 'b'), hasItem('b'));
+ *
+ */
+ function hasItem(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItem'), $args);
+ }
+}
+
+if (!function_exists('hasItems')) { /**
+ * Test if the value is an array containing elements that match all of these
+ * matchers.
+ *
+ * Example:
+ *
+ * assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));
+ *
+ */
+ function hasItems(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItems'), $args);
+ }
+}
+
+if (!function_exists('equalTo')) { /**
+ * Is the value equal to another value, as tested by the use of the "=="
+ * comparison operator?
+ */
+ function equalTo($item)
+ {
+ return \Hamcrest\Core\IsEqual::equalTo($item);
+ }
+}
+
+if (!function_exists('identicalTo')) { /**
+ * Tests of the value is identical to $value as tested by the "===" operator.
+ */
+ function identicalTo($value)
+ {
+ return \Hamcrest\Core\IsIdentical::identicalTo($value);
+ }
+}
+
+if (!function_exists('anInstanceOf')) { /**
+ * Is the value an instance of a particular type?
+ * This version assumes no relationship between the required type and
+ * the signature of the method that sets it up, for example in
+ * assertThat($anObject, anInstanceOf('Thing'));
+ */
+ function anInstanceOf($theClass)
+ {
+ return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass);
+ }
+}
+
+if (!function_exists('any')) { /**
+ * Is the value an instance of a particular type?
+ * This version assumes no relationship between the required type and
+ * the signature of the method that sets it up, for example in
+ * assertThat($anObject, anInstanceOf('Thing'));
+ */
+ function any($theClass)
+ {
+ return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass);
+ }
+}
+
+if (!function_exists('not')) { /**
+ * Matches if value does not match $value.
+ */
+ function not($value)
+ {
+ return \Hamcrest\Core\IsNot::not($value);
+ }
+}
+
+if (!function_exists('nullValue')) { /**
+ * Matches if value is null.
+ */
+ function nullValue()
+ {
+ return \Hamcrest\Core\IsNull::nullValue();
+ }
+}
+
+if (!function_exists('notNullValue')) { /**
+ * Matches if value is not null.
+ */
+ function notNullValue()
+ {
+ return \Hamcrest\Core\IsNull::notNullValue();
+ }
+}
+
+if (!function_exists('sameInstance')) { /**
+ * Creates a new instance of IsSame.
+ *
+ * @param mixed $object
+ * The predicate evaluates to true only when the argument is
+ * this object.
+ *
+ * @return \Hamcrest\Core\IsSame
+ */
+ function sameInstance($object)
+ {
+ return \Hamcrest\Core\IsSame::sameInstance($object);
+ }
+}
+
+if (!function_exists('typeOf')) { /**
+ * Is the value a particular built-in type?
+ */
+ function typeOf($theType)
+ {
+ return \Hamcrest\Core\IsTypeOf::typeOf($theType);
+ }
+}
+
+if (!function_exists('set')) { /**
+ * Matches if value (class, object, or array) has named $property.
+ */
+ function set($property)
+ {
+ return \Hamcrest\Core\Set::set($property);
+ }
+}
+
+if (!function_exists('notSet')) { /**
+ * Matches if value (class, object, or array) does not have named $property.
+ */
+ function notSet($property)
+ {
+ return \Hamcrest\Core\Set::notSet($property);
+ }
+}
+
+if (!function_exists('closeTo')) { /**
+ * Matches if value is a number equal to $value within some range of
+ * acceptable error $delta.
+ */
+ function closeTo($value, $delta)
+ {
+ return \Hamcrest\Number\IsCloseTo::closeTo($value, $delta);
+ }
+}
+
+if (!function_exists('comparesEqualTo')) { /**
+ * The value is not > $value, nor < $value.
+ */
+ function comparesEqualTo($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::comparesEqualTo($value);
+ }
+}
+
+if (!function_exists('greaterThan')) { /**
+ * The value is > $value.
+ */
+ function greaterThan($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::greaterThan($value);
+ }
+}
+
+if (!function_exists('greaterThanOrEqualTo')) { /**
+ * The value is >= $value.
+ */
+ function greaterThanOrEqualTo($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value);
+ }
+}
+
+if (!function_exists('atLeast')) { /**
+ * The value is >= $value.
+ */
+ function atLeast($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value);
+ }
+}
+
+if (!function_exists('lessThan')) { /**
+ * The value is < $value.
+ */
+ function lessThan($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::lessThan($value);
+ }
+}
+
+if (!function_exists('lessThanOrEqualTo')) { /**
+ * The value is <= $value.
+ */
+ function lessThanOrEqualTo($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value);
+ }
+}
+
+if (!function_exists('atMost')) { /**
+ * The value is <= $value.
+ */
+ function atMost($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value);
+ }
+}
+
+if (!function_exists('isEmptyString')) { /**
+ * Matches if value is a zero-length string.
+ */
+ function isEmptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isEmptyString();
+ }
+}
+
+if (!function_exists('emptyString')) { /**
+ * Matches if value is a zero-length string.
+ */
+ function emptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isEmptyString();
+ }
+}
+
+if (!function_exists('isEmptyOrNullString')) { /**
+ * Matches if value is null or a zero-length string.
+ */
+ function isEmptyOrNullString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString();
+ }
+}
+
+if (!function_exists('nullOrEmptyString')) { /**
+ * Matches if value is null or a zero-length string.
+ */
+ function nullOrEmptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString();
+ }
+}
+
+if (!function_exists('isNonEmptyString')) { /**
+ * Matches if value is a non-zero-length string.
+ */
+ function isNonEmptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isNonEmptyString();
+ }
+}
+
+if (!function_exists('nonEmptyString')) { /**
+ * Matches if value is a non-zero-length string.
+ */
+ function nonEmptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isNonEmptyString();
+ }
+}
+
+if (!function_exists('equalToIgnoringCase')) { /**
+ * Matches if value is a string equal to $string, regardless of the case.
+ */
+ function equalToIgnoringCase($string)
+ {
+ return \Hamcrest\Text\IsEqualIgnoringCase::equalToIgnoringCase($string);
+ }
+}
+
+if (!function_exists('equalToIgnoringWhiteSpace')) { /**
+ * Matches if value is a string equal to $string, regardless of whitespace.
+ */
+ function equalToIgnoringWhiteSpace($string)
+ {
+ return \Hamcrest\Text\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace($string);
+ }
+}
+
+if (!function_exists('matchesPattern')) { /**
+ * Matches if value is a string that matches regular expression $pattern.
+ */
+ function matchesPattern($pattern)
+ {
+ return \Hamcrest\Text\MatchesPattern::matchesPattern($pattern);
+ }
+}
+
+if (!function_exists('containsString')) { /**
+ * Matches if value is a string that contains $substring.
+ */
+ function containsString($substring)
+ {
+ return \Hamcrest\Text\StringContains::containsString($substring);
+ }
+}
+
+if (!function_exists('containsStringIgnoringCase')) { /**
+ * Matches if value is a string that contains $substring regardless of the case.
+ */
+ function containsStringIgnoringCase($substring)
+ {
+ return \Hamcrest\Text\StringContainsIgnoringCase::containsStringIgnoringCase($substring);
+ }
+}
+
+if (!function_exists('stringContainsInOrder')) { /**
+ * Matches if value contains $substrings in a constrained order.
+ */
+ function stringContainsInOrder(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Text\StringContainsInOrder', 'stringContainsInOrder'), $args);
+ }
+}
+
+if (!function_exists('endsWith')) { /**
+ * Matches if value is a string that ends with $substring.
+ */
+ function endsWith($substring)
+ {
+ return \Hamcrest\Text\StringEndsWith::endsWith($substring);
+ }
+}
+
+if (!function_exists('startsWith')) { /**
+ * Matches if value is a string that starts with $substring.
+ */
+ function startsWith($substring)
+ {
+ return \Hamcrest\Text\StringStartsWith::startsWith($substring);
+ }
+}
+
+if (!function_exists('arrayValue')) { /**
+ * Is the value an array?
+ */
+ function arrayValue()
+ {
+ return \Hamcrest\Type\IsArray::arrayValue();
+ }
+}
+
+if (!function_exists('booleanValue')) { /**
+ * Is the value a boolean?
+ */
+ function booleanValue()
+ {
+ return \Hamcrest\Type\IsBoolean::booleanValue();
+ }
+}
+
+if (!function_exists('boolValue')) { /**
+ * Is the value a boolean?
+ */
+ function boolValue()
+ {
+ return \Hamcrest\Type\IsBoolean::booleanValue();
+ }
+}
+
+if (!function_exists('callableValue')) { /**
+ * Is the value callable?
+ */
+ function callableValue()
+ {
+ return \Hamcrest\Type\IsCallable::callableValue();
+ }
+}
+
+if (!function_exists('doubleValue')) { /**
+ * Is the value a float/double?
+ */
+ function doubleValue()
+ {
+ return \Hamcrest\Type\IsDouble::doubleValue();
+ }
+}
+
+if (!function_exists('floatValue')) { /**
+ * Is the value a float/double?
+ */
+ function floatValue()
+ {
+ return \Hamcrest\Type\IsDouble::doubleValue();
+ }
+}
+
+if (!function_exists('integerValue')) { /**
+ * Is the value an integer?
+ */
+ function integerValue()
+ {
+ return \Hamcrest\Type\IsInteger::integerValue();
+ }
+}
+
+if (!function_exists('intValue')) { /**
+ * Is the value an integer?
+ */
+ function intValue()
+ {
+ return \Hamcrest\Type\IsInteger::integerValue();
+ }
+}
+
+if (!function_exists('numericValue')) { /**
+ * Is the value a numeric?
+ */
+ function numericValue()
+ {
+ return \Hamcrest\Type\IsNumeric::numericValue();
+ }
+}
+
+if (!function_exists('objectValue')) { /**
+ * Is the value an object?
+ */
+ function objectValue()
+ {
+ return \Hamcrest\Type\IsObject::objectValue();
+ }
+}
+
+if (!function_exists('anObject')) { /**
+ * Is the value an object?
+ */
+ function anObject()
+ {
+ return \Hamcrest\Type\IsObject::objectValue();
+ }
+}
+
+if (!function_exists('resourceValue')) { /**
+ * Is the value a resource?
+ */
+ function resourceValue()
+ {
+ return \Hamcrest\Type\IsResource::resourceValue();
+ }
+}
+
+if (!function_exists('scalarValue')) { /**
+ * Is the value a scalar (boolean, integer, double, or string)?
+ */
+ function scalarValue()
+ {
+ return \Hamcrest\Type\IsScalar::scalarValue();
+ }
+}
+
+if (!function_exists('stringValue')) { /**
+ * Is the value a string?
+ */
+ function stringValue()
+ {
+ return \Hamcrest\Type\IsString::stringValue();
+ }
+}
+
+if (!function_exists('hasXPath')) { /**
+ * Wraps $matcher
with {@link Hamcrest\Core\IsEqual)
+ * if it's not a matcher and the XPath in count()
+ * if it's an integer.
+ */
+ function hasXPath($xpath, $matcher = null)
+ {
+ return \Hamcrest\Xml\HasXPath::hasXPath($xpath, $matcher);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArray.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArray.php
new file mode 100644
index 0000000..9ea5697
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArray.php
@@ -0,0 +1,118 @@
+_elementMatchers = $elementMatchers;
+ }
+
+ protected function matchesSafely($array)
+ {
+ if (array_keys($array) != array_keys($this->_elementMatchers)) {
+ return false;
+ }
+
+ /** @var $matcher \Hamcrest\Matcher */
+ foreach ($this->_elementMatchers as $k => $matcher) {
+ if (!$matcher->matches($array[$k])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected function describeMismatchSafely($actual, Description $mismatchDescription)
+ {
+ if (count($actual) != count($this->_elementMatchers)) {
+ $mismatchDescription->appendText('array length was ' . count($actual));
+
+ return;
+ } elseif (array_keys($actual) != array_keys($this->_elementMatchers)) {
+ $mismatchDescription->appendText('array keys were ')
+ ->appendValueList(
+ $this->descriptionStart(),
+ $this->descriptionSeparator(),
+ $this->descriptionEnd(),
+ array_keys($actual)
+ )
+ ;
+
+ return;
+ }
+
+ /** @var $matcher \Hamcrest\Matcher */
+ foreach ($this->_elementMatchers as $k => $matcher) {
+ if (!$matcher->matches($actual[$k])) {
+ $mismatchDescription->appendText('element ')->appendValue($k)
+ ->appendText(' was ')->appendValue($actual[$k]);
+
+ return;
+ }
+ }
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendList(
+ $this->descriptionStart(),
+ $this->descriptionSeparator(),
+ $this->descriptionEnd(),
+ $this->_elementMatchers
+ );
+ }
+
+ /**
+ * Evaluates to true only if each $matcher[$i] is satisfied by $array[$i].
+ *
+ * @factory ...
+ */
+ public static function anArray(/* args... */)
+ {
+ $args = func_get_args();
+
+ return new self(Util::createMatcherArray($args));
+ }
+
+ // -- Protected Methods
+
+ protected function descriptionStart()
+ {
+ return '[';
+ }
+
+ protected function descriptionSeparator()
+ {
+ return ', ';
+ }
+
+ protected function descriptionEnd()
+ {
+ return ']';
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContaining.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContaining.php
new file mode 100644
index 0000000..0e4a1ed
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContaining.php
@@ -0,0 +1,63 @@
+_elementMatcher = $elementMatcher;
+ }
+
+ protected function matchesSafely($array)
+ {
+ foreach ($array as $element) {
+ if ($this->_elementMatcher->matches($element)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected function describeMismatchSafely($array, Description $mismatchDescription)
+ {
+ $mismatchDescription->appendText('was ')->appendValue($array);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description
+ ->appendText('an array containing ')
+ ->appendDescriptionOf($this->_elementMatcher)
+ ;
+ }
+
+ /**
+ * Evaluates to true if any item in an array satisfies the given matcher.
+ *
+ * @param mixed $item as a {@link Hamcrest\Matcher} or a value.
+ *
+ * @return \Hamcrest\Arrays\IsArrayContaining
+ * @factory hasValue
+ */
+ public static function hasItemInArray($item)
+ {
+ return new self(Util::wrapValueWithIsEqual($item));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInAnyOrder.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInAnyOrder.php
new file mode 100644
index 0000000..9009026
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInAnyOrder.php
@@ -0,0 +1,59 @@
+_elementMatchers = $elementMatchers;
+ }
+
+ protected function matchesSafelyWithDiagnosticDescription($array, Description $mismatchDescription)
+ {
+ $matching = new MatchingOnce($this->_elementMatchers, $mismatchDescription);
+
+ foreach ($array as $element) {
+ if (!$matching->matches($element)) {
+ return false;
+ }
+ }
+
+ return $matching->isFinished($array);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendList('[', ', ', ']', $this->_elementMatchers)
+ ->appendText(' in any order')
+ ;
+ }
+
+ /**
+ * An array with elements that match the given matchers.
+ *
+ * @factory containsInAnyOrder ...
+ */
+ public static function arrayContainingInAnyOrder(/* args... */)
+ {
+ $args = func_get_args();
+
+ return new self(Util::createMatcherArray($args));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInOrder.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInOrder.php
new file mode 100644
index 0000000..6115740
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingInOrder.php
@@ -0,0 +1,57 @@
+_elementMatchers = $elementMatchers;
+ }
+
+ protected function matchesSafelyWithDiagnosticDescription($array, Description $mismatchDescription)
+ {
+ $series = new SeriesMatchingOnce($this->_elementMatchers, $mismatchDescription);
+
+ foreach ($array as $element) {
+ if (!$series->matches($element)) {
+ return false;
+ }
+ }
+
+ return $series->isFinished();
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendList('[', ', ', ']', $this->_elementMatchers);
+ }
+
+ /**
+ * An array with elements that match the given matchers in the same order.
+ *
+ * @factory contains ...
+ */
+ public static function arrayContaining(/* args... */)
+ {
+ $args = func_get_args();
+
+ return new self(Util::createMatcherArray($args));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKey.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKey.php
new file mode 100644
index 0000000..523477e
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKey.php
@@ -0,0 +1,75 @@
+_keyMatcher = $keyMatcher;
+ }
+
+ protected function matchesSafely($array)
+ {
+ foreach ($array as $key => $element) {
+ if ($this->_keyMatcher->matches($key)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected function describeMismatchSafely($array, Description $mismatchDescription)
+ {
+ //Not using appendValueList() so that keys can be shown
+ $mismatchDescription->appendText('array was ')
+ ->appendText('[')
+ ;
+ $loop = false;
+ foreach ($array as $key => $value) {
+ if ($loop) {
+ $mismatchDescription->appendText(', ');
+ }
+ $mismatchDescription->appendValue($key)->appendText(' => ')->appendValue($value);
+ $loop = true;
+ }
+ $mismatchDescription->appendText(']');
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description
+ ->appendText('array with key ')
+ ->appendDescriptionOf($this->_keyMatcher)
+ ;
+ }
+
+ /**
+ * Evaluates to true if any key in an array matches the given matcher.
+ *
+ * @param mixed $key as a {@link Hamcrest\Matcher} or a value.
+ *
+ * @return \Hamcrest\Arrays\IsArrayContainingKey
+ * @factory hasKey
+ */
+ public static function hasKeyInArray($key)
+ {
+ return new self(Util::wrapValueWithIsEqual($key));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKeyValuePair.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKeyValuePair.php
new file mode 100644
index 0000000..9ac3eba
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayContainingKeyValuePair.php
@@ -0,0 +1,80 @@
+_keyMatcher = $keyMatcher;
+ $this->_valueMatcher = $valueMatcher;
+ }
+
+ protected function matchesSafely($array)
+ {
+ foreach ($array as $key => $value) {
+ if ($this->_keyMatcher->matches($key) && $this->_valueMatcher->matches($value)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected function describeMismatchSafely($array, Description $mismatchDescription)
+ {
+ //Not using appendValueList() so that keys can be shown
+ $mismatchDescription->appendText('array was ')
+ ->appendText('[')
+ ;
+ $loop = false;
+ foreach ($array as $key => $value) {
+ if ($loop) {
+ $mismatchDescription->appendText(', ');
+ }
+ $mismatchDescription->appendValue($key)->appendText(' => ')->appendValue($value);
+ $loop = true;
+ }
+ $mismatchDescription->appendText(']');
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('array containing [')
+ ->appendDescriptionOf($this->_keyMatcher)
+ ->appendText(' => ')
+ ->appendDescriptionOf($this->_valueMatcher)
+ ->appendText(']')
+ ;
+ }
+
+ /**
+ * Test if an array has both an key and value in parity with each other.
+ *
+ * @factory hasEntry
+ */
+ public static function hasKeyValuePair($key, $value)
+ {
+ return new self(
+ Util::wrapValueWithIsEqual($key),
+ Util::wrapValueWithIsEqual($value)
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayWithSize.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayWithSize.php
new file mode 100644
index 0000000..074375c
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/IsArrayWithSize.php
@@ -0,0 +1,73 @@
+_elementMatchers = $elementMatchers;
+ $this->_mismatchDescription = $mismatchDescription;
+ }
+
+ public function matches($item)
+ {
+ return $this->_isNotSurplus($item) && $this->_isMatched($item);
+ }
+
+ public function isFinished($items)
+ {
+ if (empty($this->_elementMatchers)) {
+ return true;
+ }
+
+ $this->_mismatchDescription
+ ->appendText('No item matches: ')->appendList('', ', ', '', $this->_elementMatchers)
+ ->appendText(' in ')->appendValueList('[', ', ', ']', $items)
+ ;
+
+ return false;
+ }
+
+ // -- Private Methods
+
+ private function _isNotSurplus($item)
+ {
+ if (empty($this->_elementMatchers)) {
+ $this->_mismatchDescription->appendText('Not matched: ')->appendValue($item);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ private function _isMatched($item)
+ {
+ /** @var $matcher \Hamcrest\Matcher */
+ foreach ($this->_elementMatchers as $i => $matcher) {
+ if ($matcher->matches($item)) {
+ unset($this->_elementMatchers[$i]);
+
+ return true;
+ }
+ }
+
+ $this->_mismatchDescription->appendText('Not matched: ')->appendValue($item);
+
+ return false;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/SeriesMatchingOnce.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/SeriesMatchingOnce.php
new file mode 100644
index 0000000..12a912d
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Arrays/SeriesMatchingOnce.php
@@ -0,0 +1,75 @@
+_elementMatchers = $elementMatchers;
+ $this->_keys = array_keys($elementMatchers);
+ $this->_mismatchDescription = $mismatchDescription;
+ }
+
+ public function matches($item)
+ {
+ return $this->_isNotSurplus($item) && $this->_isMatched($item);
+ }
+
+ public function isFinished()
+ {
+ if (!empty($this->_elementMatchers)) {
+ $nextMatcher = current($this->_elementMatchers);
+ $this->_mismatchDescription->appendText('No item matched: ')->appendDescriptionOf($nextMatcher);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ // -- Private Methods
+
+ private function _isNotSurplus($item)
+ {
+ if (empty($this->_elementMatchers)) {
+ $this->_mismatchDescription->appendText('Not matched: ')->appendValue($item);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ private function _isMatched($item)
+ {
+ $this->_nextMatchKey = array_shift($this->_keys);
+ $nextMatcher = array_shift($this->_elementMatchers);
+
+ if (!$nextMatcher->matches($item)) {
+ $this->_describeMismatch($nextMatcher, $item);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ private function _describeMismatch(Matcher $matcher, $item)
+ {
+ $this->_mismatchDescription->appendText('item with key ' . $this->_nextMatchKey . ': ');
+ $matcher->describeMismatch($item, $this->_mismatchDescription);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/AssertionError.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/AssertionError.php
new file mode 100644
index 0000000..3a2a0e7
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/AssertionError.php
@@ -0,0 +1,10 @@
+append($text);
+
+ return $this;
+ }
+
+ public function appendDescriptionOf(SelfDescribing $value)
+ {
+ $value->describeTo($this);
+
+ return $this;
+ }
+
+ public function appendValue($value)
+ {
+ if (is_null($value)) {
+ $this->append('null');
+ } elseif (is_string($value)) {
+ $this->_toPhpSyntax($value);
+ } elseif (is_float($value)) {
+ $this->append('<');
+ $this->append($value);
+ $this->append('F>');
+ } elseif (is_bool($value)) {
+ $this->append('<');
+ $this->append($value ? 'true' : 'false');
+ $this->append('>');
+ } elseif (is_array($value) || $value instanceof \Iterator || $value instanceof \IteratorAggregate) {
+ $this->appendValueList('[', ', ', ']', $value);
+ } elseif (is_object($value) && !method_exists($value, '__toString')) {
+ $this->append('<');
+ $this->append(get_class($value));
+ $this->append('>');
+ } else {
+ $this->append('<');
+ $this->append($value);
+ $this->append('>');
+ }
+
+ return $this;
+ }
+
+ public function appendValueList($start, $separator, $end, $values)
+ {
+ $list = array();
+ foreach ($values as $v) {
+ $list[] = new SelfDescribingValue($v);
+ }
+
+ $this->appendList($start, $separator, $end, $list);
+
+ return $this;
+ }
+
+ public function appendList($start, $separator, $end, $values)
+ {
+ $this->append($start);
+
+ $separate = false;
+
+ foreach ($values as $value) {
+ /*if (!($value instanceof Hamcrest\SelfDescribing)) {
+ $value = new Hamcrest\Internal\SelfDescribingValue($value);
+ }*/
+
+ if ($separate) {
+ $this->append($separator);
+ }
+
+ $this->appendDescriptionOf($value);
+
+ $separate = true;
+ }
+
+ $this->append($end);
+
+ return $this;
+ }
+
+ // -- Protected Methods
+
+ /**
+ * Append the String $str to the description.
+ */
+ abstract protected function append($str);
+
+ // -- Private Methods
+
+ private function _toPhpSyntax($value)
+ {
+ $str = '"';
+ for ($i = 0, $len = strlen($value); $i < $len; ++$i) {
+ switch ($value[$i]) {
+ case '"':
+ $str .= '\\"';
+ break;
+
+ case "\t":
+ $str .= '\\t';
+ break;
+
+ case "\r":
+ $str .= '\\r';
+ break;
+
+ case "\n":
+ $str .= '\\n';
+ break;
+
+ default:
+ $str .= $value[$i];
+ }
+ }
+ $str .= '"';
+ $this->append($str);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/BaseMatcher.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/BaseMatcher.php
new file mode 100644
index 0000000..286db3e
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/BaseMatcher.php
@@ -0,0 +1,25 @@
+appendText('was ')->appendValue($item);
+ }
+
+ public function __toString()
+ {
+ return StringDescription::toString($this);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsEmptyTraversable.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsEmptyTraversable.php
new file mode 100644
index 0000000..8ab58ea
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsEmptyTraversable.php
@@ -0,0 +1,71 @@
+_empty = $empty;
+ }
+
+ public function matches($item)
+ {
+ if (!$item instanceof \Traversable) {
+ return false;
+ }
+
+ foreach ($item as $value) {
+ return !$this->_empty;
+ }
+
+ return $this->_empty;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText($this->_empty ? 'an empty traversable' : 'a non-empty traversable');
+ }
+
+ /**
+ * Returns true if traversable is empty.
+ *
+ * @factory
+ */
+ public static function emptyTraversable()
+ {
+ if (!self::$_INSTANCE) {
+ self::$_INSTANCE = new self;
+ }
+
+ return self::$_INSTANCE;
+ }
+
+ /**
+ * Returns true if traversable is not empty.
+ *
+ * @factory
+ */
+ public static function nonEmptyTraversable()
+ {
+ if (!self::$_NOT_INSTANCE) {
+ self::$_NOT_INSTANCE = new self(false);
+ }
+
+ return self::$_NOT_INSTANCE;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsTraversableWithSize.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsTraversableWithSize.php
new file mode 100644
index 0000000..c95edc5
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Collection/IsTraversableWithSize.php
@@ -0,0 +1,47 @@
+false.
+ */
+class AllOf extends DiagnosingMatcher
+{
+
+ private $_matchers;
+
+ public function __construct(array $matchers)
+ {
+ Util::checkAllAreMatchers($matchers);
+
+ $this->_matchers = $matchers;
+ }
+
+ public function matchesWithDiagnosticDescription($item, Description $mismatchDescription)
+ {
+ /** @var $matcher \Hamcrest\Matcher */
+ foreach ($this->_matchers as $matcher) {
+ if (!$matcher->matches($item)) {
+ $mismatchDescription->appendDescriptionOf($matcher)->appendText(' ');
+ $matcher->describeMismatch($item, $mismatchDescription);
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendList('(', ' and ', ')', $this->_matchers);
+ }
+
+ /**
+ * Evaluates to true only if ALL of the passed in matchers evaluate to true.
+ *
+ * @factory ...
+ */
+ public static function allOf(/* args... */)
+ {
+ $args = func_get_args();
+
+ return new self(Util::createMatcherArray($args));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/AnyOf.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/AnyOf.php
new file mode 100644
index 0000000..4504279
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/AnyOf.php
@@ -0,0 +1,58 @@
+true.
+ */
+class AnyOf extends ShortcutCombination
+{
+
+ public function __construct(array $matchers)
+ {
+ parent::__construct($matchers);
+ }
+
+ public function matches($item)
+ {
+ return $this->matchesWithShortcut($item, true);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $this->describeToWithOperator($description, 'or');
+ }
+
+ /**
+ * Evaluates to true if ANY of the passed in matchers evaluate to true.
+ *
+ * @factory ...
+ */
+ public static function anyOf(/* args... */)
+ {
+ $args = func_get_args();
+
+ return new self(Util::createMatcherArray($args));
+ }
+
+ /**
+ * Evaluates to false if ANY of the passed in matchers evaluate to true.
+ *
+ * @factory ...
+ */
+ public static function noneOf(/* args... */)
+ {
+ $args = func_get_args();
+
+ return IsNot::not(
+ new self(Util::createMatcherArray($args))
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/CombinableMatcher.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/CombinableMatcher.php
new file mode 100644
index 0000000..e3b4aa7
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/CombinableMatcher.php
@@ -0,0 +1,78 @@
+_matcher = $matcher;
+ }
+
+ public function matches($item)
+ {
+ return $this->_matcher->matches($item);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendDescriptionOf($this->_matcher);
+ }
+
+ /** Diversion from Hamcrest-Java... Logical "and" not permitted */
+ public function andAlso(Matcher $other)
+ {
+ return new self(new AllOf($this->_templatedListWith($other)));
+ }
+
+ /** Diversion from Hamcrest-Java... Logical "or" not permitted */
+ public function orElse(Matcher $other)
+ {
+ return new self(new AnyOf($this->_templatedListWith($other)));
+ }
+
+ /**
+ * This is useful for fluently combining matchers that must both pass.
+ * For example:
+ *
+ * assertThat($string, both(containsString("a"))->andAlso(containsString("b")));
+ *
+ *
+ * @factory
+ */
+ public static function both(Matcher $matcher)
+ {
+ return new self($matcher);
+ }
+
+ /**
+ * This is useful for fluently combining matchers where either may pass,
+ * for example:
+ *
+ * assertThat($string, either(containsString("a"))->orElse(containsString("b")));
+ *
+ *
+ * @factory
+ */
+ public static function either(Matcher $matcher)
+ {
+ return new self($matcher);
+ }
+
+ // -- Private Methods
+
+ private function _templatedListWith(Matcher $other)
+ {
+ return array($this->_matcher, $other);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/DescribedAs.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/DescribedAs.php
new file mode 100644
index 0000000..5b2583f
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/DescribedAs.php
@@ -0,0 +1,68 @@
+_descriptionTemplate = $descriptionTemplate;
+ $this->_matcher = $matcher;
+ $this->_values = $values;
+ }
+
+ public function matches($item)
+ {
+ return $this->_matcher->matches($item);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $textStart = 0;
+ while (preg_match(self::ARG_PATTERN, $this->_descriptionTemplate, $matches, PREG_OFFSET_CAPTURE, $textStart)) {
+ $text = $matches[0][0];
+ $index = $matches[1][0];
+ $offset = $matches[0][1];
+
+ $description->appendText(substr($this->_descriptionTemplate, $textStart, $offset - $textStart));
+ $description->appendValue($this->_values[$index]);
+
+ $textStart = $offset + strlen($text);
+ }
+
+ if ($textStart < strlen($this->_descriptionTemplate)) {
+ $description->appendText(substr($this->_descriptionTemplate, $textStart));
+ }
+ }
+
+ /**
+ * Wraps an existing matcher and overrides the description when it fails.
+ *
+ * @factory ...
+ */
+ public static function describedAs(/* $description, Hamcrest\Matcher $matcher, $values... */)
+ {
+ $args = func_get_args();
+ $description = array_shift($args);
+ $matcher = array_shift($args);
+ $values = $args;
+
+ return new self($description, $matcher, $values);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Every.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Every.php
new file mode 100644
index 0000000..d686f8d
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Every.php
@@ -0,0 +1,56 @@
+_matcher = $matcher;
+ }
+
+ protected function matchesSafelyWithDiagnosticDescription($items, Description $mismatchDescription)
+ {
+ foreach ($items as $item) {
+ if (!$this->_matcher->matches($item)) {
+ $mismatchDescription->appendText('an item ');
+ $this->_matcher->describeMismatch($item, $mismatchDescription);
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('every item is ')->appendDescriptionOf($this->_matcher);
+ }
+
+ /**
+ * @param Matcher $itemMatcher
+ * A matcher to apply to every element in an array.
+ *
+ * @return \Hamcrest\Core\Every
+ * Evaluates to TRUE for a collection in which every item matches $itemMatcher
+ *
+ * @factory
+ */
+ public static function everyItem(Matcher $itemMatcher)
+ {
+ return new self($itemMatcher);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/HasToString.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/HasToString.php
new file mode 100644
index 0000000..45bd910
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/HasToString.php
@@ -0,0 +1,56 @@
+toString();
+ }
+
+ return (string) $actual;
+ }
+
+ /**
+ * Does array size satisfy a given matcher?
+ *
+ * @factory
+ */
+ public static function hasToString($matcher)
+ {
+ return new self(Util::wrapValueWithIsEqual($matcher));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Is.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Is.php
new file mode 100644
index 0000000..41266dc
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Is.php
@@ -0,0 +1,57 @@
+_matcher = $matcher;
+ }
+
+ public function matches($arg)
+ {
+ return $this->_matcher->matches($arg);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('is ')->appendDescriptionOf($this->_matcher);
+ }
+
+ public function describeMismatch($item, Description $mismatchDescription)
+ {
+ $this->_matcher->describeMismatch($item, $mismatchDescription);
+ }
+
+ /**
+ * Decorates another Matcher, retaining the behavior but allowing tests
+ * to be slightly more expressive.
+ *
+ * For example: assertThat($cheese, equalTo($smelly))
+ * vs. assertThat($cheese, is(equalTo($smelly)))
+ *
+ * @factory
+ */
+ public static function is($value)
+ {
+ return new self(Util::wrapValueWithIsEqual($value));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsAnything.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsAnything.php
new file mode 100644
index 0000000..f20e6c0
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsAnything.php
@@ -0,0 +1,45 @@
+true.
+ */
+class IsAnything extends BaseMatcher
+{
+
+ private $_message;
+
+ public function __construct($message = 'ANYTHING')
+ {
+ $this->_message = $message;
+ }
+
+ public function matches($item)
+ {
+ return true;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText($this->_message);
+ }
+
+ /**
+ * This matcher always evaluates to true.
+ *
+ * @param string $description A meaningful string used when describing itself.
+ *
+ * @return \Hamcrest\Core\IsAnything
+ * @factory
+ */
+ public static function anything($description = 'ANYTHING')
+ {
+ return new self($description);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsCollectionContaining.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsCollectionContaining.php
new file mode 100644
index 0000000..5e60426
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsCollectionContaining.php
@@ -0,0 +1,93 @@
+_elementMatcher = $elementMatcher;
+ }
+
+ protected function matchesSafely($items)
+ {
+ foreach ($items as $item) {
+ if ($this->_elementMatcher->matches($item)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected function describeMismatchSafely($items, Description $mismatchDescription)
+ {
+ $mismatchDescription->appendText('was ')->appendValue($items);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description
+ ->appendText('a collection containing ')
+ ->appendDescriptionOf($this->_elementMatcher)
+ ;
+ }
+
+ /**
+ * Test if the value is an array containing this matcher.
+ *
+ * Example:
+ *
+ * assertThat(array('a', 'b'), hasItem(equalTo('b')));
+ * //Convenience defaults to equalTo()
+ * assertThat(array('a', 'b'), hasItem('b'));
+ *
+ *
+ * @factory ...
+ */
+ public static function hasItem()
+ {
+ $args = func_get_args();
+ $firstArg = array_shift($args);
+
+ return new self(Util::wrapValueWithIsEqual($firstArg));
+ }
+
+ /**
+ * Test if the value is an array containing elements that match all of these
+ * matchers.
+ *
+ * Example:
+ *
+ * assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));
+ *
+ *
+ * @factory ...
+ */
+ public static function hasItems(/* args... */)
+ {
+ $args = func_get_args();
+ $matchers = array();
+
+ foreach ($args as $arg) {
+ $matchers[] = self::hasItem($arg);
+ }
+
+ return AllOf::allOf($matchers);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsEqual.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsEqual.php
new file mode 100644
index 0000000..523fba0
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsEqual.php
@@ -0,0 +1,44 @@
+_item = $item;
+ }
+
+ public function matches($arg)
+ {
+ return (($arg == $this->_item) && ($this->_item == $arg));
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendValue($this->_item);
+ }
+
+ /**
+ * Is the value equal to another value, as tested by the use of the "=="
+ * comparison operator?
+ *
+ * @factory
+ */
+ public static function equalTo($item)
+ {
+ return new self($item);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsIdentical.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsIdentical.php
new file mode 100644
index 0000000..28f7b36
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsIdentical.php
@@ -0,0 +1,38 @@
+_value = $value;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendValue($this->_value);
+ }
+
+ /**
+ * Tests of the value is identical to $value as tested by the "===" operator.
+ *
+ * @factory
+ */
+ public static function identicalTo($value)
+ {
+ return new self($value);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsInstanceOf.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsInstanceOf.php
new file mode 100644
index 0000000..7a5c92a
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsInstanceOf.php
@@ -0,0 +1,67 @@
+_theClass = $theClass;
+ }
+
+ protected function matchesWithDiagnosticDescription($item, Description $mismatchDescription)
+ {
+ if (!is_object($item)) {
+ $mismatchDescription->appendText('was ')->appendValue($item);
+
+ return false;
+ }
+
+ if (!($item instanceof $this->_theClass)) {
+ $mismatchDescription->appendText('[' . get_class($item) . '] ')
+ ->appendValue($item);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('an instance of ')
+ ->appendText($this->_theClass)
+ ;
+ }
+
+ /**
+ * Is the value an instance of a particular type?
+ * This version assumes no relationship between the required type and
+ * the signature of the method that sets it up, for example in
+ * assertThat($anObject, anInstanceOf('Thing'));
+ *
+ * @factory any
+ */
+ public static function anInstanceOf($theClass)
+ {
+ return new self($theClass);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNot.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNot.php
new file mode 100644
index 0000000..167f0d0
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNot.php
@@ -0,0 +1,44 @@
+_matcher = $matcher;
+ }
+
+ public function matches($arg)
+ {
+ return !$this->_matcher->matches($arg);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('not ')->appendDescriptionOf($this->_matcher);
+ }
+
+ /**
+ * Matches if value does not match $value.
+ *
+ * @factory
+ */
+ public static function not($value)
+ {
+ return new self(Util::wrapValueWithIsEqual($value));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNull.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNull.php
new file mode 100644
index 0000000..91a454c
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsNull.php
@@ -0,0 +1,56 @@
+appendText('null');
+ }
+
+ /**
+ * Matches if value is null.
+ *
+ * @factory
+ */
+ public static function nullValue()
+ {
+ if (!self::$_INSTANCE) {
+ self::$_INSTANCE = new self();
+ }
+
+ return self::$_INSTANCE;
+ }
+
+ /**
+ * Matches if value is not null.
+ *
+ * @factory
+ */
+ public static function notNullValue()
+ {
+ if (!self::$_NOT_INSTANCE) {
+ self::$_NOT_INSTANCE = IsNot::not(self::nullValue());
+ }
+
+ return self::$_NOT_INSTANCE;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsSame.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsSame.php
new file mode 100644
index 0000000..8107870
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsSame.php
@@ -0,0 +1,51 @@
+_object = $object;
+ }
+
+ public function matches($object)
+ {
+ return ($object === $this->_object) && ($this->_object === $object);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('sameInstance(')
+ ->appendValue($this->_object)
+ ->appendText(')')
+ ;
+ }
+
+ /**
+ * Creates a new instance of IsSame.
+ *
+ * @param mixed $object
+ * The predicate evaluates to true only when the argument is
+ * this object.
+ *
+ * @return \Hamcrest\Core\IsSame
+ * @factory
+ */
+ public static function sameInstance($object)
+ {
+ return new self($object);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsTypeOf.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsTypeOf.php
new file mode 100644
index 0000000..d24f0f9
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/IsTypeOf.php
@@ -0,0 +1,71 @@
+_theType = strtolower($theType);
+ }
+
+ public function matches($item)
+ {
+ return strtolower(gettype($item)) == $this->_theType;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText(self::getTypeDescription($this->_theType));
+ }
+
+ public function describeMismatch($item, Description $description)
+ {
+ if ($item === null) {
+ $description->appendText('was null');
+ } else {
+ $description->appendText('was ')
+ ->appendText(self::getTypeDescription(strtolower(gettype($item))))
+ ->appendText(' ')
+ ->appendValue($item)
+ ;
+ }
+ }
+
+ public static function getTypeDescription($type)
+ {
+ if ($type == 'null') {
+ return 'null';
+ }
+
+ return (strpos('aeiou', substr($type, 0, 1)) === false ? 'a ' : 'an ')
+ . $type;
+ }
+
+ /**
+ * Is the value a particular built-in type?
+ *
+ * @factory
+ */
+ public static function typeOf($theType)
+ {
+ return new self($theType);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Set.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Set.php
new file mode 100644
index 0000000..cdc45d5
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/Set.php
@@ -0,0 +1,95 @@
+
+ * assertThat(array('a', 'b'), set('b'));
+ * assertThat($foo, set('bar'));
+ * assertThat('Server', notSet('defaultPort'));
+ *
+ *
+ * @todo Replace $property with a matcher and iterate all property names.
+ */
+class Set extends BaseMatcher
+{
+
+ private $_property;
+ private $_not;
+
+ public function __construct($property, $not = false)
+ {
+ $this->_property = $property;
+ $this->_not = $not;
+ }
+
+ public function matches($item)
+ {
+ if ($item === null) {
+ return false;
+ }
+ $property = $this->_property;
+ if (is_array($item)) {
+ $result = isset($item[$property]);
+ } elseif (is_object($item)) {
+ $result = isset($item->$property);
+ } elseif (is_string($item)) {
+ $result = isset($item::$$property);
+ } else {
+ throw new \InvalidArgumentException('Must pass an object, array, or class name');
+ }
+
+ return $this->_not ? !$result : $result;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText($this->_not ? 'unset property ' : 'set property ')->appendText($this->_property);
+ }
+
+ public function describeMismatch($item, Description $description)
+ {
+ $value = '';
+ if (!$this->_not) {
+ $description->appendText('was not set');
+ } else {
+ $property = $this->_property;
+ if (is_array($item)) {
+ $value = $item[$property];
+ } elseif (is_object($item)) {
+ $value = $item->$property;
+ } elseif (is_string($item)) {
+ $value = $item::$$property;
+ }
+ parent::describeMismatch($value, $description);
+ }
+ }
+
+ /**
+ * Matches if value (class, object, or array) has named $property.
+ *
+ * @factory
+ */
+ public static function set($property)
+ {
+ return new self($property);
+ }
+
+ /**
+ * Matches if value (class, object, or array) does not have named $property.
+ *
+ * @factory
+ */
+ public static function notSet($property)
+ {
+ return new self($property, true);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/ShortcutCombination.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/ShortcutCombination.php
new file mode 100644
index 0000000..d93db74
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Core/ShortcutCombination.php
@@ -0,0 +1,43 @@
+
+ */
+ private $_matchers;
+
+ public function __construct(array $matchers)
+ {
+ Util::checkAllAreMatchers($matchers);
+
+ $this->_matchers = $matchers;
+ }
+
+ protected function matchesWithShortcut($item, $shortcut)
+ {
+ /** @var $matcher \Hamcrest\Matcher */
+ foreach ($this->_matchers as $matcher) {
+ if ($matcher->matches($item) == $shortcut) {
+ return $shortcut;
+ }
+ }
+
+ return !$shortcut;
+ }
+
+ public function describeToWithOperator(Description $description, $operator)
+ {
+ $description->appendList('(', ' ' . $operator . ' ', ')', $this->_matchers);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Description.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Description.php
new file mode 100644
index 0000000..9a482db
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Description.php
@@ -0,0 +1,70 @@
+matchesWithDiagnosticDescription($item, new NullDescription());
+ }
+
+ public function describeMismatch($item, Description $mismatchDescription)
+ {
+ $this->matchesWithDiagnosticDescription($item, $mismatchDescription);
+ }
+
+ abstract protected function matchesWithDiagnosticDescription($item, Description $mismatchDescription);
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/FeatureMatcher.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/FeatureMatcher.php
new file mode 100644
index 0000000..59f6cc7
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/FeatureMatcher.php
@@ -0,0 +1,67 @@
+featureValueOf() in a subclass to pull out the feature to be
+ * matched against.
+ */
+abstract class FeatureMatcher extends TypeSafeDiagnosingMatcher
+{
+
+ private $_subMatcher;
+ private $_featureDescription;
+ private $_featureName;
+
+ /**
+ * Constructor.
+ *
+ * @param string $type
+ * @param string $subtype
+ * @param \Hamcrest\Matcher $subMatcher The matcher to apply to the feature
+ * @param string $featureDescription Descriptive text to use in describeTo
+ * @param string $featureName Identifying text for mismatch message
+ */
+ public function __construct($type, $subtype, Matcher $subMatcher, $featureDescription, $featureName)
+ {
+ parent::__construct($type, $subtype);
+
+ $this->_subMatcher = $subMatcher;
+ $this->_featureDescription = $featureDescription;
+ $this->_featureName = $featureName;
+ }
+
+ /**
+ * Implement this to extract the interesting feature.
+ *
+ * @param mixed $actual the target object
+ *
+ * @return mixed the feature to be matched
+ */
+ abstract protected function featureValueOf($actual);
+
+ public function matchesSafelyWithDiagnosticDescription($actual, Description $mismatchDescription)
+ {
+ $featureValue = $this->featureValueOf($actual);
+
+ if (!$this->_subMatcher->matches($featureValue)) {
+ $mismatchDescription->appendText($this->_featureName)
+ ->appendText(' was ')->appendValue($featureValue);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ final public function describeTo(Description $description)
+ {
+ $description->appendText($this->_featureDescription)->appendText(' ')
+ ->appendDescriptionOf($this->_subMatcher)
+ ;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Internal/SelfDescribingValue.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Internal/SelfDescribingValue.php
new file mode 100644
index 0000000..995da71
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Internal/SelfDescribingValue.php
@@ -0,0 +1,27 @@
+_value = $value;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendValue($this->_value);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matcher.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matcher.php
new file mode 100644
index 0000000..e5dcf09
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matcher.php
@@ -0,0 +1,50 @@
+
+ * Matcher implementations should NOT directly implement this interface .
+ * Instead, extend the {@link Hamcrest\BaseMatcher} abstract class,
+ * which will ensure that the Matcher API can grow to support
+ * new features and remain compatible with all Matcher implementations.
+ *
+ * For easy access to common Matcher implementations, use the static factory
+ * methods in {@link Hamcrest\CoreMatchers}.
+ *
+ * @see Hamcrest\CoreMatchers
+ * @see Hamcrest\BaseMatcher
+ */
+interface Matcher extends SelfDescribing
+{
+
+ /**
+ * Evaluates the matcher for argument $item .
+ *
+ * @param mixed $item the object against which the matcher is evaluated.
+ *
+ * @return boolean true
if $item matches,
+ * otherwise false
.
+ *
+ * @see Hamcrest\BaseMatcher
+ */
+ public function matches($item);
+
+ /**
+ * Generate a description of why the matcher has not accepted the item.
+ * The description will be part of a larger description of why a matching
+ * failed, so it should be concise.
+ * This method assumes that matches($item)
is false, but
+ * will not check this.
+ *
+ * @param mixed $item The item that the Matcher has rejected.
+ * @param Description $description
+ * @return
+ */
+ public function describeMismatch($item, Description $description);
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/MatcherAssert.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/MatcherAssert.php
new file mode 100644
index 0000000..d546dbe
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/MatcherAssert.php
@@ -0,0 +1,118 @@
+
+ * // With an identifier
+ * assertThat("apple flavour", $apple->flavour(), equalTo("tasty"));
+ * // Without an identifier
+ * assertThat($apple->flavour(), equalTo("tasty"));
+ * // Evaluating a boolean expression
+ * assertThat("some error", $a > $b);
+ * assertThat($a > $b);
+ *
+ */
+ public static function assertThat(/* $args ... */)
+ {
+ $args = func_get_args();
+ switch (count($args)) {
+ case 1:
+ self::$_count++;
+ if (!$args[0]) {
+ throw new AssertionError();
+ }
+ break;
+
+ case 2:
+ self::$_count++;
+ if ($args[1] instanceof Matcher) {
+ self::doAssert('', $args[0], $args[1]);
+ } elseif (!$args[1]) {
+ throw new AssertionError($args[0]);
+ }
+ break;
+
+ case 3:
+ self::$_count++;
+ self::doAssert(
+ $args[0],
+ $args[1],
+ Util::wrapValueWithIsEqual($args[2])
+ );
+ break;
+
+ default:
+ throw new \InvalidArgumentException('assertThat() requires one to three arguments');
+ }
+ }
+
+ /**
+ * Returns the number of assertions performed.
+ *
+ * @return int
+ */
+ public static function getCount()
+ {
+ return self::$_count;
+ }
+
+ /**
+ * Resets the number of assertions performed to zero.
+ */
+ public static function resetCount()
+ {
+ self::$_count = 0;
+ }
+
+ /**
+ * Performs the actual assertion logic.
+ *
+ * If $matcher
doesn't match $actual
,
+ * throws a {@link Hamcrest\AssertionError} with a description
+ * of the failure along with the optional $identifier
.
+ *
+ * @param string $identifier added to the message upon failure
+ * @param mixed $actual value to compare against $matcher
+ * @param \Hamcrest\Matcher $matcher applied to $actual
+ * @throws AssertionError
+ */
+ private static function doAssert($identifier, $actual, Matcher $matcher)
+ {
+ if (!$matcher->matches($actual)) {
+ $description = new StringDescription();
+ if (!empty($identifier)) {
+ $description->appendText($identifier . PHP_EOL);
+ }
+ $description->appendText('Expected: ')
+ ->appendDescriptionOf($matcher)
+ ->appendText(PHP_EOL . ' but: ');
+
+ $matcher->describeMismatch($actual, $description);
+
+ throw new AssertionError((string) $description);
+ }
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matchers.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matchers.php
new file mode 100644
index 0000000..23232e4
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Matchers.php
@@ -0,0 +1,713 @@
+
+ * assertThat($string, both(containsString("a"))->andAlso(containsString("b")));
+ *
+ */
+ public static function both(\Hamcrest\Matcher $matcher)
+ {
+ return \Hamcrest\Core\CombinableMatcher::both($matcher);
+ }
+
+ /**
+ * This is useful for fluently combining matchers where either may pass,
+ * for example:
+ *
+ * assertThat($string, either(containsString("a"))->orElse(containsString("b")));
+ *
+ */
+ public static function either(\Hamcrest\Matcher $matcher)
+ {
+ return \Hamcrest\Core\CombinableMatcher::either($matcher);
+ }
+
+ /**
+ * Wraps an existing matcher and overrides the description when it fails.
+ */
+ public static function describedAs(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Core\DescribedAs', 'describedAs'), $args);
+ }
+
+ /**
+ * @param Matcher $itemMatcher
+ * A matcher to apply to every element in an array.
+ *
+ * @return \Hamcrest\Core\Every
+ * Evaluates to TRUE for a collection in which every item matches $itemMatcher
+ */
+ public static function everyItem(\Hamcrest\Matcher $itemMatcher)
+ {
+ return \Hamcrest\Core\Every::everyItem($itemMatcher);
+ }
+
+ /**
+ * Does array size satisfy a given matcher?
+ */
+ public static function hasToString($matcher)
+ {
+ return \Hamcrest\Core\HasToString::hasToString($matcher);
+ }
+
+ /**
+ * Decorates another Matcher, retaining the behavior but allowing tests
+ * to be slightly more expressive.
+ *
+ * For example: assertThat($cheese, equalTo($smelly))
+ * vs. assertThat($cheese, is(equalTo($smelly)))
+ */
+ public static function is($value)
+ {
+ return \Hamcrest\Core\Is::is($value);
+ }
+
+ /**
+ * This matcher always evaluates to true.
+ *
+ * @param string $description A meaningful string used when describing itself.
+ *
+ * @return \Hamcrest\Core\IsAnything
+ */
+ public static function anything($description = 'ANYTHING')
+ {
+ return \Hamcrest\Core\IsAnything::anything($description);
+ }
+
+ /**
+ * Test if the value is an array containing this matcher.
+ *
+ * Example:
+ *
+ * assertThat(array('a', 'b'), hasItem(equalTo('b')));
+ * //Convenience defaults to equalTo()
+ * assertThat(array('a', 'b'), hasItem('b'));
+ *
+ */
+ public static function hasItem(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItem'), $args);
+ }
+
+ /**
+ * Test if the value is an array containing elements that match all of these
+ * matchers.
+ *
+ * Example:
+ *
+ * assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));
+ *
+ */
+ public static function hasItems(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItems'), $args);
+ }
+
+ /**
+ * Is the value equal to another value, as tested by the use of the "=="
+ * comparison operator?
+ */
+ public static function equalTo($item)
+ {
+ return \Hamcrest\Core\IsEqual::equalTo($item);
+ }
+
+ /**
+ * Tests of the value is identical to $value as tested by the "===" operator.
+ */
+ public static function identicalTo($value)
+ {
+ return \Hamcrest\Core\IsIdentical::identicalTo($value);
+ }
+
+ /**
+ * Is the value an instance of a particular type?
+ * This version assumes no relationship between the required type and
+ * the signature of the method that sets it up, for example in
+ * assertThat($anObject, anInstanceOf('Thing'));
+ */
+ public static function anInstanceOf($theClass)
+ {
+ return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass);
+ }
+
+ /**
+ * Is the value an instance of a particular type?
+ * This version assumes no relationship between the required type and
+ * the signature of the method that sets it up, for example in
+ * assertThat($anObject, anInstanceOf('Thing'));
+ */
+ public static function any($theClass)
+ {
+ return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass);
+ }
+
+ /**
+ * Matches if value does not match $value.
+ */
+ public static function not($value)
+ {
+ return \Hamcrest\Core\IsNot::not($value);
+ }
+
+ /**
+ * Matches if value is null.
+ */
+ public static function nullValue()
+ {
+ return \Hamcrest\Core\IsNull::nullValue();
+ }
+
+ /**
+ * Matches if value is not null.
+ */
+ public static function notNullValue()
+ {
+ return \Hamcrest\Core\IsNull::notNullValue();
+ }
+
+ /**
+ * Creates a new instance of IsSame.
+ *
+ * @param mixed $object
+ * The predicate evaluates to true only when the argument is
+ * this object.
+ *
+ * @return \Hamcrest\Core\IsSame
+ */
+ public static function sameInstance($object)
+ {
+ return \Hamcrest\Core\IsSame::sameInstance($object);
+ }
+
+ /**
+ * Is the value a particular built-in type?
+ */
+ public static function typeOf($theType)
+ {
+ return \Hamcrest\Core\IsTypeOf::typeOf($theType);
+ }
+
+ /**
+ * Matches if value (class, object, or array) has named $property.
+ */
+ public static function set($property)
+ {
+ return \Hamcrest\Core\Set::set($property);
+ }
+
+ /**
+ * Matches if value (class, object, or array) does not have named $property.
+ */
+ public static function notSet($property)
+ {
+ return \Hamcrest\Core\Set::notSet($property);
+ }
+
+ /**
+ * Matches if value is a number equal to $value within some range of
+ * acceptable error $delta.
+ */
+ public static function closeTo($value, $delta)
+ {
+ return \Hamcrest\Number\IsCloseTo::closeTo($value, $delta);
+ }
+
+ /**
+ * The value is not > $value, nor < $value.
+ */
+ public static function comparesEqualTo($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::comparesEqualTo($value);
+ }
+
+ /**
+ * The value is > $value.
+ */
+ public static function greaterThan($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::greaterThan($value);
+ }
+
+ /**
+ * The value is >= $value.
+ */
+ public static function greaterThanOrEqualTo($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value);
+ }
+
+ /**
+ * The value is >= $value.
+ */
+ public static function atLeast($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value);
+ }
+
+ /**
+ * The value is < $value.
+ */
+ public static function lessThan($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::lessThan($value);
+ }
+
+ /**
+ * The value is <= $value.
+ */
+ public static function lessThanOrEqualTo($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value);
+ }
+
+ /**
+ * The value is <= $value.
+ */
+ public static function atMost($value)
+ {
+ return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value);
+ }
+
+ /**
+ * Matches if value is a zero-length string.
+ */
+ public static function isEmptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isEmptyString();
+ }
+
+ /**
+ * Matches if value is a zero-length string.
+ */
+ public static function emptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isEmptyString();
+ }
+
+ /**
+ * Matches if value is null or a zero-length string.
+ */
+ public static function isEmptyOrNullString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString();
+ }
+
+ /**
+ * Matches if value is null or a zero-length string.
+ */
+ public static function nullOrEmptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString();
+ }
+
+ /**
+ * Matches if value is a non-zero-length string.
+ */
+ public static function isNonEmptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isNonEmptyString();
+ }
+
+ /**
+ * Matches if value is a non-zero-length string.
+ */
+ public static function nonEmptyString()
+ {
+ return \Hamcrest\Text\IsEmptyString::isNonEmptyString();
+ }
+
+ /**
+ * Matches if value is a string equal to $string, regardless of the case.
+ */
+ public static function equalToIgnoringCase($string)
+ {
+ return \Hamcrest\Text\IsEqualIgnoringCase::equalToIgnoringCase($string);
+ }
+
+ /**
+ * Matches if value is a string equal to $string, regardless of whitespace.
+ */
+ public static function equalToIgnoringWhiteSpace($string)
+ {
+ return \Hamcrest\Text\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace($string);
+ }
+
+ /**
+ * Matches if value is a string that matches regular expression $pattern.
+ */
+ public static function matchesPattern($pattern)
+ {
+ return \Hamcrest\Text\MatchesPattern::matchesPattern($pattern);
+ }
+
+ /**
+ * Matches if value is a string that contains $substring.
+ */
+ public static function containsString($substring)
+ {
+ return \Hamcrest\Text\StringContains::containsString($substring);
+ }
+
+ /**
+ * Matches if value is a string that contains $substring regardless of the case.
+ */
+ public static function containsStringIgnoringCase($substring)
+ {
+ return \Hamcrest\Text\StringContainsIgnoringCase::containsStringIgnoringCase($substring);
+ }
+
+ /**
+ * Matches if value contains $substrings in a constrained order.
+ */
+ public static function stringContainsInOrder(/* args... */)
+ {
+ $args = func_get_args();
+ return call_user_func_array(array('\Hamcrest\Text\StringContainsInOrder', 'stringContainsInOrder'), $args);
+ }
+
+ /**
+ * Matches if value is a string that ends with $substring.
+ */
+ public static function endsWith($substring)
+ {
+ return \Hamcrest\Text\StringEndsWith::endsWith($substring);
+ }
+
+ /**
+ * Matches if value is a string that starts with $substring.
+ */
+ public static function startsWith($substring)
+ {
+ return \Hamcrest\Text\StringStartsWith::startsWith($substring);
+ }
+
+ /**
+ * Is the value an array?
+ */
+ public static function arrayValue()
+ {
+ return \Hamcrest\Type\IsArray::arrayValue();
+ }
+
+ /**
+ * Is the value a boolean?
+ */
+ public static function booleanValue()
+ {
+ return \Hamcrest\Type\IsBoolean::booleanValue();
+ }
+
+ /**
+ * Is the value a boolean?
+ */
+ public static function boolValue()
+ {
+ return \Hamcrest\Type\IsBoolean::booleanValue();
+ }
+
+ /**
+ * Is the value callable?
+ */
+ public static function callableValue()
+ {
+ return \Hamcrest\Type\IsCallable::callableValue();
+ }
+
+ /**
+ * Is the value a float/double?
+ */
+ public static function doubleValue()
+ {
+ return \Hamcrest\Type\IsDouble::doubleValue();
+ }
+
+ /**
+ * Is the value a float/double?
+ */
+ public static function floatValue()
+ {
+ return \Hamcrest\Type\IsDouble::doubleValue();
+ }
+
+ /**
+ * Is the value an integer?
+ */
+ public static function integerValue()
+ {
+ return \Hamcrest\Type\IsInteger::integerValue();
+ }
+
+ /**
+ * Is the value an integer?
+ */
+ public static function intValue()
+ {
+ return \Hamcrest\Type\IsInteger::integerValue();
+ }
+
+ /**
+ * Is the value a numeric?
+ */
+ public static function numericValue()
+ {
+ return \Hamcrest\Type\IsNumeric::numericValue();
+ }
+
+ /**
+ * Is the value an object?
+ */
+ public static function objectValue()
+ {
+ return \Hamcrest\Type\IsObject::objectValue();
+ }
+
+ /**
+ * Is the value an object?
+ */
+ public static function anObject()
+ {
+ return \Hamcrest\Type\IsObject::objectValue();
+ }
+
+ /**
+ * Is the value a resource?
+ */
+ public static function resourceValue()
+ {
+ return \Hamcrest\Type\IsResource::resourceValue();
+ }
+
+ /**
+ * Is the value a scalar (boolean, integer, double, or string)?
+ */
+ public static function scalarValue()
+ {
+ return \Hamcrest\Type\IsScalar::scalarValue();
+ }
+
+ /**
+ * Is the value a string?
+ */
+ public static function stringValue()
+ {
+ return \Hamcrest\Type\IsString::stringValue();
+ }
+
+ /**
+ * Wraps $matcher
with {@link Hamcrest\Core\IsEqual)
+ * if it's not a matcher and the XPath in count()
+ * if it's an integer.
+ */
+ public static function hasXPath($xpath, $matcher = null)
+ {
+ return \Hamcrest\Xml\HasXPath::hasXPath($xpath, $matcher);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/NullDescription.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/NullDescription.php
new file mode 100644
index 0000000..aae8e46
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/NullDescription.php
@@ -0,0 +1,43 @@
+_value = $value;
+ $this->_delta = $delta;
+ }
+
+ protected function matchesSafely($item)
+ {
+ return $this->_actualDelta($item) <= 0.0;
+ }
+
+ protected function describeMismatchSafely($item, Description $mismatchDescription)
+ {
+ $mismatchDescription->appendValue($item)
+ ->appendText(' differed by ')
+ ->appendValue($this->_actualDelta($item))
+ ;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('a numeric value within ')
+ ->appendValue($this->_delta)
+ ->appendText(' of ')
+ ->appendValue($this->_value)
+ ;
+ }
+
+ /**
+ * Matches if value is a number equal to $value within some range of
+ * acceptable error $delta.
+ *
+ * @factory
+ */
+ public static function closeTo($value, $delta)
+ {
+ return new self($value, $delta);
+ }
+
+ // -- Private Methods
+
+ private function _actualDelta($item)
+ {
+ return (abs(($item - $this->_value)) - $this->_delta);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Number/OrderingComparison.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Number/OrderingComparison.php
new file mode 100644
index 0000000..369d0cf
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Number/OrderingComparison.php
@@ -0,0 +1,132 @@
+_value = $value;
+ $this->_minCompare = $minCompare;
+ $this->_maxCompare = $maxCompare;
+ }
+
+ protected function matchesSafely($other)
+ {
+ $compare = $this->_compare($this->_value, $other);
+
+ return ($this->_minCompare <= $compare) && ($compare <= $this->_maxCompare);
+ }
+
+ protected function describeMismatchSafely($item, Description $mismatchDescription)
+ {
+ $mismatchDescription
+ ->appendValue($item)->appendText(' was ')
+ ->appendText($this->_comparison($this->_compare($this->_value, $item)))
+ ->appendText(' ')->appendValue($this->_value)
+ ;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('a value ')
+ ->appendText($this->_comparison($this->_minCompare))
+ ;
+ if ($this->_minCompare != $this->_maxCompare) {
+ $description->appendText(' or ')
+ ->appendText($this->_comparison($this->_maxCompare))
+ ;
+ }
+ $description->appendText(' ')->appendValue($this->_value);
+ }
+
+ /**
+ * The value is not > $value, nor < $value.
+ *
+ * @factory
+ */
+ public static function comparesEqualTo($value)
+ {
+ return new self($value, 0, 0);
+ }
+
+ /**
+ * The value is > $value.
+ *
+ * @factory
+ */
+ public static function greaterThan($value)
+ {
+ return new self($value, -1, -1);
+ }
+
+ /**
+ * The value is >= $value.
+ *
+ * @factory atLeast
+ */
+ public static function greaterThanOrEqualTo($value)
+ {
+ return new self($value, -1, 0);
+ }
+
+ /**
+ * The value is < $value.
+ *
+ * @factory
+ */
+ public static function lessThan($value)
+ {
+ return new self($value, 1, 1);
+ }
+
+ /**
+ * The value is <= $value.
+ *
+ * @factory atMost
+ */
+ public static function lessThanOrEqualTo($value)
+ {
+ return new self($value, 0, 1);
+ }
+
+ // -- Private Methods
+
+ private function _compare($left, $right)
+ {
+ $a = $left;
+ $b = $right;
+
+ if ($a < $b) {
+ return -1;
+ } elseif ($a == $b) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+ private function _comparison($compare)
+ {
+ if ($compare > 0) {
+ return 'less than';
+ } elseif ($compare == 0) {
+ return 'equal to';
+ } else {
+ return 'greater than';
+ }
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/SelfDescribing.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/SelfDescribing.php
new file mode 100644
index 0000000..872fdf9
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/SelfDescribing.php
@@ -0,0 +1,23 @@
+_out = (string) $out;
+ }
+
+ public function __toString()
+ {
+ return $this->_out;
+ }
+
+ /**
+ * Return the description of a {@link Hamcrest\SelfDescribing} object as a
+ * String.
+ *
+ * @param \Hamcrest\SelfDescribing $selfDescribing
+ * The object to be described.
+ *
+ * @return string
+ * The description of the object.
+ */
+ public static function toString(SelfDescribing $selfDescribing)
+ {
+ $self = new self();
+
+ return (string) $self->appendDescriptionOf($selfDescribing);
+ }
+
+ /**
+ * Alias for {@link toString()}.
+ */
+ public static function asString(SelfDescribing $selfDescribing)
+ {
+ return self::toString($selfDescribing);
+ }
+
+ // -- Protected Methods
+
+ protected function append($str)
+ {
+ $this->_out .= $str;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEmptyString.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEmptyString.php
new file mode 100644
index 0000000..2ae61b9
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEmptyString.php
@@ -0,0 +1,85 @@
+_empty = $empty;
+ }
+
+ public function matches($item)
+ {
+ return $this->_empty
+ ? ($item === '')
+ : is_string($item) && $item !== '';
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText($this->_empty ? 'an empty string' : 'a non-empty string');
+ }
+
+ /**
+ * Matches if value is a zero-length string.
+ *
+ * @factory emptyString
+ */
+ public static function isEmptyString()
+ {
+ if (!self::$_INSTANCE) {
+ self::$_INSTANCE = new self(true);
+ }
+
+ return self::$_INSTANCE;
+ }
+
+ /**
+ * Matches if value is null or a zero-length string.
+ *
+ * @factory nullOrEmptyString
+ */
+ public static function isEmptyOrNullString()
+ {
+ if (!self::$_NULL_OR_EMPTY_INSTANCE) {
+ self::$_NULL_OR_EMPTY_INSTANCE = AnyOf::anyOf(
+ IsNull::nullvalue(),
+ self::isEmptyString()
+ );
+ }
+
+ return self::$_NULL_OR_EMPTY_INSTANCE;
+ }
+
+ /**
+ * Matches if value is a non-zero-length string.
+ *
+ * @factory nonEmptyString
+ */
+ public static function isNonEmptyString()
+ {
+ if (!self::$_NOT_INSTANCE) {
+ self::$_NOT_INSTANCE = new self(false);
+ }
+
+ return self::$_NOT_INSTANCE;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringCase.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringCase.php
new file mode 100644
index 0000000..3836a8c
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringCase.php
@@ -0,0 +1,52 @@
+_string = $string;
+ }
+
+ protected function matchesSafely($item)
+ {
+ return strtolower($this->_string) === strtolower($item);
+ }
+
+ protected function describeMismatchSafely($item, Description $mismatchDescription)
+ {
+ $mismatchDescription->appendText('was ')->appendText($item);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('equalToIgnoringCase(')
+ ->appendValue($this->_string)
+ ->appendText(')')
+ ;
+ }
+
+ /**
+ * Matches if value is a string equal to $string, regardless of the case.
+ *
+ * @factory
+ */
+ public static function equalToIgnoringCase($string)
+ {
+ return new self($string);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringWhiteSpace.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringWhiteSpace.php
new file mode 100644
index 0000000..853692b
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/IsEqualIgnoringWhiteSpace.php
@@ -0,0 +1,66 @@
+_string = $string;
+ }
+
+ protected function matchesSafely($item)
+ {
+ return (strtolower($this->_stripSpace($item))
+ === strtolower($this->_stripSpace($this->_string)));
+ }
+
+ protected function describeMismatchSafely($item, Description $mismatchDescription)
+ {
+ $mismatchDescription->appendText('was ')->appendText($item);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('equalToIgnoringWhiteSpace(')
+ ->appendValue($this->_string)
+ ->appendText(')')
+ ;
+ }
+
+ /**
+ * Matches if value is a string equal to $string, regardless of whitespace.
+ *
+ * @factory
+ */
+ public static function equalToIgnoringWhiteSpace($string)
+ {
+ return new self($string);
+ }
+
+ // -- Private Methods
+
+ private function _stripSpace($string)
+ {
+ $parts = preg_split("/[\r\n\t ]+/", $string);
+ foreach ($parts as $i => $part) {
+ $parts[$i] = trim($part, " \r\n\t");
+ }
+
+ return trim(implode(' ', $parts), " \r\n\t");
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/MatchesPattern.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/MatchesPattern.php
new file mode 100644
index 0000000..fa0d68e
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/MatchesPattern.php
@@ -0,0 +1,40 @@
+_substring, (string) $item) >= 1;
+ }
+
+ protected function relationship()
+ {
+ return 'matching';
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContains.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContains.php
new file mode 100644
index 0000000..b92786b
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContains.php
@@ -0,0 +1,45 @@
+_substring);
+ }
+
+ /**
+ * Matches if value is a string that contains $substring.
+ *
+ * @factory
+ */
+ public static function containsString($substring)
+ {
+ return new self($substring);
+ }
+
+ // -- Protected Methods
+
+ protected function evalSubstringOf($item)
+ {
+ return (false !== strpos((string) $item, $this->_substring));
+ }
+
+ protected function relationship()
+ {
+ return 'containing';
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsIgnoringCase.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsIgnoringCase.php
new file mode 100644
index 0000000..69f37c2
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsIgnoringCase.php
@@ -0,0 +1,40 @@
+_substring));
+ }
+
+ protected function relationship()
+ {
+ return 'containing in any case';
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsInOrder.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsInOrder.php
new file mode 100644
index 0000000..e75de65
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringContainsInOrder.php
@@ -0,0 +1,66 @@
+_substrings = $substrings;
+ }
+
+ protected function matchesSafely($item)
+ {
+ $fromIndex = 0;
+
+ foreach ($this->_substrings as $substring) {
+ if (false === $fromIndex = strpos($item, $substring, $fromIndex)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected function describeMismatchSafely($item, Description $mismatchDescription)
+ {
+ $mismatchDescription->appendText('was ')->appendText($item);
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('a string containing ')
+ ->appendValueList('', ', ', '', $this->_substrings)
+ ->appendText(' in order')
+ ;
+ }
+
+ /**
+ * Matches if value contains $substrings in a constrained order.
+ *
+ * @factory ...
+ */
+ public static function stringContainsInOrder(/* args... */)
+ {
+ $args = func_get_args();
+
+ if (isset($args[0]) && is_array($args[0])) {
+ $args = $args[0];
+ }
+
+ return new self($args);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringEndsWith.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringEndsWith.php
new file mode 100644
index 0000000..f802ee4
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringEndsWith.php
@@ -0,0 +1,40 @@
+_substring))) === $this->_substring);
+ }
+
+ protected function relationship()
+ {
+ return 'ending with';
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringStartsWith.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringStartsWith.php
new file mode 100644
index 0000000..79c9565
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/StringStartsWith.php
@@ -0,0 +1,40 @@
+_substring)) === $this->_substring);
+ }
+
+ protected function relationship()
+ {
+ return 'starting with';
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/SubstringMatcher.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/SubstringMatcher.php
new file mode 100644
index 0000000..e560ad6
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Text/SubstringMatcher.php
@@ -0,0 +1,45 @@
+_substring = $substring;
+ }
+
+ protected function matchesSafely($item)
+ {
+ return $this->evalSubstringOf($item);
+ }
+
+ protected function describeMismatchSafely($item, Description $mismatchDescription)
+ {
+ $mismatchDescription->appendText('was "')->appendText($item)->appendText('"');
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('a string ')
+ ->appendText($this->relationship())
+ ->appendText(' ')
+ ->appendValue($this->_substring)
+ ;
+ }
+
+ abstract protected function evalSubstringOf($string);
+
+ abstract protected function relationship();
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsArray.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsArray.php
new file mode 100644
index 0000000..9179102
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsArray.php
@@ -0,0 +1,32 @@
+isHexadecimal($item)) {
+ return true;
+ }
+
+ return is_numeric($item);
+ }
+
+ /**
+ * Return if the string passed is a valid hexadecimal number.
+ * This check is necessary because PHP 7 doesn't recognize hexadecimal string as numeric anymore.
+ *
+ * @param mixed $item
+ * @return boolean
+ */
+ private function isHexadecimal($item)
+ {
+ if (is_string($item) && preg_match('/^0x(.*)$/', $item, $matches)) {
+ return ctype_xdigit($matches[1]);
+ }
+
+ return false;
+ }
+
+ /**
+ * Is the value a numeric?
+ *
+ * @factory
+ */
+ public static function numericValue()
+ {
+ return new self;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsObject.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsObject.php
new file mode 100644
index 0000000..65918fc
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Type/IsObject.php
@@ -0,0 +1,32 @@
+matchesSafelyWithDiagnosticDescription($item, new NullDescription());
+ }
+
+ final public function describeMismatchSafely($item, Description $mismatchDescription)
+ {
+ $this->matchesSafelyWithDiagnosticDescription($item, $mismatchDescription);
+ }
+
+ // -- Protected Methods
+
+ /**
+ * Subclasses should implement these. The item will already have been checked for
+ * the specific type.
+ */
+ abstract protected function matchesSafelyWithDiagnosticDescription($item, Description $mismatchDescription);
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/TypeSafeMatcher.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/TypeSafeMatcher.php
new file mode 100644
index 0000000..56e299a
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/TypeSafeMatcher.php
@@ -0,0 +1,107 @@
+_expectedType = $expectedType;
+ $this->_expectedSubtype = $expectedSubtype;
+ }
+
+ final public function matches($item)
+ {
+ return $this->_isSafeType($item) && $this->matchesSafely($item);
+ }
+
+ final public function describeMismatch($item, Description $mismatchDescription)
+ {
+ if (!$this->_isSafeType($item)) {
+ parent::describeMismatch($item, $mismatchDescription);
+ } else {
+ $this->describeMismatchSafely($item, $mismatchDescription);
+ }
+ }
+
+ // -- Protected Methods
+
+ /**
+ * The item will already have been checked for the specific type and subtype.
+ */
+ abstract protected function matchesSafely($item);
+
+ /**
+ * The item will already have been checked for the specific type and subtype.
+ */
+ abstract protected function describeMismatchSafely($item, Description $mismatchDescription);
+
+ // -- Private Methods
+
+ private function _isSafeType($value)
+ {
+ switch ($this->_expectedType) {
+
+ case self::TYPE_ANY:
+ return true;
+
+ case self::TYPE_STRING:
+ return is_string($value) || is_numeric($value);
+
+ case self::TYPE_NUMERIC:
+ return is_numeric($value) || is_string($value);
+
+ case self::TYPE_ARRAY:
+ return is_array($value);
+
+ case self::TYPE_OBJECT:
+ return is_object($value)
+ && ($this->_expectedSubtype === null
+ || $value instanceof $this->_expectedSubtype);
+
+ case self::TYPE_RESOURCE:
+ return is_resource($value)
+ && ($this->_expectedSubtype === null
+ || get_resource_type($value) == $this->_expectedSubtype);
+
+ case self::TYPE_BOOLEAN:
+ return true;
+
+ default:
+ return true;
+
+ }
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Util.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Util.php
new file mode 100644
index 0000000..169b036
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Util.php
@@ -0,0 +1,76 @@
+ all items are
+ */
+ public static function createMatcherArray(array $items)
+ {
+ //Extract single array item
+ if (count($items) == 1 && is_array($items[0])) {
+ $items = $items[0];
+ }
+
+ //Replace non-matchers
+ foreach ($items as &$item) {
+ if (!($item instanceof Matcher)) {
+ $item = Core\IsEqual::equalTo($item);
+ }
+ }
+
+ return $items;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Xml/HasXPath.php b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Xml/HasXPath.php
new file mode 100644
index 0000000..d9764e4
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest/Xml/HasXPath.php
@@ -0,0 +1,195 @@
+_xpath = $xpath;
+ $this->_matcher = $matcher;
+ }
+
+ /**
+ * Matches if the XPath matches against the DOM node and the matcher.
+ *
+ * @param string|\DOMNode $actual
+ * @param Description $mismatchDescription
+ * @return bool
+ */
+ protected function matchesWithDiagnosticDescription($actual, Description $mismatchDescription)
+ {
+ if (is_string($actual)) {
+ $actual = $this->createDocument($actual);
+ } elseif (!$actual instanceof \DOMNode) {
+ $mismatchDescription->appendText('was ')->appendValue($actual);
+
+ return false;
+ }
+ $result = $this->evaluate($actual);
+ if ($result instanceof \DOMNodeList) {
+ return $this->matchesContent($result, $mismatchDescription);
+ } else {
+ return $this->matchesExpression($result, $mismatchDescription);
+ }
+ }
+
+ /**
+ * Creates and returns a DOMDocument
from the given
+ * XML or HTML string.
+ *
+ * @param string $text
+ * @return \DOMDocument built from $text
+ * @throws \InvalidArgumentException if the document is not valid
+ */
+ protected function createDocument($text)
+ {
+ $document = new \DOMDocument();
+ if (preg_match('/^\s*<\?xml/', $text)) {
+ if (!@$document->loadXML($text)) {
+ throw new \InvalidArgumentException('Must pass a valid XML document');
+ }
+ } else {
+ if (!@$document->loadHTML($text)) {
+ throw new \InvalidArgumentException('Must pass a valid HTML or XHTML document');
+ }
+ }
+
+ return $document;
+ }
+
+ /**
+ * Applies the configured XPath to the DOM node and returns either
+ * the result if it's an expression or the node list if it's a query.
+ *
+ * @param \DOMNode $node context from which to issue query
+ * @return mixed result of expression or DOMNodeList from query
+ */
+ protected function evaluate(\DOMNode $node)
+ {
+ if ($node instanceof \DOMDocument) {
+ $xpathDocument = new \DOMXPath($node);
+
+ return $xpathDocument->evaluate($this->_xpath);
+ } else {
+ $xpathDocument = new \DOMXPath($node->ownerDocument);
+
+ return $xpathDocument->evaluate($this->_xpath, $node);
+ }
+ }
+
+ /**
+ * Matches if the list of nodes is not empty and the content of at least
+ * one node matches the configured matcher, if supplied.
+ *
+ * @param \DOMNodeList $nodes selected by the XPath query
+ * @param Description $mismatchDescription
+ * @return bool
+ */
+ protected function matchesContent(\DOMNodeList $nodes, Description $mismatchDescription)
+ {
+ if ($nodes->length == 0) {
+ $mismatchDescription->appendText('XPath returned no results');
+ } elseif ($this->_matcher === null) {
+ return true;
+ } else {
+ foreach ($nodes as $node) {
+ if ($this->_matcher->matches($node->textContent)) {
+ return true;
+ }
+ }
+ $content = array();
+ foreach ($nodes as $node) {
+ $content[] = $node->textContent;
+ }
+ $mismatchDescription->appendText('XPath returned ')
+ ->appendValue($content);
+ }
+
+ return false;
+ }
+
+ /**
+ * Matches if the result of the XPath expression matches the configured
+ * matcher or evaluates to true
if there is none.
+ *
+ * @param mixed $result result of the XPath expression
+ * @param Description $mismatchDescription
+ * @return bool
+ */
+ protected function matchesExpression($result, Description $mismatchDescription)
+ {
+ if ($this->_matcher === null) {
+ if ($result) {
+ return true;
+ }
+ $mismatchDescription->appendText('XPath expression result was ')
+ ->appendValue($result);
+ } else {
+ if ($this->_matcher->matches($result)) {
+ return true;
+ }
+ $mismatchDescription->appendText('XPath expression result ');
+ $this->_matcher->describeMismatch($result, $mismatchDescription);
+ }
+
+ return false;
+ }
+
+ public function describeTo(Description $description)
+ {
+ $description->appendText('XML or HTML document with XPath "')
+ ->appendText($this->_xpath)
+ ->appendText('"');
+ if ($this->_matcher !== null) {
+ $description->appendText(' ');
+ $this->_matcher->describeTo($description);
+ }
+ }
+
+ /**
+ * Wraps $matcher
with {@link Hamcrest\Core\IsEqual)
+ * if it's not a matcher and the XPath in count()
+ * if it's an integer.
+ *
+ * @factory
+ */
+ public static function hasXPath($xpath, $matcher = null)
+ {
+ if ($matcher === null || $matcher instanceof Matcher) {
+ return new self($xpath, $matcher);
+ } elseif (is_int($matcher) && strpos($xpath, 'count(') !== 0) {
+ $xpath = 'count(' . $xpath . ')';
+ }
+
+ return new self($xpath, IsEqual::equalTo($matcher));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/AbstractMatcherTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/AbstractMatcherTest.php
new file mode 100644
index 0000000..6c52c0e
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/AbstractMatcherTest.php
@@ -0,0 +1,66 @@
+assertTrue($matcher->matches($arg), $message);
+ }
+
+ public function assertDoesNotMatch(\Hamcrest\Matcher $matcher, $arg, $message)
+ {
+ $this->assertFalse($matcher->matches($arg), $message);
+ }
+
+ public function assertDescription($expected, \Hamcrest\Matcher $matcher)
+ {
+ $description = new \Hamcrest\StringDescription();
+ $description->appendDescriptionOf($matcher);
+ $this->assertEquals($expected, (string) $description, 'Expected description');
+ }
+
+ public function assertMismatchDescription($expected, \Hamcrest\Matcher $matcher, $arg)
+ {
+ $description = new \Hamcrest\StringDescription();
+ $this->assertFalse(
+ $matcher->matches($arg),
+ 'Precondtion: Matcher should not match item'
+ );
+ $matcher->describeMismatch($arg, $description);
+ $this->assertEquals(
+ $expected,
+ (string) $description,
+ 'Expected mismatch description'
+ );
+ }
+
+ public function testIsNullSafe()
+ {
+ //Should not generate any notices
+ $this->createMatcher()->matches(null);
+ $this->createMatcher()->describeMismatch(
+ null,
+ new \Hamcrest\NullDescription()
+ );
+ }
+
+ public function testCopesWithUnknownTypes()
+ {
+ //Should not generate any notices
+ $this->createMatcher()->matches(new UnknownType());
+ $this->createMatcher()->describeMismatch(
+ new UnknownType(),
+ new NullDescription()
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingInAnyOrderTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingInAnyOrderTest.php
new file mode 100644
index 0000000..45d9f13
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingInAnyOrderTest.php
@@ -0,0 +1,54 @@
+assertDescription('[<1>, <2>] in any order', containsInAnyOrder(array(1, 2)));
+ }
+
+ public function testMatchesItemsInAnyOrder()
+ {
+ $this->assertMatches(containsInAnyOrder(array(1, 2, 3)), array(1, 2, 3), 'in order');
+ $this->assertMatches(containsInAnyOrder(array(1, 2, 3)), array(3, 2, 1), 'out of order');
+ $this->assertMatches(containsInAnyOrder(array(1)), array(1), 'single');
+ }
+
+ public function testAppliesMatchersInAnyOrder()
+ {
+ $this->assertMatches(
+ containsInAnyOrder(array(1, 2, 3)),
+ array(1, 2, 3),
+ 'in order'
+ );
+ $this->assertMatches(
+ containsInAnyOrder(array(1, 2, 3)),
+ array(3, 2, 1),
+ 'out of order'
+ );
+ $this->assertMatches(
+ containsInAnyOrder(array(1)),
+ array(1),
+ 'single'
+ );
+ }
+
+ public function testMismatchesItemsInAnyOrder()
+ {
+ $matcher = containsInAnyOrder(array(1, 2, 3));
+
+ $this->assertMismatchDescription('was null', $matcher, null);
+ $this->assertMismatchDescription('No item matches: <1>, <2>, <3> in []', $matcher, array());
+ $this->assertMismatchDescription('No item matches: <2>, <3> in [<1>]', $matcher, array(1));
+ $this->assertMismatchDescription('Not matched: <4>', $matcher, array(4, 3, 2, 1));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingInOrderTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingInOrderTest.php
new file mode 100644
index 0000000..1868343
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingInOrderTest.php
@@ -0,0 +1,44 @@
+assertDescription('[<1>, <2>]', arrayContaining(array(1, 2)));
+ }
+
+ public function testMatchesItemsInOrder()
+ {
+ $this->assertMatches(arrayContaining(array(1, 2, 3)), array(1, 2, 3), 'in order');
+ $this->assertMatches(arrayContaining(array(1)), array(1), 'single');
+ }
+
+ public function testAppliesMatchersInOrder()
+ {
+ $this->assertMatches(
+ arrayContaining(array(1, 2, 3)),
+ array(1, 2, 3),
+ 'in order'
+ );
+ $this->assertMatches(arrayContaining(array(1)), array(1), 'single');
+ }
+
+ public function testMismatchesItemsInAnyOrder()
+ {
+ $matcher = arrayContaining(array(1, 2, 3));
+ $this->assertMismatchDescription('was null', $matcher, null);
+ $this->assertMismatchDescription('No item matched: <1>', $matcher, array());
+ $this->assertMismatchDescription('No item matched: <2>', $matcher, array(1));
+ $this->assertMismatchDescription('item with key 0: was <4>', $matcher, array(4, 3, 2, 1));
+ $this->assertMismatchDescription('item with key 2: was <4>', $matcher, array(1, 2, 4));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingKeyTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingKeyTest.php
new file mode 100644
index 0000000..31770d8
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingKeyTest.php
@@ -0,0 +1,62 @@
+1);
+
+ $this->assertMatches(hasKey('a'), $array, 'Matches single key');
+ }
+
+ public function testMatchesArrayContainingKey()
+ {
+ $array = array('a'=>1, 'b'=>2, 'c'=>3);
+
+ $this->assertMatches(hasKey('a'), $array, 'Matches a');
+ $this->assertMatches(hasKey('c'), $array, 'Matches c');
+ }
+
+ public function testMatchesArrayContainingKeyWithIntegerKeys()
+ {
+ $array = array(1=>'A', 2=>'B');
+
+ assertThat($array, hasKey(1));
+ }
+
+ public function testMatchesArrayContainingKeyWithNumberKeys()
+ {
+ $array = array(1=>'A', 2=>'B');
+
+ assertThat($array, hasKey(1));
+
+ // very ugly version!
+ assertThat($array, IsArrayContainingKey::hasKeyInArray(2));
+ }
+
+ public function testHasReadableDescription()
+ {
+ $this->assertDescription('array with key "a"', hasKey('a'));
+ }
+
+ public function testDoesNotMatchEmptyArray()
+ {
+ $this->assertMismatchDescription('array was []', hasKey('Foo'), array());
+ }
+
+ public function testDoesNotMatchArrayMissingKey()
+ {
+ $array = array('a'=>1, 'b'=>2, 'c'=>3);
+
+ $this->assertMismatchDescription('array was ["a" => <1>, "b" => <2>, "c" => <3>]', hasKey('d'), $array);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingKeyValuePairTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingKeyValuePairTest.php
new file mode 100644
index 0000000..a415f9f
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingKeyValuePairTest.php
@@ -0,0 +1,36 @@
+1, 'b'=>2);
+
+ $this->assertMatches(hasKeyValuePair(equalTo('a'), equalTo(1)), $array, 'matcherA');
+ $this->assertMatches(hasKeyValuePair(equalTo('b'), equalTo(2)), $array, 'matcherB');
+ $this->assertMismatchDescription(
+ 'array was ["a" => <1>, "b" => <2>]',
+ hasKeyValuePair(equalTo('c'), equalTo(3)),
+ $array
+ );
+ }
+
+ public function testDoesNotMatchNull()
+ {
+ $this->assertMismatchDescription('was null', hasKeyValuePair(anything(), anything()), null);
+ }
+
+ public function testHasReadableDescription()
+ {
+ $this->assertDescription('array containing ["a" => <2>]', hasKeyValuePair(equalTo('a'), equalTo(2)));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingTest.php
new file mode 100644
index 0000000..8d5bd81
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayContainingTest.php
@@ -0,0 +1,50 @@
+assertMatches(
+ hasItemInArray('a'),
+ array('a', 'b', 'c'),
+ "should matches array that contains 'a'"
+ );
+ }
+
+ public function testDoesNotMatchAnArrayThatDoesntContainAnElementMatchingTheGivenMatcher()
+ {
+ $this->assertDoesNotMatch(
+ hasItemInArray('a'),
+ array('b', 'c'),
+ "should not matches array that doesn't contain 'a'"
+ );
+ $this->assertDoesNotMatch(
+ hasItemInArray('a'),
+ array(),
+ 'should not match empty array'
+ );
+ }
+
+ public function testDoesNotMatchNull()
+ {
+ $this->assertDoesNotMatch(
+ hasItemInArray('a'),
+ null,
+ 'should not match null'
+ );
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription('an array containing "a"', hasItemInArray('a'));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayTest.php
new file mode 100644
index 0000000..e4db53e
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayTest.php
@@ -0,0 +1,89 @@
+assertMatches(
+ anArray(array(equalTo('a'), equalTo('b'), equalTo('c'))),
+ array('a', 'b', 'c'),
+ 'should match array with matching elements'
+ );
+ }
+
+ public function testDoesNotMatchAnArrayWhenElementsDoNotMatch()
+ {
+ $this->assertDoesNotMatch(
+ anArray(array(equalTo('a'), equalTo('b'))),
+ array('b', 'c'),
+ 'should not match array with different elements'
+ );
+ }
+
+ public function testDoesNotMatchAnArrayOfDifferentSize()
+ {
+ $this->assertDoesNotMatch(
+ anArray(array(equalTo('a'), equalTo('b'))),
+ array('a', 'b', 'c'),
+ 'should not match larger array'
+ );
+ $this->assertDoesNotMatch(
+ anArray(array(equalTo('a'), equalTo('b'))),
+ array('a'),
+ 'should not match smaller array'
+ );
+ }
+
+ public function testDoesNotMatchNull()
+ {
+ $this->assertDoesNotMatch(
+ anArray(array(equalTo('a'))),
+ null,
+ 'should not match null'
+ );
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription(
+ '["a", "b"]',
+ anArray(array(equalTo('a'), equalTo('b')))
+ );
+ }
+
+ public function testHasAReadableMismatchDescriptionWhenKeysDontMatch()
+ {
+ $this->assertMismatchDescription(
+ 'array keys were [<1>, <2>]',
+ anArray(array(equalTo('a'), equalTo('b'))),
+ array(1 => 'a', 2 => 'b')
+ );
+ }
+
+ public function testSupportsMatchesAssociativeArrays()
+ {
+ $this->assertMatches(
+ anArray(array('x'=>equalTo('a'), 'y'=>equalTo('b'), 'z'=>equalTo('c'))),
+ array('x'=>'a', 'y'=>'b', 'z'=>'c'),
+ 'should match associative array with matching elements'
+ );
+ }
+
+ public function testDoesNotMatchAnAssociativeArrayWhenKeysDoNotMatch()
+ {
+ $this->assertDoesNotMatch(
+ anArray(array('x'=>equalTo('a'), 'y'=>equalTo('b'))),
+ array('x'=>'b', 'z'=>'c'),
+ 'should not match array with different keys'
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayWithSizeTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayWithSizeTest.php
new file mode 100644
index 0000000..8413c89
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Array/IsArrayWithSizeTest.php
@@ -0,0 +1,37 @@
+assertMatches(arrayWithSize(equalTo(3)), array(1, 2, 3), 'correct size');
+ $this->assertDoesNotMatch(arrayWithSize(equalTo(2)), array(1, 2, 3), 'incorrect size');
+ }
+
+ public function testProvidesConvenientShortcutForArrayWithSizeEqualTo()
+ {
+ $this->assertMatches(arrayWithSize(3), array(1, 2, 3), 'correct size');
+ $this->assertDoesNotMatch(arrayWithSize(2), array(1, 2, 3), 'incorrect size');
+ }
+
+ public function testEmptyArray()
+ {
+ $this->assertMatches(emptyArray(), array(), 'correct size');
+ $this->assertDoesNotMatch(emptyArray(), array(1), 'incorrect size');
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription('an array with size <3>', arrayWithSize(equalTo(3)));
+ $this->assertDescription('an empty array', emptyArray());
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/BaseMatcherTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/BaseMatcherTest.php
new file mode 100644
index 0000000..833e2c3
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/BaseMatcherTest.php
@@ -0,0 +1,23 @@
+appendText('SOME DESCRIPTION');
+ }
+
+ public function testDescribesItselfWithToStringMethod()
+ {
+ $someMatcher = new \Hamcrest\SomeMatcher();
+ $this->assertEquals('SOME DESCRIPTION', (string) $someMatcher);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Collection/IsEmptyTraversableTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Collection/IsEmptyTraversableTest.php
new file mode 100644
index 0000000..2f15fb4
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Collection/IsEmptyTraversableTest.php
@@ -0,0 +1,77 @@
+assertMatches(
+ emptyTraversable(),
+ new \ArrayObject(array()),
+ 'an empty traversable'
+ );
+ }
+
+ public function testEmptyMatcherDoesNotMatchWhenNotEmpty()
+ {
+ $this->assertDoesNotMatch(
+ emptyTraversable(),
+ new \ArrayObject(array(1, 2, 3)),
+ 'a non-empty traversable'
+ );
+ }
+
+ public function testEmptyMatcherDoesNotMatchNull()
+ {
+ $this->assertDoesNotMatch(
+ emptyTraversable(),
+ null,
+ 'should not match null'
+ );
+ }
+
+ public function testEmptyMatcherHasAReadableDescription()
+ {
+ $this->assertDescription('an empty traversable', emptyTraversable());
+ }
+
+ public function testNonEmptyDoesNotMatchNull()
+ {
+ $this->assertDoesNotMatch(
+ nonEmptyTraversable(),
+ null,
+ 'should not match null'
+ );
+ }
+
+ public function testNonEmptyDoesNotMatchWhenEmpty()
+ {
+ $this->assertDoesNotMatch(
+ nonEmptyTraversable(),
+ new \ArrayObject(array()),
+ 'an empty traversable'
+ );
+ }
+
+ public function testNonEmptyMatchesWhenNotEmpty()
+ {
+ $this->assertMatches(
+ nonEmptyTraversable(),
+ new \ArrayObject(array(1, 2, 3)),
+ 'a non-empty traversable'
+ );
+ }
+
+ public function testNonEmptyNonEmptyMatcherHasAReadableDescription()
+ {
+ $this->assertDescription('a non-empty traversable', nonEmptyTraversable());
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Collection/IsTraversableWithSizeTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Collection/IsTraversableWithSizeTest.php
new file mode 100644
index 0000000..c1c67a7
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Collection/IsTraversableWithSizeTest.php
@@ -0,0 +1,57 @@
+assertMatches(
+ traversableWithSize(equalTo(3)),
+ new \ArrayObject(array(1, 2, 3)),
+ 'correct size'
+ );
+ }
+
+ public function testDoesNotMatchWhenSizeIsIncorrect()
+ {
+ $this->assertDoesNotMatch(
+ traversableWithSize(equalTo(2)),
+ new \ArrayObject(array(1, 2, 3)),
+ 'incorrect size'
+ );
+ }
+
+ public function testDoesNotMatchNull()
+ {
+ $this->assertDoesNotMatch(
+ traversableWithSize(3),
+ null,
+ 'should not match null'
+ );
+ }
+
+ public function testProvidesConvenientShortcutForTraversableWithSizeEqualTo()
+ {
+ $this->assertMatches(
+ traversableWithSize(3),
+ new \ArrayObject(array(1, 2, 3)),
+ 'correct size'
+ );
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription(
+ 'a traversable with size <3>',
+ traversableWithSize(equalTo(3))
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/AllOfTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/AllOfTest.php
new file mode 100644
index 0000000..86b8c27
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/AllOfTest.php
@@ -0,0 +1,56 @@
+assertDescription(
+ '("good" and "bad" and "ugly")',
+ allOf('good', 'bad', 'ugly')
+ );
+ }
+
+ public function testMismatchDescriptionDescribesFirstFailingMatch()
+ {
+ $this->assertMismatchDescription(
+ '"good" was "bad"',
+ allOf('bad', 'good'),
+ 'bad'
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/AnyOfTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/AnyOfTest.php
new file mode 100644
index 0000000..3d62b93
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/AnyOfTest.php
@@ -0,0 +1,79 @@
+assertDescription(
+ '("good" or "bad" or "ugly")',
+ anyOf('good', 'bad', 'ugly')
+ );
+ }
+
+ public function testNoneOfEvaluatesToTheLogicalDisjunctionOfTwoOtherMatchers()
+ {
+ assertThat('good', not(noneOf('bad', 'good')));
+ assertThat('good', not(noneOf('good', 'good')));
+ assertThat('good', not(noneOf('good', 'bad')));
+
+ assertThat('good', noneOf('bad', startsWith('b')));
+ }
+
+ public function testNoneOfEvaluatesToTheLogicalDisjunctionOfManyOtherMatchers()
+ {
+ assertThat('good', not(noneOf('bad', 'good', 'bad', 'bad', 'bad')));
+ assertThat('good', noneOf('bad', 'bad', 'bad', 'bad', 'bad'));
+ }
+
+ public function testNoneOfSupportsMixedTypes()
+ {
+ $combined = noneOf(
+ equalTo(new \Hamcrest\Core\SampleBaseClass('good')),
+ equalTo(new \Hamcrest\Core\SampleBaseClass('ugly')),
+ equalTo(new \Hamcrest\Core\SampleSubClass('good'))
+ );
+
+ assertThat(new \Hamcrest\Core\SampleSubClass('bad'), $combined);
+ }
+
+ public function testNoneOfHasAReadableDescription()
+ {
+ $this->assertDescription(
+ 'not ("good" or "bad" or "ugly")',
+ noneOf('good', 'bad', 'ugly')
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/CombinableMatcherTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/CombinableMatcherTest.php
new file mode 100644
index 0000000..4c22614
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/CombinableMatcherTest.php
@@ -0,0 +1,59 @@
+_either_3_or_4 = \Hamcrest\Core\CombinableMatcher::either(equalTo(3))->orElse(equalTo(4));
+ $this->_not_3_and_not_4 = \Hamcrest\Core\CombinableMatcher::both(not(equalTo(3)))->andAlso(not(equalTo(4)));
+ }
+
+ protected function createMatcher()
+ {
+ return \Hamcrest\Core\CombinableMatcher::either(equalTo('irrelevant'))->orElse(equalTo('ignored'));
+ }
+
+ public function testBothAcceptsAndRejects()
+ {
+ assertThat(2, $this->_not_3_and_not_4);
+ assertThat(3, not($this->_not_3_and_not_4));
+ }
+
+ public function testAcceptsAndRejectsThreeAnds()
+ {
+ $tripleAnd = $this->_not_3_and_not_4->andAlso(equalTo(2));
+ assertThat(2, $tripleAnd);
+ assertThat(3, not($tripleAnd));
+ }
+
+ public function testBothDescribesItself()
+ {
+ $this->assertEquals('(not <3> and not <4>)', (string) $this->_not_3_and_not_4);
+ $this->assertMismatchDescription('was <3>', $this->_not_3_and_not_4, 3);
+ }
+
+ public function testEitherAcceptsAndRejects()
+ {
+ assertThat(3, $this->_either_3_or_4);
+ assertThat(6, not($this->_either_3_or_4));
+ }
+
+ public function testAcceptsAndRejectsThreeOrs()
+ {
+ $orTriple = $this->_either_3_or_4->orElse(greaterThan(10));
+
+ assertThat(11, $orTriple);
+ assertThat(9, not($orTriple));
+ }
+
+ public function testEitherDescribesItself()
+ {
+ $this->assertEquals('(<3> or <4>)', (string) $this->_either_3_or_4);
+ $this->assertMismatchDescription('was <6>', $this->_either_3_or_4, 6);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/DescribedAsTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/DescribedAsTest.php
new file mode 100644
index 0000000..673ab41
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/DescribedAsTest.php
@@ -0,0 +1,36 @@
+assertDescription('m1 description', $m1);
+ $this->assertDescription('m2 description', $m2);
+ }
+
+ public function testAppendsValuesToDescription()
+ {
+ $m = describedAs('value 1 = %0, value 2 = %1', anything(), 33, 97);
+
+ $this->assertDescription('value 1 = <33>, value 2 = <97>', $m);
+ }
+
+ public function testDelegatesMatchingToAnotherMatcher()
+ {
+ $m1 = describedAs('irrelevant', anything());
+ $m2 = describedAs('irrelevant', not(anything()));
+
+ $this->assertTrue($m1->matches(new \stdClass()));
+ $this->assertFalse($m2->matches('hi'));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/EveryTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/EveryTest.php
new file mode 100644
index 0000000..5eb153c
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/EveryTest.php
@@ -0,0 +1,30 @@
+assertEquals('every item is a string containing "a"', (string) $each);
+
+ $this->assertMismatchDescription('an item was "BbB"', $each, array('BbB'));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/HasToStringTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/HasToStringTest.php
new file mode 100644
index 0000000..e2e136d
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/HasToStringTest.php
@@ -0,0 +1,108 @@
+assertMatches(
+ hasToString(equalTo('php')),
+ new \Hamcrest\Core\PhpForm(),
+ 'correct __toString'
+ );
+ $this->assertMatches(
+ hasToString(equalTo('java')),
+ new \Hamcrest\Core\JavaForm(),
+ 'correct toString'
+ );
+ }
+
+ public function testPicksJavaOverPhpToString()
+ {
+ $this->assertMatches(
+ hasToString(equalTo('java')),
+ new \Hamcrest\Core\BothForms(),
+ 'correct toString'
+ );
+ }
+
+ public function testDoesNotMatchWhenToStringDoesNotMatch()
+ {
+ $this->assertDoesNotMatch(
+ hasToString(equalTo('mismatch')),
+ new \Hamcrest\Core\PhpForm(),
+ 'incorrect __toString'
+ );
+ $this->assertDoesNotMatch(
+ hasToString(equalTo('mismatch')),
+ new \Hamcrest\Core\JavaForm(),
+ 'incorrect toString'
+ );
+ $this->assertDoesNotMatch(
+ hasToString(equalTo('mismatch')),
+ new \Hamcrest\Core\BothForms(),
+ 'incorrect __toString'
+ );
+ }
+
+ public function testDoesNotMatchNull()
+ {
+ $this->assertDoesNotMatch(
+ hasToString(equalTo('a')),
+ null,
+ 'should not match null'
+ );
+ }
+
+ public function testProvidesConvenientShortcutForTraversableWithSizeEqualTo()
+ {
+ $this->assertMatches(
+ hasToString(equalTo('php')),
+ new \Hamcrest\Core\PhpForm(),
+ 'correct __toString'
+ );
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription(
+ 'an object with toString() "php"',
+ hasToString(equalTo('php'))
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsAnythingTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsAnythingTest.php
new file mode 100644
index 0000000..f68032e
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsAnythingTest.php
@@ -0,0 +1,29 @@
+assertDescription('ANYTHING', anything());
+ }
+
+ public function testCanOverrideDescription()
+ {
+ $description = 'description';
+ $this->assertDescription($description, anything($description));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsCollectionContainingTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsCollectionContainingTest.php
new file mode 100644
index 0000000..a3929b5
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsCollectionContainingTest.php
@@ -0,0 +1,91 @@
+assertMatches(
+ $itemMatcher,
+ array('a', 'b', 'c'),
+ "should match list that contains 'a'"
+ );
+ }
+
+ public function testDoesNotMatchCollectionThatDoesntContainAnElementMatchingTheGivenMatcher()
+ {
+ $matcher1 = hasItem(equalTo('a'));
+ $this->assertDoesNotMatch(
+ $matcher1,
+ array('b', 'c'),
+ "should not match list that doesn't contain 'a'"
+ );
+
+ $matcher2 = hasItem(equalTo('a'));
+ $this->assertDoesNotMatch(
+ $matcher2,
+ array(),
+ 'should not match the empty list'
+ );
+ }
+
+ public function testDoesNotMatchNull()
+ {
+ $this->assertDoesNotMatch(
+ hasItem(equalTo('a')),
+ null,
+ 'should not match null'
+ );
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription('a collection containing "a"', hasItem(equalTo('a')));
+ }
+
+ public function testMatchesAllItemsInCollection()
+ {
+ $matcher1 = hasItems(equalTo('a'), equalTo('b'), equalTo('c'));
+ $this->assertMatches(
+ $matcher1,
+ array('a', 'b', 'c'),
+ 'should match list containing all items'
+ );
+
+ $matcher2 = hasItems('a', 'b', 'c');
+ $this->assertMatches(
+ $matcher2,
+ array('a', 'b', 'c'),
+ 'should match list containing all items (without matchers)'
+ );
+
+ $matcher3 = hasItems(equalTo('a'), equalTo('b'), equalTo('c'));
+ $this->assertMatches(
+ $matcher3,
+ array('c', 'b', 'a'),
+ 'should match list containing all items in any order'
+ );
+
+ $matcher4 = hasItems(equalTo('a'), equalTo('b'), equalTo('c'));
+ $this->assertMatches(
+ $matcher4,
+ array('e', 'c', 'b', 'a', 'd'),
+ 'should match list containing all items plus others'
+ );
+
+ $matcher5 = hasItems(equalTo('a'), equalTo('b'), equalTo('c'));
+ $this->assertDoesNotMatch(
+ $matcher5,
+ array('e', 'c', 'b', 'd'), // 'a' missing
+ 'should not match list unless it contains all items'
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsEqualTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsEqualTest.php
new file mode 100644
index 0000000..73e3ff0
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsEqualTest.php
@@ -0,0 +1,102 @@
+_arg = $arg;
+ }
+
+ public function __toString()
+ {
+ return $this->_arg;
+ }
+}
+
+class IsEqualTest extends \Hamcrest\AbstractMatcherTest
+{
+
+ protected function createMatcher()
+ {
+ return \Hamcrest\Core\IsEqual::equalTo('irrelevant');
+ }
+
+ public function testComparesObjectsUsingEqualityOperator()
+ {
+ assertThat("hi", equalTo("hi"));
+ assertThat("bye", not(equalTo("hi")));
+
+ assertThat(1, equalTo(1));
+ assertThat(1, not(equalTo(2)));
+
+ assertThat("2", equalTo(2));
+ }
+
+ public function testCanCompareNullValues()
+ {
+ assertThat(null, equalTo(null));
+
+ assertThat(null, not(equalTo('hi')));
+ assertThat('hi', not(equalTo(null)));
+ }
+
+ public function testComparesTheElementsOfAnArray()
+ {
+ $s1 = array('a', 'b');
+ $s2 = array('a', 'b');
+ $s3 = array('c', 'd');
+ $s4 = array('a', 'b', 'c', 'd');
+
+ assertThat($s1, equalTo($s1));
+ assertThat($s2, equalTo($s1));
+ assertThat($s3, not(equalTo($s1)));
+ assertThat($s4, not(equalTo($s1)));
+ }
+
+ public function testComparesTheElementsOfAnArrayOfPrimitiveTypes()
+ {
+ $i1 = array(1, 2);
+ $i2 = array(1, 2);
+ $i3 = array(3, 4);
+ $i4 = array(1, 2, 3, 4);
+
+ assertThat($i1, equalTo($i1));
+ assertThat($i2, equalTo($i1));
+ assertThat($i3, not(equalTo($i1)));
+ assertThat($i4, not(equalTo($i1)));
+ }
+
+ public function testRecursivelyTestsElementsOfArrays()
+ {
+ $i1 = array(array(1, 2), array(3, 4));
+ $i2 = array(array(1, 2), array(3, 4));
+ $i3 = array(array(5, 6), array(7, 8));
+ $i4 = array(array(1, 2, 3, 4), array(3, 4));
+
+ assertThat($i1, equalTo($i1));
+ assertThat($i2, equalTo($i1));
+ assertThat($i3, not(equalTo($i1)));
+ assertThat($i4, not(equalTo($i1)));
+ }
+
+ public function testIncludesTheResultOfCallingToStringOnItsArgumentInTheDescription()
+ {
+ $argumentDescription = 'ARGUMENT DESCRIPTION';
+ $argument = new \Hamcrest\Core\DummyToStringClass($argumentDescription);
+ $this->assertDescription('<' . $argumentDescription . '>', equalTo($argument));
+ }
+
+ public function testReturnsAnObviousDescriptionIfCreatedWithANestedMatcherByMistake()
+ {
+ $innerMatcher = equalTo('NestedMatcher');
+ $this->assertDescription('<' . (string) $innerMatcher . '>', equalTo($innerMatcher));
+ }
+
+ public function testReturnsGoodDescriptionIfCreatedWithNullReference()
+ {
+ $this->assertDescription('null', equalTo(null));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsIdenticalTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsIdenticalTest.php
new file mode 100644
index 0000000..9cc2794
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsIdenticalTest.php
@@ -0,0 +1,30 @@
+assertDescription('"ARG"', identicalTo('ARG'));
+ }
+
+ public function testReturnsReadableDescriptionFromToStringWhenInitialisedWithNull()
+ {
+ $this->assertDescription('null', identicalTo(null));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsInstanceOfTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsInstanceOfTest.php
new file mode 100644
index 0000000..7a5f095
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsInstanceOfTest.php
@@ -0,0 +1,51 @@
+_baseClassInstance = new \Hamcrest\Core\SampleBaseClass('good');
+ $this->_subClassInstance = new \Hamcrest\Core\SampleSubClass('good');
+ }
+
+ protected function createMatcher()
+ {
+ return \Hamcrest\Core\IsInstanceOf::anInstanceOf('stdClass');
+ }
+
+ public function testEvaluatesToTrueIfArgumentIsInstanceOfASpecificClass()
+ {
+ assertThat($this->_baseClassInstance, anInstanceOf('Hamcrest\Core\SampleBaseClass'));
+ assertThat($this->_subClassInstance, anInstanceOf('Hamcrest\Core\SampleSubClass'));
+ assertThat(null, not(anInstanceOf('Hamcrest\Core\SampleBaseClass')));
+ assertThat(new \stdClass(), not(anInstanceOf('Hamcrest\Core\SampleBaseClass')));
+ }
+
+ public function testEvaluatesToFalseIfArgumentIsNotAnObject()
+ {
+ assertThat(null, not(anInstanceOf('Hamcrest\Core\SampleBaseClass')));
+ assertThat(false, not(anInstanceOf('Hamcrest\Core\SampleBaseClass')));
+ assertThat(5, not(anInstanceOf('Hamcrest\Core\SampleBaseClass')));
+ assertThat('foo', not(anInstanceOf('Hamcrest\Core\SampleBaseClass')));
+ assertThat(array(1, 2, 3), not(anInstanceOf('Hamcrest\Core\SampleBaseClass')));
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription('an instance of stdClass', anInstanceOf('stdClass'));
+ }
+
+ public function testDecribesActualClassInMismatchMessage()
+ {
+ $this->assertMismatchDescription(
+ '[Hamcrest\Core\SampleBaseClass] ',
+ anInstanceOf('Hamcrest\Core\SampleSubClass'),
+ $this->_baseClassInstance
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsNotTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsNotTest.php
new file mode 100644
index 0000000..09d4a65
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsNotTest.php
@@ -0,0 +1,31 @@
+assertMatches(not(equalTo('A')), 'B', 'should match');
+ $this->assertDoesNotMatch(not(equalTo('B')), 'B', 'should not match');
+ }
+
+ public function testProvidesConvenientShortcutForNotEqualTo()
+ {
+ $this->assertMatches(not('A'), 'B', 'should match');
+ $this->assertMatches(not('B'), 'A', 'should match');
+ $this->assertDoesNotMatch(not('A'), 'A', 'should not match');
+ $this->assertDoesNotMatch(not('B'), 'B', 'should not match');
+ }
+
+ public function testUsesDescriptionOfNegatedMatcherWithPrefix()
+ {
+ $this->assertDescription('not a value greater than <2>', not(greaterThan(2)));
+ $this->assertDescription('not "A"', not('A'));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsNullTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsNullTest.php
new file mode 100644
index 0000000..bfa4255
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsNullTest.php
@@ -0,0 +1,20 @@
+assertDescription('sameInstance("ARG")', sameInstance('ARG'));
+ }
+
+ public function testReturnsReadableDescriptionFromToStringWhenInitialisedWithNull()
+ {
+ $this->assertDescription('sameInstance(null)', sameInstance(null));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsTest.php
new file mode 100644
index 0000000..bbd848b
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsTest.php
@@ -0,0 +1,33 @@
+assertMatches(is(equalTo(true)), true, 'should match');
+ $this->assertMatches(is(equalTo(false)), false, 'should match');
+ $this->assertDoesNotMatch(is(equalTo(true)), false, 'should not match');
+ $this->assertDoesNotMatch(is(equalTo(false)), true, 'should not match');
+ }
+
+ public function testGeneratesIsPrefixInDescription()
+ {
+ $this->assertDescription('is ', is(equalTo(true)));
+ }
+
+ public function testProvidesConvenientShortcutForIsEqualTo()
+ {
+ $this->assertMatches(is('A'), 'A', 'should match');
+ $this->assertMatches(is('B'), 'B', 'should match');
+ $this->assertDoesNotMatch(is('A'), 'B', 'should not match');
+ $this->assertDoesNotMatch(is('B'), 'A', 'should not match');
+ $this->assertDescription('is "A"', is('A'));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsTypeOfTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsTypeOfTest.php
new file mode 100644
index 0000000..3f48dea
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/IsTypeOfTest.php
@@ -0,0 +1,45 @@
+assertDescription('a double', typeOf('double'));
+ $this->assertDescription('an integer', typeOf('integer'));
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', typeOf('boolean'), null);
+ $this->assertMismatchDescription('was an integer <5>', typeOf('float'), 5);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/SampleBaseClass.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/SampleBaseClass.php
new file mode 100644
index 0000000..c953e7c
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/SampleBaseClass.php
@@ -0,0 +1,18 @@
+_arg = $arg;
+ }
+
+ public function __toString()
+ {
+ return $this->_arg;
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/SampleSubClass.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/SampleSubClass.php
new file mode 100644
index 0000000..822f1b6
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Core/SampleSubClass.php
@@ -0,0 +1,6 @@
+_instanceProperty);
+ }
+
+ protected function createMatcher()
+ {
+ return \Hamcrest\Core\Set::set('property_name');
+ }
+
+ public function testEvaluatesToTrueIfArrayPropertyIsSet()
+ {
+ assertThat(array('foo' => 'bar'), set('foo'));
+ }
+
+ public function testNegatedEvaluatesToFalseIfArrayPropertyIsSet()
+ {
+ assertThat(array('foo' => 'bar'), not(notSet('foo')));
+ }
+
+ public function testEvaluatesToTrueIfClassPropertyIsSet()
+ {
+ self::$_classProperty = 'bar';
+ assertThat('Hamcrest\Core\SetTest', set('_classProperty'));
+ }
+
+ public function testNegatedEvaluatesToFalseIfClassPropertyIsSet()
+ {
+ self::$_classProperty = 'bar';
+ assertThat('Hamcrest\Core\SetTest', not(notSet('_classProperty')));
+ }
+
+ public function testEvaluatesToTrueIfObjectPropertyIsSet()
+ {
+ $this->_instanceProperty = 'bar';
+ assertThat($this, set('_instanceProperty'));
+ }
+
+ public function testNegatedEvaluatesToFalseIfObjectPropertyIsSet()
+ {
+ $this->_instanceProperty = 'bar';
+ assertThat($this, not(notSet('_instanceProperty')));
+ }
+
+ public function testEvaluatesToFalseIfArrayPropertyIsNotSet()
+ {
+ assertThat(array('foo' => 'bar'), not(set('baz')));
+ }
+
+ public function testNegatedEvaluatesToTrueIfArrayPropertyIsNotSet()
+ {
+ assertThat(array('foo' => 'bar'), notSet('baz'));
+ }
+
+ public function testEvaluatesToFalseIfClassPropertyIsNotSet()
+ {
+ assertThat('Hamcrest\Core\SetTest', not(set('_classProperty')));
+ }
+
+ public function testNegatedEvaluatesToTrueIfClassPropertyIsNotSet()
+ {
+ assertThat('Hamcrest\Core\SetTest', notSet('_classProperty'));
+ }
+
+ public function testEvaluatesToFalseIfObjectPropertyIsNotSet()
+ {
+ assertThat($this, not(set('_instanceProperty')));
+ }
+
+ public function testNegatedEvaluatesToTrueIfObjectPropertyIsNotSet()
+ {
+ assertThat($this, notSet('_instanceProperty'));
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription('set property foo', set('foo'));
+ $this->assertDescription('unset property bar', notSet('bar'));
+ }
+
+ public function testDecribesPropertySettingInMismatchMessage()
+ {
+ $this->assertMismatchDescription(
+ 'was not set',
+ set('bar'),
+ array('foo' => 'bar')
+ );
+ $this->assertMismatchDescription(
+ 'was "bar"',
+ notSet('foo'),
+ array('foo' => 'bar')
+ );
+ self::$_classProperty = 'bar';
+ $this->assertMismatchDescription(
+ 'was "bar"',
+ notSet('_classProperty'),
+ 'Hamcrest\Core\SetTest'
+ );
+ $this->_instanceProperty = 'bar';
+ $this->assertMismatchDescription(
+ 'was "bar"',
+ notSet('_instanceProperty'),
+ $this
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/FeatureMatcherTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/FeatureMatcherTest.php
new file mode 100644
index 0000000..7543294
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/FeatureMatcherTest.php
@@ -0,0 +1,73 @@
+_result = $result;
+ }
+ public function getResult()
+ {
+ return $this->_result;
+ }
+}
+
+/* Test-specific subclass only */
+class ResultMatcher extends \Hamcrest\FeatureMatcher
+{
+ public function __construct()
+ {
+ parent::__construct(self::TYPE_ANY, null, equalTo('bar'), 'Thingy with result', 'result');
+ }
+ public function featureValueOf($actual)
+ {
+ if ($actual instanceof \Hamcrest\Thingy) {
+ return $actual->getResult();
+ }
+ }
+}
+
+class FeatureMatcherTest extends \Hamcrest\AbstractMatcherTest
+{
+
+ private $_resultMatcher;
+
+ public function setUp()
+ {
+ $this->_resultMatcher = $this->_resultMatcher();
+ }
+
+ protected function createMatcher()
+ {
+ return $this->_resultMatcher();
+ }
+
+ public function testMatchesPartOfAnObject()
+ {
+ $this->assertMatches($this->_resultMatcher, new \Hamcrest\Thingy('bar'), 'feature');
+ $this->assertDescription('Thingy with result "bar"', $this->_resultMatcher);
+ }
+
+ public function testMismatchesPartOfAnObject()
+ {
+ $this->assertMismatchDescription(
+ 'result was "foo"',
+ $this->_resultMatcher,
+ new \Hamcrest\Thingy('foo')
+ );
+ }
+
+ public function testDoesNotGenerateNoticesForNull()
+ {
+ $this->assertMismatchDescription('result was null', $this->_resultMatcher, null);
+ }
+
+ // -- Creation Methods
+
+ private function _resultMatcher()
+ {
+ return new \Hamcrest\ResultMatcher();
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/MatcherAssertTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/MatcherAssertTest.php
new file mode 100644
index 0000000..2183712
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/MatcherAssertTest.php
@@ -0,0 +1,190 @@
+getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat(null);
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('', $ex->getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat('');
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('', $ex->getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat(0);
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('', $ex->getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat(0.0);
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('', $ex->getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat(array());
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('', $ex->getMessage());
+ }
+ self::assertEquals(6, \Hamcrest\MatcherAssert::getCount(), 'assertion count');
+ }
+
+ public function testAssertThatWithIdentifierAndTrueArgPasses()
+ {
+ \Hamcrest\MatcherAssert::assertThat('identifier', true);
+ \Hamcrest\MatcherAssert::assertThat('identifier', 'non-empty');
+ \Hamcrest\MatcherAssert::assertThat('identifier', 1);
+ \Hamcrest\MatcherAssert::assertThat('identifier', 3.14159);
+ \Hamcrest\MatcherAssert::assertThat('identifier', array(true));
+ self::assertEquals(5, \Hamcrest\MatcherAssert::getCount(), 'assertion count');
+ }
+
+ public function testAssertThatWithIdentifierAndFalseArgFails()
+ {
+ try {
+ \Hamcrest\MatcherAssert::assertThat('identifier', false);
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('identifier', $ex->getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat('identifier', null);
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('identifier', $ex->getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat('identifier', '');
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('identifier', $ex->getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat('identifier', 0);
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('identifier', $ex->getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat('identifier', 0.0);
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('identifier', $ex->getMessage());
+ }
+ try {
+ \Hamcrest\MatcherAssert::assertThat('identifier', array());
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals('identifier', $ex->getMessage());
+ }
+ self::assertEquals(6, \Hamcrest\MatcherAssert::getCount(), 'assertion count');
+ }
+
+ public function testAssertThatWithActualValueAndMatcherArgsThatMatchPasses()
+ {
+ \Hamcrest\MatcherAssert::assertThat(true, is(true));
+ self::assertEquals(1, \Hamcrest\MatcherAssert::getCount(), 'assertion count');
+ }
+
+ public function testAssertThatWithActualValueAndMatcherArgsThatDontMatchFails()
+ {
+ $expected = 'expected';
+ $actual = 'actual';
+
+ $expectedMessage =
+ 'Expected: "expected"' . PHP_EOL .
+ ' but: was "actual"';
+
+ try {
+ \Hamcrest\MatcherAssert::assertThat($actual, equalTo($expected));
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals($expectedMessage, $ex->getMessage());
+ self::assertEquals(1, \Hamcrest\MatcherAssert::getCount(), 'assertion count');
+ }
+ }
+
+ public function testAssertThatWithIdentifierAndActualValueAndMatcherArgsThatMatchPasses()
+ {
+ \Hamcrest\MatcherAssert::assertThat('identifier', true, is(true));
+ self::assertEquals(1, \Hamcrest\MatcherAssert::getCount(), 'assertion count');
+ }
+
+ public function testAssertThatWithIdentifierAndActualValueAndMatcherArgsThatDontMatchFails()
+ {
+ $expected = 'expected';
+ $actual = 'actual';
+
+ $expectedMessage =
+ 'identifier' . PHP_EOL .
+ 'Expected: "expected"' . PHP_EOL .
+ ' but: was "actual"';
+
+ try {
+ \Hamcrest\MatcherAssert::assertThat('identifier', $actual, equalTo($expected));
+ self::fail('expected assertion failure');
+ } catch (\Hamcrest\AssertionError $ex) {
+ self::assertEquals($expectedMessage, $ex->getMessage());
+ self::assertEquals(1, \Hamcrest\MatcherAssert::getCount(), 'assertion count');
+ }
+ }
+
+ public function testAssertThatWithNoArgsThrowsErrorAndDoesntIncrementCount()
+ {
+ try {
+ \Hamcrest\MatcherAssert::assertThat();
+ self::fail('expected invalid argument exception');
+ } catch (\InvalidArgumentException $ex) {
+ self::assertEquals(0, \Hamcrest\MatcherAssert::getCount(), 'assertion count');
+ }
+ }
+
+ public function testAssertThatWithFourArgsThrowsErrorAndDoesntIncrementCount()
+ {
+ try {
+ \Hamcrest\MatcherAssert::assertThat(1, 2, 3, 4);
+ self::fail('expected invalid argument exception');
+ } catch (\InvalidArgumentException $ex) {
+ self::assertEquals(0, \Hamcrest\MatcherAssert::getCount(), 'assertion count');
+ }
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Number/IsCloseToTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Number/IsCloseToTest.php
new file mode 100644
index 0000000..987d552
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Number/IsCloseToTest.php
@@ -0,0 +1,27 @@
+assertTrue($p->matches(1.0));
+ $this->assertTrue($p->matches(0.5));
+ $this->assertTrue($p->matches(1.5));
+
+ $this->assertDoesNotMatch($p, 2.0, 'too large');
+ $this->assertMismatchDescription('<2F> differed by <0.5F>', $p, 2.0);
+ $this->assertDoesNotMatch($p, 0.0, 'number too small');
+ $this->assertMismatchDescription('<0F> differed by <0.5F>', $p, 0.0);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Number/OrderingComparisonTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Number/OrderingComparisonTest.php
new file mode 100644
index 0000000..a4c94d3
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Number/OrderingComparisonTest.php
@@ -0,0 +1,41 @@
+_text = $text;
+ }
+
+ public function describeTo(\Hamcrest\Description $description)
+ {
+ $description->appendText($this->_text);
+ }
+}
+
+class StringDescriptionTest extends \PhpUnit_Framework_TestCase
+{
+
+ private $_description;
+
+ public function setUp()
+ {
+ $this->_description = new \Hamcrest\StringDescription();
+ }
+
+ public function testAppendTextAppendsTextInformation()
+ {
+ $this->_description->appendText('foo')->appendText('bar');
+ $this->assertEquals('foobar', (string) $this->_description);
+ }
+
+ public function testAppendValueCanAppendTextTypes()
+ {
+ $this->_description->appendValue('foo');
+ $this->assertEquals('"foo"', (string) $this->_description);
+ }
+
+ public function testSpecialCharactersAreEscapedForStringTypes()
+ {
+ $this->_description->appendValue("foo\\bar\"zip\r\n");
+ $this->assertEquals('"foo\\bar\\"zip\r\n"', (string) $this->_description);
+ }
+
+ public function testIntegerValuesCanBeAppended()
+ {
+ $this->_description->appendValue(42);
+ $this->assertEquals('<42>', (string) $this->_description);
+ }
+
+ public function testFloatValuesCanBeAppended()
+ {
+ $this->_description->appendValue(42.78);
+ $this->assertEquals('<42.78F>', (string) $this->_description);
+ }
+
+ public function testNullValuesCanBeAppended()
+ {
+ $this->_description->appendValue(null);
+ $this->assertEquals('null', (string) $this->_description);
+ }
+
+ public function testArraysCanBeAppended()
+ {
+ $this->_description->appendValue(array('foo', 42.78));
+ $this->assertEquals('["foo", <42.78F>]', (string) $this->_description);
+ }
+
+ public function testObjectsCanBeAppended()
+ {
+ $this->_description->appendValue(new \stdClass());
+ $this->assertEquals('', (string) $this->_description);
+ }
+
+ public function testBooleanValuesCanBeAppended()
+ {
+ $this->_description->appendValue(false);
+ $this->assertEquals('', (string) $this->_description);
+ }
+
+ public function testListsOfvaluesCanBeAppended()
+ {
+ $this->_description->appendValue(array('foo', 42.78));
+ $this->assertEquals('["foo", <42.78F>]', (string) $this->_description);
+ }
+
+ public function testIterableOfvaluesCanBeAppended()
+ {
+ $items = new \ArrayObject(array('foo', 42.78));
+ $this->_description->appendValue($items);
+ $this->assertEquals('["foo", <42.78F>]', (string) $this->_description);
+ }
+
+ public function testIteratorOfvaluesCanBeAppended()
+ {
+ $items = new \ArrayObject(array('foo', 42.78));
+ $this->_description->appendValue($items->getIterator());
+ $this->assertEquals('["foo", <42.78F>]', (string) $this->_description);
+ }
+
+ public function testListsOfvaluesCanBeAppendedManually()
+ {
+ $this->_description->appendValueList('@start@', '@sep@ ', '@end@', array('foo', 42.78));
+ $this->assertEquals('@start@"foo"@sep@ <42.78F>@end@', (string) $this->_description);
+ }
+
+ public function testIterableOfvaluesCanBeAppendedManually()
+ {
+ $items = new \ArrayObject(array('foo', 42.78));
+ $this->_description->appendValueList('@start@', '@sep@ ', '@end@', $items);
+ $this->assertEquals('@start@"foo"@sep@ <42.78F>@end@', (string) $this->_description);
+ }
+
+ public function testIteratorOfvaluesCanBeAppendedManually()
+ {
+ $items = new \ArrayObject(array('foo', 42.78));
+ $this->_description->appendValueList('@start@', '@sep@ ', '@end@', $items->getIterator());
+ $this->assertEquals('@start@"foo"@sep@ <42.78F>@end@', (string) $this->_description);
+ }
+
+ public function testSelfDescribingObjectsCanBeAppended()
+ {
+ $this->_description
+ ->appendDescriptionOf(new \Hamcrest\SampleSelfDescriber('foo'))
+ ->appendDescriptionOf(new \Hamcrest\SampleSelfDescriber('bar'))
+ ;
+ $this->assertEquals('foobar', (string) $this->_description);
+ }
+
+ public function testSelfDescribingObjectsCanBeAppendedAsLists()
+ {
+ $this->_description->appendList('@start@', '@sep@ ', '@end@', array(
+ new \Hamcrest\SampleSelfDescriber('foo'),
+ new \Hamcrest\SampleSelfDescriber('bar')
+ ));
+ $this->assertEquals('@start@foo@sep@ bar@end@', (string) $this->_description);
+ }
+
+ public function testSelfDescribingObjectsCanBeAppendedAsIteratedLists()
+ {
+ $items = new \ArrayObject(array(
+ new \Hamcrest\SampleSelfDescriber('foo'),
+ new \Hamcrest\SampleSelfDescriber('bar')
+ ));
+ $this->_description->appendList('@start@', '@sep@ ', '@end@', $items);
+ $this->assertEquals('@start@foo@sep@ bar@end@', (string) $this->_description);
+ }
+
+ public function testSelfDescribingObjectsCanBeAppendedAsIterators()
+ {
+ $items = new \ArrayObject(array(
+ new \Hamcrest\SampleSelfDescriber('foo'),
+ new \Hamcrest\SampleSelfDescriber('bar')
+ ));
+ $this->_description->appendList('@start@', '@sep@ ', '@end@', $items->getIterator());
+ $this->assertEquals('@start@foo@sep@ bar@end@', (string) $this->_description);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/IsEmptyStringTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/IsEmptyStringTest.php
new file mode 100644
index 0000000..8d5c56b
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/IsEmptyStringTest.php
@@ -0,0 +1,86 @@
+assertDoesNotMatch(emptyString(), null, 'null');
+ }
+
+ public function testEmptyDoesNotMatchZero()
+ {
+ $this->assertDoesNotMatch(emptyString(), 0, 'zero');
+ }
+
+ public function testEmptyDoesNotMatchFalse()
+ {
+ $this->assertDoesNotMatch(emptyString(), false, 'false');
+ }
+
+ public function testEmptyDoesNotMatchEmptyArray()
+ {
+ $this->assertDoesNotMatch(emptyString(), array(), 'empty array');
+ }
+
+ public function testEmptyMatchesEmptyString()
+ {
+ $this->assertMatches(emptyString(), '', 'empty string');
+ }
+
+ public function testEmptyDoesNotMatchNonEmptyString()
+ {
+ $this->assertDoesNotMatch(emptyString(), 'foo', 'non-empty string');
+ }
+
+ public function testEmptyHasAReadableDescription()
+ {
+ $this->assertDescription('an empty string', emptyString());
+ }
+
+ public function testEmptyOrNullMatchesNull()
+ {
+ $this->assertMatches(nullOrEmptyString(), null, 'null');
+ }
+
+ public function testEmptyOrNullMatchesEmptyString()
+ {
+ $this->assertMatches(nullOrEmptyString(), '', 'empty string');
+ }
+
+ public function testEmptyOrNullDoesNotMatchNonEmptyString()
+ {
+ $this->assertDoesNotMatch(nullOrEmptyString(), 'foo', 'non-empty string');
+ }
+
+ public function testEmptyOrNullHasAReadableDescription()
+ {
+ $this->assertDescription('(null or an empty string)', nullOrEmptyString());
+ }
+
+ public function testNonEmptyDoesNotMatchNull()
+ {
+ $this->assertDoesNotMatch(nonEmptyString(), null, 'null');
+ }
+
+ public function testNonEmptyDoesNotMatchEmptyString()
+ {
+ $this->assertDoesNotMatch(nonEmptyString(), '', 'empty string');
+ }
+
+ public function testNonEmptyMatchesNonEmptyString()
+ {
+ $this->assertMatches(nonEmptyString(), 'foo', 'non-empty string');
+ }
+
+ public function testNonEmptyHasAReadableDescription()
+ {
+ $this->assertDescription('a non-empty string', nonEmptyString());
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/IsEqualIgnoringCaseTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/IsEqualIgnoringCaseTest.php
new file mode 100644
index 0000000..0539fd5
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/IsEqualIgnoringCaseTest.php
@@ -0,0 +1,40 @@
+assertDescription(
+ 'equalToIgnoringCase("heLLo")',
+ equalToIgnoringCase('heLLo')
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/IsEqualIgnoringWhiteSpaceTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/IsEqualIgnoringWhiteSpaceTest.php
new file mode 100644
index 0000000..6c2304f
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/IsEqualIgnoringWhiteSpaceTest.php
@@ -0,0 +1,51 @@
+_matcher = \Hamcrest\Text\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace(
+ "Hello World how\n are we? "
+ );
+ }
+
+ protected function createMatcher()
+ {
+ return $this->_matcher;
+ }
+
+ public function testPassesIfWordsAreSameButWhitespaceDiffers()
+ {
+ assertThat('Hello World how are we?', $this->_matcher);
+ assertThat(" Hello \rWorld \t how are\nwe?", $this->_matcher);
+ }
+
+ public function testFailsIfTextOtherThanWhitespaceDiffers()
+ {
+ assertThat('Hello PLANET how are we?', not($this->_matcher));
+ assertThat('Hello World how are we', not($this->_matcher));
+ }
+
+ public function testFailsIfWhitespaceIsAddedOrRemovedInMidWord()
+ {
+ assertThat('HelloWorld how are we?', not($this->_matcher));
+ assertThat('Hello Wo rld how are we?', not($this->_matcher));
+ }
+
+ public function testFailsIfMatchingAgainstNull()
+ {
+ assertThat(null, not($this->_matcher));
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription(
+ "equalToIgnoringWhiteSpace(\"Hello World how\\n are we? \")",
+ $this->_matcher
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/MatchesPatternTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/MatchesPatternTest.php
new file mode 100644
index 0000000..4891598
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/MatchesPatternTest.php
@@ -0,0 +1,30 @@
+assertDescription('a string matching "pattern"', matchesPattern('pattern'));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringContainsIgnoringCaseTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringContainsIgnoringCaseTest.php
new file mode 100644
index 0000000..3b5b08e
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringContainsIgnoringCaseTest.php
@@ -0,0 +1,80 @@
+_stringContains = \Hamcrest\Text\StringContainsIgnoringCase::containsStringIgnoringCase(
+ strtolower(self::EXCERPT)
+ );
+ }
+
+ protected function createMatcher()
+ {
+ return $this->_stringContains;
+ }
+
+ public function testEvaluatesToTrueIfArgumentContainsSpecifiedSubstring()
+ {
+ $this->assertTrue(
+ $this->_stringContains->matches(self::EXCERPT . 'END'),
+ 'should be true if excerpt at beginning'
+ );
+ $this->assertTrue(
+ $this->_stringContains->matches('START' . self::EXCERPT),
+ 'should be true if excerpt at end'
+ );
+ $this->assertTrue(
+ $this->_stringContains->matches('START' . self::EXCERPT . 'END'),
+ 'should be true if excerpt in middle'
+ );
+ $this->assertTrue(
+ $this->_stringContains->matches(self::EXCERPT . self::EXCERPT),
+ 'should be true if excerpt is repeated'
+ );
+
+ $this->assertFalse(
+ $this->_stringContains->matches('Something else'),
+ 'should not be true if excerpt is not in string'
+ );
+ $this->assertFalse(
+ $this->_stringContains->matches(substr(self::EXCERPT, 1)),
+ 'should not be true if part of excerpt is in string'
+ );
+ }
+
+ public function testEvaluatesToTrueIfArgumentIsEqualToSubstring()
+ {
+ $this->assertTrue(
+ $this->_stringContains->matches(self::EXCERPT),
+ 'should be true if excerpt is entire string'
+ );
+ }
+
+ public function testEvaluatesToTrueIfArgumentContainsExactSubstring()
+ {
+ $this->assertTrue(
+ $this->_stringContains->matches(strtolower(self::EXCERPT)),
+ 'should be false if excerpt is entire string ignoring case'
+ );
+ $this->assertTrue(
+ $this->_stringContains->matches('START' . strtolower(self::EXCERPT) . 'END'),
+ 'should be false if excerpt is contained in string ignoring case'
+ );
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription(
+ 'a string containing in any case "'
+ . strtolower(self::EXCERPT) . '"',
+ $this->_stringContains
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringContainsInOrderTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringContainsInOrderTest.php
new file mode 100644
index 0000000..0be7062
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringContainsInOrderTest.php
@@ -0,0 +1,42 @@
+_m = \Hamcrest\Text\StringContainsInOrder::stringContainsInOrder(array('a', 'b', 'c'));
+ }
+
+ protected function createMatcher()
+ {
+ return $this->_m;
+ }
+
+ public function testMatchesOnlyIfStringContainsGivenSubstringsInTheSameOrder()
+ {
+ $this->assertMatches($this->_m, 'abc', 'substrings in order');
+ $this->assertMatches($this->_m, '1a2b3c4', 'substrings separated');
+
+ $this->assertDoesNotMatch($this->_m, 'cab', 'substrings out of order');
+ $this->assertDoesNotMatch($this->_m, 'xyz', 'no substrings in string');
+ $this->assertDoesNotMatch($this->_m, 'ac', 'substring missing');
+ $this->assertDoesNotMatch($this->_m, '', 'empty string');
+ }
+
+ public function testAcceptsVariableArguments()
+ {
+ $this->assertMatches(stringContainsInOrder('a', 'b', 'c'), 'abc', 'substrings as variable arguments');
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription(
+ 'a string containing "a", "b", "c" in order',
+ $this->_m
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringContainsTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringContainsTest.php
new file mode 100644
index 0000000..203fd91
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringContainsTest.php
@@ -0,0 +1,86 @@
+_stringContains = \Hamcrest\Text\StringContains::containsString(self::EXCERPT);
+ }
+
+ protected function createMatcher()
+ {
+ return $this->_stringContains;
+ }
+
+ public function testEvaluatesToTrueIfArgumentContainsSubstring()
+ {
+ $this->assertTrue(
+ $this->_stringContains->matches(self::EXCERPT . 'END'),
+ 'should be true if excerpt at beginning'
+ );
+ $this->assertTrue(
+ $this->_stringContains->matches('START' . self::EXCERPT),
+ 'should be true if excerpt at end'
+ );
+ $this->assertTrue(
+ $this->_stringContains->matches('START' . self::EXCERPT . 'END'),
+ 'should be true if excerpt in middle'
+ );
+ $this->assertTrue(
+ $this->_stringContains->matches(self::EXCERPT . self::EXCERPT),
+ 'should be true if excerpt is repeated'
+ );
+
+ $this->assertFalse(
+ $this->_stringContains->matches('Something else'),
+ 'should not be true if excerpt is not in string'
+ );
+ $this->assertFalse(
+ $this->_stringContains->matches(substr(self::EXCERPT, 1)),
+ 'should not be true if part of excerpt is in string'
+ );
+ }
+
+ public function testEvaluatesToTrueIfArgumentIsEqualToSubstring()
+ {
+ $this->assertTrue(
+ $this->_stringContains->matches(self::EXCERPT),
+ 'should be true if excerpt is entire string'
+ );
+ }
+
+ public function testEvaluatesToFalseIfArgumentContainsSubstringIgnoringCase()
+ {
+ $this->assertFalse(
+ $this->_stringContains->matches(strtolower(self::EXCERPT)),
+ 'should be false if excerpt is entire string ignoring case'
+ );
+ $this->assertFalse(
+ $this->_stringContains->matches('START' . strtolower(self::EXCERPT) . 'END'),
+ 'should be false if excerpt is contained in string ignoring case'
+ );
+ }
+
+ public function testIgnoringCaseReturnsCorrectMatcher()
+ {
+ $this->assertTrue(
+ $this->_stringContains->ignoringCase()->matches('EXceRpT'),
+ 'should be true if excerpt is entire string ignoring case'
+ );
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription(
+ 'a string containing "'
+ . self::EXCERPT . '"',
+ $this->_stringContains
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringEndsWithTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringEndsWithTest.php
new file mode 100644
index 0000000..fffa3c9
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringEndsWithTest.php
@@ -0,0 +1,62 @@
+_stringEndsWith = \Hamcrest\Text\StringEndsWith::endsWith(self::EXCERPT);
+ }
+
+ protected function createMatcher()
+ {
+ return $this->_stringEndsWith;
+ }
+
+ public function testEvaluatesToTrueIfArgumentContainsSpecifiedSubstring()
+ {
+ $this->assertFalse(
+ $this->_stringEndsWith->matches(self::EXCERPT . 'END'),
+ 'should be false if excerpt at beginning'
+ );
+ $this->assertTrue(
+ $this->_stringEndsWith->matches('START' . self::EXCERPT),
+ 'should be true if excerpt at end'
+ );
+ $this->assertFalse(
+ $this->_stringEndsWith->matches('START' . self::EXCERPT . 'END'),
+ 'should be false if excerpt in middle'
+ );
+ $this->assertTrue(
+ $this->_stringEndsWith->matches(self::EXCERPT . self::EXCERPT),
+ 'should be true if excerpt is at end and repeated'
+ );
+
+ $this->assertFalse(
+ $this->_stringEndsWith->matches('Something else'),
+ 'should be false if excerpt is not in string'
+ );
+ $this->assertFalse(
+ $this->_stringEndsWith->matches(substr(self::EXCERPT, 0, strlen(self::EXCERPT) - 2)),
+ 'should be false if part of excerpt is at end of string'
+ );
+ }
+
+ public function testEvaluatesToTrueIfArgumentIsEqualToSubstring()
+ {
+ $this->assertTrue(
+ $this->_stringEndsWith->matches(self::EXCERPT),
+ 'should be true if excerpt is entire string'
+ );
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription('a string ending with "EXCERPT"', $this->_stringEndsWith);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringStartsWithTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringStartsWithTest.php
new file mode 100644
index 0000000..fc3761b
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Text/StringStartsWithTest.php
@@ -0,0 +1,62 @@
+_stringStartsWith = \Hamcrest\Text\StringStartsWith::startsWith(self::EXCERPT);
+ }
+
+ protected function createMatcher()
+ {
+ return $this->_stringStartsWith;
+ }
+
+ public function testEvaluatesToTrueIfArgumentContainsSpecifiedSubstring()
+ {
+ $this->assertTrue(
+ $this->_stringStartsWith->matches(self::EXCERPT . 'END'),
+ 'should be true if excerpt at beginning'
+ );
+ $this->assertFalse(
+ $this->_stringStartsWith->matches('START' . self::EXCERPT),
+ 'should be false if excerpt at end'
+ );
+ $this->assertFalse(
+ $this->_stringStartsWith->matches('START' . self::EXCERPT . 'END'),
+ 'should be false if excerpt in middle'
+ );
+ $this->assertTrue(
+ $this->_stringStartsWith->matches(self::EXCERPT . self::EXCERPT),
+ 'should be true if excerpt is at beginning and repeated'
+ );
+
+ $this->assertFalse(
+ $this->_stringStartsWith->matches('Something else'),
+ 'should be false if excerpt is not in string'
+ );
+ $this->assertFalse(
+ $this->_stringStartsWith->matches(substr(self::EXCERPT, 1)),
+ 'should be false if part of excerpt is at start of string'
+ );
+ }
+
+ public function testEvaluatesToTrueIfArgumentIsEqualToSubstring()
+ {
+ $this->assertTrue(
+ $this->_stringStartsWith->matches(self::EXCERPT),
+ 'should be true if excerpt is entire string'
+ );
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription('a string starting with "EXCERPT"', $this->_stringStartsWith);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsArrayTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsArrayTest.php
new file mode 100644
index 0000000..d13c24d
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsArrayTest.php
@@ -0,0 +1,35 @@
+assertDescription('an array', arrayValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', arrayValue(), null);
+ $this->assertMismatchDescription('was a string "foo"', arrayValue(), 'foo');
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsBooleanTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsBooleanTest.php
new file mode 100644
index 0000000..24309fc
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsBooleanTest.php
@@ -0,0 +1,35 @@
+assertDescription('a boolean', booleanValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', booleanValue(), null);
+ $this->assertMismatchDescription('was a string "foo"', booleanValue(), 'foo');
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsCallableTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsCallableTest.php
new file mode 100644
index 0000000..5098e21
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsCallableTest.php
@@ -0,0 +1,103 @@
+=')) {
+ $this->markTestSkipped('Closures require php 5.3');
+ }
+ eval('assertThat(function () {}, callableValue());');
+ }
+
+ public function testEvaluatesToTrueIfArgumentImplementsInvoke()
+ {
+ if (!version_compare(PHP_VERSION, '5.3', '>=')) {
+ $this->markTestSkipped('Magic method __invoke() requires php 5.3');
+ }
+ assertThat($this, callableValue());
+ }
+
+ public function testEvaluatesToFalseIfArgumentIsInvalidFunctionName()
+ {
+ if (function_exists('not_a_Hamcrest_function')) {
+ $this->markTestSkipped('Function "not_a_Hamcrest_function" must not exist');
+ }
+
+ assertThat('not_a_Hamcrest_function', not(callableValue()));
+ }
+
+ public function testEvaluatesToFalseIfArgumentIsInvalidStaticMethodCallback()
+ {
+ assertThat(
+ array('Hamcrest\Type\IsCallableTest', 'noMethod'),
+ not(callableValue())
+ );
+ }
+
+ public function testEvaluatesToFalseIfArgumentIsInvalidInstanceMethodCallback()
+ {
+ assertThat(array($this, 'noMethod'), not(callableValue()));
+ }
+
+ public function testEvaluatesToFalseIfArgumentDoesntImplementInvoke()
+ {
+ assertThat(new \stdClass(), not(callableValue()));
+ }
+
+ public function testEvaluatesToFalseIfArgumentDoesntMatchType()
+ {
+ assertThat(false, not(callableValue()));
+ assertThat(5.2, not(callableValue()));
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription('a callable', callableValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription(
+ 'was a string "invalid-function"',
+ callableValue(),
+ 'invalid-function'
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsDoubleTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsDoubleTest.php
new file mode 100644
index 0000000..85c2a96
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsDoubleTest.php
@@ -0,0 +1,35 @@
+assertDescription('a double', doubleValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', doubleValue(), null);
+ $this->assertMismatchDescription('was a string "foo"', doubleValue(), 'foo');
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsIntegerTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsIntegerTest.php
new file mode 100644
index 0000000..ce5a51a
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsIntegerTest.php
@@ -0,0 +1,36 @@
+assertDescription('an integer', integerValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', integerValue(), null);
+ $this->assertMismatchDescription('was a string "foo"', integerValue(), 'foo');
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsNumericTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsNumericTest.php
new file mode 100644
index 0000000..1fd83ef
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsNumericTest.php
@@ -0,0 +1,53 @@
+assertDescription('a number', numericValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', numericValue(), null);
+ $this->assertMismatchDescription('was a string "foo"', numericValue(), 'foo');
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsObjectTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsObjectTest.php
new file mode 100644
index 0000000..a3b617c
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsObjectTest.php
@@ -0,0 +1,34 @@
+assertDescription('an object', objectValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', objectValue(), null);
+ $this->assertMismatchDescription('was a string "foo"', objectValue(), 'foo');
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsResourceTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsResourceTest.php
new file mode 100644
index 0000000..d6ea534
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsResourceTest.php
@@ -0,0 +1,34 @@
+assertDescription('a resource', resourceValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', resourceValue(), null);
+ $this->assertMismatchDescription('was a string "foo"', resourceValue(), 'foo');
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsScalarTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsScalarTest.php
new file mode 100644
index 0000000..72a188d
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsScalarTest.php
@@ -0,0 +1,39 @@
+assertDescription('a scalar', scalarValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', scalarValue(), null);
+ $this->assertMismatchDescription('was an array ["foo"]', scalarValue(), array('foo'));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsStringTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsStringTest.php
new file mode 100644
index 0000000..557d591
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Type/IsStringTest.php
@@ -0,0 +1,35 @@
+assertDescription('a string', stringValue());
+ }
+
+ public function testDecribesActualTypeInMismatchMessage()
+ {
+ $this->assertMismatchDescription('was null', stringValue(), null);
+ $this->assertMismatchDescription('was a double <5.2F>', stringValue(), 5.2);
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/UtilTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/UtilTest.php
new file mode 100644
index 0000000..0c2cd04
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/UtilTest.php
@@ -0,0 +1,80 @@
+assertSame($matcher, $newMatcher);
+ }
+
+ public function testWrapValueWithIsEqualWrapsPrimitive()
+ {
+ $matcher = \Hamcrest\Util::wrapValueWithIsEqual('foo');
+ $this->assertInstanceOf('Hamcrest\Core\IsEqual', $matcher);
+ $this->assertTrue($matcher->matches('foo'));
+ }
+
+ public function testCheckAllAreMatchersAcceptsMatchers()
+ {
+ \Hamcrest\Util::checkAllAreMatchers(array(
+ new \Hamcrest\Text\MatchesPattern('/fo+/'),
+ new \Hamcrest\Core\IsEqual('foo'),
+ ));
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testCheckAllAreMatchersFailsForPrimitive()
+ {
+ \Hamcrest\Util::checkAllAreMatchers(array(
+ new \Hamcrest\Text\MatchesPattern('/fo+/'),
+ 'foo',
+ ));
+ }
+
+ private function callAndAssertCreateMatcherArray($items)
+ {
+ $matchers = \Hamcrest\Util::createMatcherArray($items);
+ $this->assertInternalType('array', $matchers);
+ $this->assertSameSize($items, $matchers);
+ foreach ($matchers as $matcher) {
+ $this->assertInstanceOf('\Hamcrest\Matcher', $matcher);
+ }
+
+ return $matchers;
+ }
+
+ public function testCreateMatcherArrayLeavesMatchersUntouched()
+ {
+ $matcher = new \Hamcrest\Text\MatchesPattern('/fo+/');
+ $items = array($matcher);
+ $matchers = $this->callAndAssertCreateMatcherArray($items);
+ $this->assertSame($matcher, $matchers[0]);
+ }
+
+ public function testCreateMatcherArrayWrapsPrimitiveWithIsEqualMatcher()
+ {
+ $matchers = $this->callAndAssertCreateMatcherArray(array('foo'));
+ $this->assertInstanceOf('Hamcrest\Core\IsEqual', $matchers[0]);
+ $this->assertTrue($matchers[0]->matches('foo'));
+ }
+
+ public function testCreateMatcherArrayDoesntModifyOriginalArray()
+ {
+ $items = array('foo');
+ $this->callAndAssertCreateMatcherArray($items);
+ $this->assertSame('foo', $items[0]);
+ }
+
+ public function testCreateMatcherArrayUnwrapsSingleArrayElement()
+ {
+ $matchers = $this->callAndAssertCreateMatcherArray(array(array('foo')));
+ $this->assertInstanceOf('Hamcrest\Core\IsEqual', $matchers[0]);
+ $this->assertTrue($matchers[0]->matches('foo'));
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Xml/HasXPathTest.php b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Xml/HasXPathTest.php
new file mode 100644
index 0000000..6774887
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/Hamcrest/Xml/HasXPathTest.php
@@ -0,0 +1,198 @@
+
+
+
+ alice
+ Alice Frankel
+ admin
+
+
+ bob
+ Bob Frankel
+ user
+
+
+ charlie
+ Charlie Chan
+ user
+
+
+XML;
+ self::$doc = new \DOMDocument();
+ self::$doc->loadXML(self::$xml);
+
+ self::$html = <<
+
+ Home Page
+
+
+ Heading
+ Some text
+
+
+HTML;
+ }
+
+ protected function createMatcher()
+ {
+ return \Hamcrest\Xml\HasXPath::hasXPath('/users/user');
+ }
+
+ public function testMatchesWhenXPathIsFound()
+ {
+ assertThat('one match', self::$doc, hasXPath('user[id = "bob"]'));
+ assertThat('two matches', self::$doc, hasXPath('user[role = "user"]'));
+ }
+
+ public function testDoesNotMatchWhenXPathIsNotFound()
+ {
+ assertThat(
+ 'no match',
+ self::$doc,
+ not(hasXPath('user[contains(id, "frank")]'))
+ );
+ }
+
+ public function testMatchesWhenExpressionWithoutMatcherEvaluatesToTrue()
+ {
+ assertThat(
+ 'one match',
+ self::$doc,
+ hasXPath('count(user[id = "bob"])')
+ );
+ }
+
+ public function testDoesNotMatchWhenExpressionWithoutMatcherEvaluatesToFalse()
+ {
+ assertThat(
+ 'no matches',
+ self::$doc,
+ not(hasXPath('count(user[id = "frank"])'))
+ );
+ }
+
+ public function testMatchesWhenExpressionIsEqual()
+ {
+ assertThat(
+ 'one match',
+ self::$doc,
+ hasXPath('count(user[id = "bob"])', 1)
+ );
+ assertThat(
+ 'two matches',
+ self::$doc,
+ hasXPath('count(user[role = "user"])', 2)
+ );
+ }
+
+ public function testDoesNotMatchWhenExpressionIsNotEqual()
+ {
+ assertThat(
+ 'no match',
+ self::$doc,
+ not(hasXPath('count(user[id = "frank"])', 2))
+ );
+ assertThat(
+ 'one match',
+ self::$doc,
+ not(hasXPath('count(user[role = "admin"])', 2))
+ );
+ }
+
+ public function testMatchesWhenContentMatches()
+ {
+ assertThat(
+ 'one match',
+ self::$doc,
+ hasXPath('user/name', containsString('ice'))
+ );
+ assertThat(
+ 'two matches',
+ self::$doc,
+ hasXPath('user/role', equalTo('user'))
+ );
+ }
+
+ public function testDoesNotMatchWhenContentDoesNotMatch()
+ {
+ assertThat(
+ 'no match',
+ self::$doc,
+ not(hasXPath('user/name', containsString('Bobby')))
+ );
+ assertThat(
+ 'no matches',
+ self::$doc,
+ not(hasXPath('user/role', equalTo('owner')))
+ );
+ }
+
+ public function testProvidesConvenientShortcutForHasXPathEqualTo()
+ {
+ assertThat('matches', self::$doc, hasXPath('count(user)', 3));
+ assertThat('matches', self::$doc, hasXPath('user[2]/id', 'bob'));
+ }
+
+ public function testProvidesConvenientShortcutForHasXPathCountEqualTo()
+ {
+ assertThat('matches', self::$doc, hasXPath('user[id = "charlie"]', 1));
+ }
+
+ public function testMatchesAcceptsXmlString()
+ {
+ assertThat('accepts XML string', self::$xml, hasXPath('user'));
+ }
+
+ public function testMatchesAcceptsHtmlString()
+ {
+ assertThat('accepts HTML string', self::$html, hasXPath('body/h1', 'Heading'));
+ }
+
+ public function testHasAReadableDescription()
+ {
+ $this->assertDescription(
+ 'XML or HTML document with XPath "/users/user"',
+ hasXPath('/users/user')
+ );
+ $this->assertDescription(
+ 'XML or HTML document with XPath "count(/users/user)" <2>',
+ hasXPath('/users/user', 2)
+ );
+ $this->assertDescription(
+ 'XML or HTML document with XPath "/users/user/name"'
+ . ' a string starting with "Alice"',
+ hasXPath('/users/user/name', startsWith('Alice'))
+ );
+ }
+
+ public function testHasAReadableMismatchDescription()
+ {
+ $this->assertMismatchDescription(
+ 'XPath returned no results',
+ hasXPath('/users/name'),
+ self::$doc
+ );
+ $this->assertMismatchDescription(
+ 'XPath expression result was <3F>',
+ hasXPath('/users/user', 2),
+ self::$doc
+ );
+ $this->assertMismatchDescription(
+ 'XPath returned ["alice", "bob", "charlie"]',
+ hasXPath('/users/user/id', 'Frank'),
+ self::$doc
+ );
+ }
+}
diff --git a/vendor/hamcrest/hamcrest-php/tests/bootstrap.php b/vendor/hamcrest/hamcrest-php/tests/bootstrap.php
new file mode 100644
index 0000000..bc4958d
--- /dev/null
+++ b/vendor/hamcrest/hamcrest-php/tests/bootstrap.php
@@ -0,0 +1,11 @@
+
+
+
+ .
+
+
+
+
+
+ ../hamcrest
+
+
+
diff --git a/vendor/mockery/mockery/.gitignore b/vendor/mockery/mockery/.gitignore
new file mode 100644
index 0000000..062facc
--- /dev/null
+++ b/vendor/mockery/mockery/.gitignore
@@ -0,0 +1,15 @@
+*~
+pearfarm.spec
+*.sublime-project
+library/Hamcrest/*
+composer.lock
+vendor/
+composer.phar
+test.php
+build/
+phpunit.xml
+*.DS_store
+.idea/*
+.php_cs.cache
+docs/api
+phpDocumentor.phar*
diff --git a/vendor/mockery/mockery/.php_cs b/vendor/mockery/mockery/.php_cs
new file mode 100644
index 0000000..be098ba
--- /dev/null
+++ b/vendor/mockery/mockery/.php_cs
@@ -0,0 +1,30 @@
+in([
+ 'library',
+ 'tests',
+ ]);
+
+ return PhpCsFixer\Config::create()
+ ->setRules(array(
+ '@PSR2' => true,
+ ))
+ ->setUsingCache(true)
+ ->setFinder($finder)
+ ;
+}
+
+$finder = DefaultFinder::create()->in(
+ [
+ 'library',
+ 'tests',
+ ]);
+
+return Config::create()
+ ->level('psr2')
+ ->setUsingCache(true)
+ ->finder($finder);
diff --git a/vendor/mockery/mockery/.phpstorm.meta.php b/vendor/mockery/mockery/.phpstorm.meta.php
new file mode 100644
index 0000000..6c53f80
--- /dev/null
+++ b/vendor/mockery/mockery/.phpstorm.meta.php
@@ -0,0 +1,11 @@
+> ~/.phpenv/versions/"$(phpenv version-name)"/etc/conf.d/travis.ini
+ fi
+
+script:
+- |
+ if [[ $TRAVIS_PHP_VERSION = 5.* ]]; then
+ ./vendor/bin/phpunit --coverage-text --coverage-clover="build/logs/clover.xml" --testsuite="Mockery Test Suite PHP56";
+ else
+ ./vendor/bin/phpunit --coverage-text --coverage-clover="build/logs/clover.xml" --testsuite="Mockery Test Suite";
+ fi
+
+after_success:
+ - composer require satooshi/php-coveralls
+ - vendor/bin/coveralls -v
+ - wget https://scrutinizer-ci.com/ocular.phar
+ - php ocular.phar code-coverage:upload --format=php-clover "build/logs/clover.xml"
+ - make apidocs
+
+notifications:
+ email:
+ - padraic.brady@gmail.com
+ - dave@atstsolutions.co.uk
+
+ irc: irc.freenode.org#mockery
+deploy:
+ overwrite: true
+ provider: pages
+ file_glob: true
+ file: docs/api/*
+ local_dir: docs/api
+ skip_cleanup: true
+ github_token: $GITHUB_TOKEN
+ on:
+ branch: master
+ php: '7.1'
+ condition: $DEPS = latest
diff --git a/vendor/mockery/mockery/CHANGELOG.md b/vendor/mockery/mockery/CHANGELOG.md
new file mode 100644
index 0000000..ba8a3e6
--- /dev/null
+++ b/vendor/mockery/mockery/CHANGELOG.md
@@ -0,0 +1,106 @@
+# Change Log
+
+## x.y.z (unreleased)
+
+## 1.2.0 (2018-10-02)
+
+* Starts counting default expectations towards count (#910)
+* Adds workaround for some HHVM return types (#909)
+* Adds PhpStorm metadata support for autocomplete etc (#904)
+* Further attempts to support multiple PHPUnit versions (#903)
+* Allows setting constructor expectations on instance mocks (#900)
+* Adds workaround for HHVM memoization decorator (#893)
+* Adds experimental support for callable spys (#712)
+
+## 1.1.0 (2018-05-08)
+
+* Allows use of string method names in allows and expects (#794)
+* Finalises allows and expects syntax in API (#799)
+* Search for handlers in a case instensitive way (#801)
+* Deprecate allowMockingMethodsUnnecessarily (#808)
+* Fix risky tests (#769)
+* Fix namespace in TestListener (#812)
+* Fixed conflicting mock names (#813)
+* Clean elses (#819)
+* Updated protected method mocking exception message (#826)
+* Map of constants to mock (#829)
+* Simplify foreach with `in_array` function (#830)
+* Typehinted return value on Expectation#verify. (#832)
+* Fix shouldNotHaveReceived with HigherOrderMessage (#842)
+* Deprecates shouldDeferMissing (#839)
+* Adds support for return type hints in Demeter chains (#848)
+* Adds shouldNotReceive to composite expectation (#847)
+* Fix internal error when using --static-backup (#845)
+* Adds `andAnyOtherArgs` as an optional argument matcher (#860)
+* Fixes namespace qualifying with namespaced named mocks (#872)
+* Added possibility to add Constructor-Expections on hard dependencies, read: Mockery::mock('overload:...') (#781)
+
+## 1.0.0 (2017-09-06)
+
+* Destructors (`__destruct`) are stubbed out where it makes sense
+* Allow passing a closure argument to `withArgs()` to validate multiple arguments at once.
+* `Mockery\Adapter\Phpunit\TestListener` has been rewritten because it
+ incorrectly marked some tests as risky. It will no longer verify mock
+ expectations but instead check that tests do that themselves. PHPUnit 6 is
+ required if you want to use this fail safe.
+* Removes SPL Class Loader
+* Removed object recorder feature
+* Bumped minimum PHP version to 5.6
+* `andThrow` will now throw anything `\Throwable`
+* Adds `allows` and `expects` syntax
+* Adds optional global helpers for `mock`, `namedMock` and `spy`
+* Adds ability to create objects using traits
+* `Mockery\Matcher\MustBe` was deprecated
+* Marked `Mockery\MockInterface` as internal
+* Subset matcher matches recursively
+* BC BREAK - Spies return `null` by default from ignored (non-mocked) methods with nullable return type
+* Removed extracting getter methods of object instances
+* BC BREAK - Remove implicit regex matching when trying to match string arguments, introduce `\Mockery::pattern()` when regex matching is needed
+* Fix Mockery not getting closed in cases of failing test cases
+* Fix Mockery not setting properties on overloaded instance mocks
+* BC BREAK - Fix Mockery not trying default expectations if there is any concrete expectation
+* BC BREAK - Mockery's PHPUnit integration will mark a test as risky if it
+ thinks one it's exceptions has been swallowed in PHPUnit > 5.7.6. Use `$e->dismiss()` to dismiss.
+
+## 0.9.4 (XXXX-XX-XX)
+
+* `shouldIgnoreMissing` will respect global `allowMockingNonExistentMethods`
+ config
+* Some support for variadic parameters
+* Hamcrest is now a required dependency
+* Instance mocks now respect `shouldIgnoreMissing` call on control instance
+* This will be the *last version to support PHP 5.3*
+* Added `Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration` trait
+* Added `makePartial` to `Mockery\MockInterface` as it was missing
+
+## 0.9.3 (2014-12-22)
+
+* Added a basic spy implementation
+* Added `Mockery\Adapter\Phpunit\MockeryTestCase` for more reliable PHPUnit
+ integration
+
+## 0.9.2 (2014-09-03)
+
+* Some workarounds for the serialisation problems created by changes to PHP in 5.5.13, 5.4.29,
+ 5.6.
+* Demeter chains attempt to reuse doubles as they see fit, so for foo->bar and
+ foo->baz, we'll attempt to use the same foo
+
+## 0.9.1 (2014-05-02)
+
+* Allow specifying consecutive exceptions to be thrown with `andThrowExceptions`
+* Allow specifying methods which can be mocked when using
+ `Mockery\Configuration::allowMockingNonExistentMethods(false)` with
+ `Mockery\MockInterface::shouldAllowMockingMethod($methodName)`
+* Added andReturnSelf method: `$mock->shouldReceive("foo")->andReturnSelf()`
+* `shouldIgnoreMissing` now takes an optional value that will be return instead
+ of null, e.g. `$mock->shouldIgnoreMissing($mock)`
+
+## 0.9.0 (2014-02-05)
+
+* Allow mocking classes with final __wakeup() method
+* Quick definitions are now always `byDefault`
+* Allow mocking of protected methods with `shouldAllowMockingProtectedMethods`
+* Support official Hamcrest package
+* Generator completely rewritten
+* Easily create named mocks with namedMock
diff --git a/vendor/mockery/mockery/CONTRIBUTING.md b/vendor/mockery/mockery/CONTRIBUTING.md
new file mode 100644
index 0000000..b714f3f
--- /dev/null
+++ b/vendor/mockery/mockery/CONTRIBUTING.md
@@ -0,0 +1,88 @@
+# Contributing
+
+
+We'd love you to help out with mockery and no contribution is too small.
+
+
+## Reporting Bugs
+
+Issues can be reported on the [issue
+tracker](https://github.com/padraic/mockery/issues). Please try and report any
+bugs with a minimal reproducible example, it will make things easier for other
+contributors and your problems will hopefully be resolved quickly.
+
+
+## Requesting Features
+
+We're always interested to hear about your ideas and you can request features by
+creating a ticket in the [issue
+tracker](https://github.com/padraic/mockery/issues). We can't always guarantee
+someone will jump on it straight away, but putting it out there to see if anyone
+else is interested is a good idea.
+
+Likewise, if a feature you would like is already listed in
+the issue tracker, add a :+1: so that other contributors know it's a feature
+that would help others.
+
+
+## Contributing code and documentation
+
+We loosely follow the
+[PSR-1](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)
+and
+[PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) coding standards,
+but we'll probably merge any code that looks close enough.
+
+* Fork the [repository](https://github.com/padraic/mockery) on GitHub
+* Add the code for your feature or bug
+* Add some tests for your feature or bug
+* Optionally, but preferably, write some documentation
+* Optionally, update the CHANGELOG.md file with your feature or
+ [BC](http://en.wikipedia.org/wiki/Backward_compatibility) break
+* Send a [Pull
+ Request](https://help.github.com/articles/creating-a-pull-request) to the
+ correct target branch (see below)
+
+If you have a big change or would like to discuss something, create an issue in
+the [issue tracker](https://github.com/padraic/mockery/issues) or jump in to
+\#mockery on freenode
+
+
+Any code you contribute must be licensed under the [BSD 3-Clause
+License](http://opensource.org/licenses/BSD-3-Clause).
+
+
+## Target Branch
+
+Mockery may have several active branches at any one time and roughly follows a
+[Git Branching Model](https://igor.io/2013/10/21/git-branching-model.html).
+Generally, if you're developing a new feature, you want to be targeting the
+master branch, if it's a bug fix, you want to be targeting a release branch,
+e.g. 0.8.
+
+
+## Testing Mockery
+
+To run the unit tests for Mockery, clone the git repository, download Composer using
+the instructions at [http://getcomposer.org/download/](http://getcomposer.org/download/),
+then install the dependencies with `php /path/to/composer.phar install`.
+
+This will install the required PHPUnit and Hamcrest dev dependencies and create the
+autoload files required by the unit tests. You may run the `vendor/bin/phpunit` command
+to run the unit tests. If everything goes to plan, there will be no failed tests!
+
+
+## Debugging Mockery
+
+Mockery and its code generation can be difficult to debug. A good start is to
+use the `RequireLoader`, which will dump the code generated by mockery to a file
+before requiring it, rather than using eval. This will help with stack traces,
+and you will be able to open the mock class in your editor.
+
+``` php
+
+// tests/bootstrap.php
+
+Mockery::setLoader(new Mockery\Loader\RequireLoader(sys_get_temp_dir()));
+
+```
diff --git a/vendor/mockery/mockery/LICENSE b/vendor/mockery/mockery/LICENSE
new file mode 100644
index 0000000..2e127a6
--- /dev/null
+++ b/vendor/mockery/mockery/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2010, Pádraic Brady
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * The name of Pádraic Brady may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/mockery/mockery/Makefile b/vendor/mockery/mockery/Makefile
new file mode 100644
index 0000000..c312f70
--- /dev/null
+++ b/vendor/mockery/mockery/Makefile
@@ -0,0 +1,52 @@
+vendor/composer/installed.json: composer.json
+ composer install
+
+.PHONY: deps
+deps: vendor/composer/installed.json
+
+.PHONY: test
+test: deps
+ php vendor/bin/phpunit
+
+.PHONY: apidocs
+apidocs: docs/api/index.html
+
+phpDocumentor.phar:
+ wget https://github.com/phpDocumentor/phpDocumentor2/releases/download/v3.0.0-alpha.2-nightly-gdff5545/phpDocumentor.phar
+ wget https://github.com/phpDocumentor/phpDocumentor2/releases/download/v3.0.0-alpha.2-nightly-gdff5545/phpDocumentor.phar.pubkey
+
+library_files=$(shell find library -name '*.php')
+docs/api/index.html: vendor/composer/installed.json $(library_files) phpDocumentor.phar
+ php phpDocumentor.phar run -d library -t docs/api
+
+.PHONY: test-all
+test-all: test-72 test-71 test-70 test-56
+
+.PHONY: test-all-7
+test-all-7: test-72 test-71 test-70
+
+.PHONY: test-72
+test-72: deps
+ docker run -it --rm -v "$$PWD":/opt/mockery -w /opt/mockery php:7.2-cli php vendor/bin/phpunit
+
+.PHONY: test-71
+test-71: deps
+ docker run -it --rm -v "$$PWD":/opt/mockery -w /opt/mockery php:7.1-cli php vendor/bin/phpunit
+
+.PHONY: test-70
+test-70: deps
+ docker run -it --rm -v "$$PWD":/opt/mockery -w /opt/mockery php:7.0-cli php vendor/bin/phpunit
+
+.PHONY: test-56
+test-56: build56
+ docker run -it --rm \
+ -v "$$PWD/library":/opt/mockery/library \
+ -v "$$PWD/tests":/opt/mockery/tests \
+ -v "$$PWD/phpunit.xml.dist":/opt/mockery/phpunit.xml \
+ -w /opt/mockery \
+ mockery_php56 \
+ php vendor/bin/phpunit
+
+.PHONY: build56
+build56:
+ docker build -t mockery_php56 -f "$$PWD/docker/php56/Dockerfile" .
diff --git a/vendor/mockery/mockery/README.md b/vendor/mockery/mockery/README.md
new file mode 100644
index 0000000..b346f4b
--- /dev/null
+++ b/vendor/mockery/mockery/README.md
@@ -0,0 +1,299 @@
+Mockery
+=======
+
+[![Build Status](https://travis-ci.org/mockery/mockery.svg?branch=master)](https://travis-ci.org/mockery/mockery)
+[![Latest Stable Version](https://poser.pugx.org/mockery/mockery/v/stable.svg)](https://packagist.org/packages/mockery/mockery)
+[![Coverage Status](https://coveralls.io/repos/github/mockery/mockery/badge.svg)](https://coveralls.io/github/mockery/mockery)
+[![Total Downloads](https://poser.pugx.org/mockery/mockery/downloads.svg)](https://packagist.org/packages/mockery/mockery)
+
+Mockery is a simple yet flexible PHP mock object framework for use in unit testing
+with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a
+test double framework with a succinct API capable of clearly defining all possible
+object operations and interactions using a human readable Domain Specific Language
+(DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library,
+Mockery is easy to integrate with PHPUnit and can operate alongside
+phpunit-mock-objects without the World ending.
+
+Mockery is released under a New BSD License.
+
+## Installation
+
+To install Mockery, run the command below and you will get the latest
+version
+
+```sh
+composer require --dev mockery/mockery
+```
+
+## Documentation
+
+In older versions, this README file was the documentation for Mockery. Over time
+we have improved this, and have created an extensive documentation for you. Please
+use this README file as a starting point for Mockery, but do read the documentation
+to learn how to use Mockery.
+
+The current version can be seen at [docs.mockery.io](http://docs.mockery.io).
+
+## Test Doubles
+
+Test doubles (often called mocks) simulate the behaviour of real objects. They are
+commonly utilised to offer test isolation, to stand in for objects which do not
+yet exist, or to allow for the exploratory design of class APIs without
+requiring actual implementation up front.
+
+The benefits of a test double framework are to allow for the flexible generation
+and configuration of test doubles. They allow the setting of expected method calls
+and/or return values using a flexible API which is capable of capturing every
+possible real object behaviour in way that is stated as close as possible to a
+natural language description. Use the `Mockery::mock` method to create a test
+double.
+
+``` php
+$double = Mockery::mock();
+```
+
+If you need Mockery to create a test double to satisfy a particular type hint,
+you can pass the type to the `mock` method.
+
+``` php
+class Book {}
+
+interface BookRepository {
+ function find($id): Book;
+ function findAll(): array;
+ function add(Book $book): void;
+}
+
+$double = Mockery::mock(BookRepository::class);
+```
+
+A detailed explanation of creating and working with test doubles is given in the
+documentation, [Creating test doubles](http://docs.mockery.io/en/latest/reference/creating_test_doubles.html)
+section.
+
+## Method Stubs 🎫
+
+A method stub is a mechanism for having your test double return canned responses
+to certain method calls. With stubs, you don't care how many times, if at all,
+the method is called. Stubs are used to provide indirect input to the system
+under test.
+
+``` php
+$double->allows()->find(123)->andReturns(new Book());
+
+$book = $double->find(123);
+```
+
+If you have used Mockery before, you might see something new in the example
+above — we created a method stub using `allows`, instead of the "old"
+`shouldReceive` syntax. This is a new feature of Mockery v1, but fear not,
+the trusty ol' `shouldReceive` is still here.
+
+For new users of Mockery, the above example can also be written as:
+
+``` php
+$double->shouldReceive('find')->with(123)->andReturn(new Book());
+$book = $double->find(123);
+```
+
+If your stub doesn't require specific arguments, you can also use this shortcut
+for setting up multiple calls at once:
+
+``` php
+$double->allows([
+ "findAll" => [new Book(), new Book()],
+]);
+```
+
+or
+
+``` php
+$double->shouldReceive('findAll')
+ ->andReturn([new Book(), new Book()]);
+```
+
+You can also use this shortcut, which creates a double and sets up some stubs in
+one call:
+
+``` php
+$double = Mockery::mock(BookRepository::class, [
+ "findAll" => [new Book(), new Book()],
+]);
+```
+
+## Method Call Expectations 📲
+
+A Method call expectation is a mechanism to allow you to verify that a
+particular method has been called. You can specify the parameters and you can
+also specify how many times you expect it to be called. Method call expectations
+are used to verify indirect output of the system under test.
+
+``` php
+$book = new Book();
+
+$double = Mockery::mock(BookRepository::class);
+$double->expects()->add($book);
+```
+
+During the test, Mockery accept calls to the `add` method as prescribed.
+After you have finished exercising the system under test, you need to
+tell Mockery to check that the method was called as expected, using the
+`Mockery::close` method. One way to do that is to add it to your `tearDown`
+method in PHPUnit.
+
+``` php
+
+public function tearDown()
+{
+ Mockery::close();
+}
+```
+
+The `expects()` method automatically sets up an expectation that the method call
+(and matching parameters) is called **once and once only**. You can choose to change
+this if you are expecting more calls.
+
+``` php
+$double->expects()->add($book)->twice();
+```
+
+If you have used Mockery before, you might see something new in the example
+above — we created a method expectation using `expects`, instead of the "old"
+`shouldReceive` syntax. This is a new feature of Mockery v1, but same as with
+`accepts` in the previous section, it can be written in the "old" style.
+
+For new users of Mockery, the above example can also be written as:
+
+``` php
+$double->shouldReceive('find')
+ ->with(123)
+ ->once()
+ ->andReturn(new Book());
+$book = $double->find(123);
+```
+
+A detailed explanation of declaring expectations on method calls, please
+read the documentation, the [Expectation declarations](http://docs.mockery.io/en/latest/reference/expectations.html)
+section. After that, you can also learn about the new `allows` and `expects` methods
+in the [Alternative shouldReceive syntax](http://docs.mockery.io/en/latest/reference/alternative_should_receive_syntax.html)
+section.
+
+It is worth mentioning that one way of setting up expectations is no better or worse
+than the other. Under the hood, `allows` and `expects` are doing the same thing as
+`shouldReceive`, at times in "less words", and as such it comes to a personal preference
+of the programmer which way to use.
+
+## Test Spies 🕵️
+
+By default, all test doubles created with the `Mockery::mock` method will only
+accept calls that they have been configured to `allow` or `expect` (or in other words,
+calls that they `shouldReceive`). Sometimes we don't necessarily care about all of the
+calls that are going to be made to an object. To facilitate this, we can tell Mockery
+to ignore any calls it has not been told to expect or allow. To do so, we can tell a
+test double `shouldIgnoreMissing`, or we can create the double using the `Mocker::spy`
+shortcut.
+
+``` php
+// $double = Mockery::mock()->shouldIgnoreMissing();
+$double = Mockery::spy();
+
+$double->foo(); // null
+$double->bar(); // null
+```
+
+Further to this, sometimes we want to have the object accept any call during the test execution
+and then verify the calls afterwards. For these purposes, we need our test
+double to act as a Spy. All mockery test doubles record the calls that are made
+to them for verification afterwards by default:
+
+``` php
+$double->baz(123);
+
+$double->shouldHaveReceived()->baz(123); // null
+$double->shouldHaveReceived()->baz(12345); // Uncaught Exception Mockery\Exception\InvalidCountException...
+```
+
+Please refer to the [Spies](http://docs.mockery.io/en/latest/reference/spies.html) section
+of the documentation to learn more about the spies.
+
+## Utilities 🔌
+
+### Global Helpers
+
+Mockery ships with a handful of global helper methods, you just need to ask
+Mockery to declare them.
+
+``` php
+Mockery::globalHelpers();
+
+$mock = mock(Some::class);
+$spy = spy(Some::class);
+
+$spy->shouldHaveReceived()
+ ->foo(anyArgs());
+```
+
+All of the global helpers are wrapped in a `!function_exists` call to avoid
+conflicts. So if you already have a global function called `spy`, Mockery will
+silently skip the declaring its own `spy` function.
+
+### Testing Traits
+
+As Mockery ships with code generation capabilities, it was trivial to add
+functionality allowing users to create objects on the fly that use particular
+traits. Any abstract methods defined by the trait will be created and can have
+expectations or stubs configured like normal Test Doubles.
+
+``` php
+trait Foo {
+ function foo() {
+ return $this->doFoo();
+ }
+
+ abstract function doFoo();
+}
+
+$double = Mockery::mock(Foo::class);
+$double->allows()->doFoo()->andReturns(123);
+$double->foo(); // int(123)
+```
+
+### Testing the constructor arguments of hard Dependencies
+
+See [Mocking hard dependencies](http://docs.mockery.io/en/latest/cookbook/mocking_hard_dependencies.html)
+
+``` php
+$implementationMock = Mockery::mock('overload:\Some\Implementation');
+
+$implementationMock->shouldReceive('__construct')
+ ->once()
+ ->with(['host' => 'localhost]);
+// add other expectations as usual
+
+$implementation = new \Some\Implementation(['host' => 'localhost']);
+```
+
+## Versioning
+
+The Mockery team attempts to adhere to [Semantic Versioning](http://semver.org),
+however, some of Mockery's internals are considered private and will be open to
+change at any time. Just because a class isn't final, or a method isn't marked
+private, does not mean it constitutes part of the API we guarantee under the
+versioning scheme.
+
+### Alternative Runtimes
+
+Mockery will attempt to continue support HHVM, but will not make any guarantees.
+
+## A new home for Mockery
+
+⚠️️ Update your remotes! Mockery has transferred to a new location. While it was once
+at `padraic/mockery`, it is now at `mockery/mockery`. While your
+existing repositories will redirect transparently for any operations, take some
+time to transition to the new URL.
+```sh
+$ git remote set-url upstream https://github.com/mockery/mockery.git
+```
+Replace `upstream` with the name of the remote you use locally; `upstream` is commonly
+used but you may be using something else. Run `git remote -v` to see what you're actually
+using.
diff --git a/vendor/mockery/mockery/composer.json b/vendor/mockery/mockery/composer.json
new file mode 100644
index 0000000..4d7c96c
--- /dev/null
+++ b/vendor/mockery/mockery/composer.json
@@ -0,0 +1,56 @@
+{
+ "name": "mockery/mockery",
+ "description": "Mockery is a simple yet flexible PHP mock object framework",
+ "scripts": {
+ "docs": "phpdoc -d library -t docs/api"
+ },
+ "keywords": [
+ "bdd",
+ "library",
+ "mock",
+ "mock objects",
+ "mockery",
+ "stub",
+ "tdd",
+ "test",
+ "test double",
+ "testing"
+ ],
+ "homepage": "https://github.com/mockery/mockery",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Pádraic Brady",
+ "email": "padraic.brady@gmail.com",
+ "homepage": "http://blog.astrumfutura.com"
+ },
+ {
+ "name": "Dave Marshall",
+ "email": "dave.marshall@atstsolutions.co.uk",
+ "homepage": "http://davedevelopment.co.uk"
+ }
+ ],
+ "require": {
+ "php": ">=5.6.0",
+ "lib-pcre": ">=7.0",
+ "hamcrest/hamcrest-php": "~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5.7.10|~6.5|~7.0"
+ },
+ "autoload": {
+ "psr-0": {
+ "Mockery": "library/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "test\\": "tests/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/mockery/mockery/docker/php56/Dockerfile b/vendor/mockery/mockery/docker/php56/Dockerfile
new file mode 100644
index 0000000..264c5c0
--- /dev/null
+++ b/vendor/mockery/mockery/docker/php56/Dockerfile
@@ -0,0 +1,14 @@
+FROM php:5.6-cli
+
+RUN apt-get update && \
+ apt-get install -y git zip unzip && \
+ apt-get -y autoremove && \
+ apt-get clean && \
+ curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && \
+ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+WORKDIR /opt/mockery
+
+COPY composer.json ./
+
+RUN composer install
diff --git a/vendor/mockery/mockery/docs/.gitignore b/vendor/mockery/mockery/docs/.gitignore
new file mode 100644
index 0000000..e35d885
--- /dev/null
+++ b/vendor/mockery/mockery/docs/.gitignore
@@ -0,0 +1 @@
+_build
diff --git a/vendor/mockery/mockery/docs/Makefile b/vendor/mockery/mockery/docs/Makefile
new file mode 100644
index 0000000..9a8c940
--- /dev/null
+++ b/vendor/mockery/mockery/docs/Makefile
@@ -0,0 +1,177 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make ' where is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MockeryDocs.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MockeryDocs.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/MockeryDocs"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MockeryDocs"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through platex and dvipdfmx..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+ @echo
+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/vendor/mockery/mockery/docs/README.md b/vendor/mockery/mockery/docs/README.md
new file mode 100644
index 0000000..63ca69d
--- /dev/null
+++ b/vendor/mockery/mockery/docs/README.md
@@ -0,0 +1,4 @@
+mockery-docs
+============
+
+Document for the PHP Mockery framework on readthedocs.org
\ No newline at end of file
diff --git a/vendor/mockery/mockery/docs/conf.py b/vendor/mockery/mockery/docs/conf.py
new file mode 100644
index 0000000..901f040
--- /dev/null
+++ b/vendor/mockery/mockery/docs/conf.py
@@ -0,0 +1,267 @@
+# -*- coding: utf-8 -*-
+#
+# Mockery Docs documentation build configuration file, created by
+# sphinx-quickstart on Mon Mar 3 14:04:26 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.todo',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Mockery Docs'
+copyright = u'Pádraic Brady, Dave Marshall and contributors'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.0'
+# The full version, including alpha/beta/rc tags.
+release = '1.0-alpha'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'MockeryDocsdoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('index', 'MockeryDocs.tex', u'Mockery Docs Documentation',
+ u'Pádraic Brady, Dave Marshall, Wouter, Graham Campbell', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'mockerydocs', u'Mockery Docs Documentation',
+ [u'Pádraic Brady, Dave Marshall, Wouter, Graham Campbell'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'MockeryDocs', u'Mockery Docs Documentation',
+ u'Pádraic Brady, Dave Marshall, Wouter, Graham Campbell', 'MockeryDocs', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
+
+
+#on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+
+if not on_rtd: # only import and set the theme if we're building docs locally
+ import sphinx_rtd_theme
+ html_theme = 'sphinx_rtd_theme'
+ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+ print sphinx_rtd_theme.get_html_theme_path()
+
+# load PhpLexer
+from sphinx.highlighting import lexers
+from pygments.lexers.web import PhpLexer
+
+# enable highlighting for PHP code not between by default
+lexers['php'] = PhpLexer(startinline=True)
+lexers['php-annotations'] = PhpLexer(startinline=True)
diff --git a/vendor/mockery/mockery/docs/cookbook/big_parent_class.rst b/vendor/mockery/mockery/docs/cookbook/big_parent_class.rst
new file mode 100644
index 0000000..a27d532
--- /dev/null
+++ b/vendor/mockery/mockery/docs/cookbook/big_parent_class.rst
@@ -0,0 +1,52 @@
+.. index::
+ single: Cookbook; Big Parent Class
+
+Big Parent Class
+================
+
+In some application code, especially older legacy code, we can come across some
+classes that extend a "big parent class" - a parent class that knows and does
+too much:
+
+.. code-block:: php
+
+ class BigParentClass
+ {
+ public function doesEverything()
+ {
+ // sets up database connections
+ // writes to log files
+ }
+ }
+
+ class ChildClass extends BigParentClass
+ {
+ public function doesOneThing()
+ {
+ // but calls on BigParentClass methods
+ $result = $this->doesEverything();
+ // does something with $result
+ return $result;
+ }
+ }
+
+We want to test our ``ChildClass`` and its ``doesOneThing`` method, but the
+problem is that it calls on ``BigParentClass::doesEverything()``. One way to
+handle this would be to mock out **all** of the dependencies ``BigParentClass``
+has and needs, and then finally actually test our ``doesOneThing`` method. It's
+an awful lot of work to do that.
+
+What we can do, is to do something... unconventional. We can create a runtime
+partial test double of the ``ChildClass`` itself and mock only the parent's
+``doesEverything()`` method:
+
+.. code-block:: php
+
+ $childClass = \Mockery::mock('ChildClass')->makePartial();
+ $childClass->shouldReceive('doesEverything')
+ ->andReturn('some result from parent');
+
+ $childClass->doesOneThing(); // string("some result from parent");
+
+With this approach we mock out only the ``doesEverything()`` method, and all the
+unmocked methods are called on the actual ``ChildClass`` instance.
diff --git a/vendor/mockery/mockery/docs/cookbook/class_constants.rst b/vendor/mockery/mockery/docs/cookbook/class_constants.rst
new file mode 100644
index 0000000..0d13dd2
--- /dev/null
+++ b/vendor/mockery/mockery/docs/cookbook/class_constants.rst
@@ -0,0 +1,183 @@
+.. index::
+ single: Cookbook; Class Constants
+
+Class Constants
+===============
+
+When creating a test double for a class, Mockery does not create stubs out of
+any class constants defined in the class we are mocking. Sometimes though, the
+non-existence of these class constants, setup of the test, and the application
+code itself, it can lead to undesired behavior, and even a PHP error:
+``PHP Fatal error: Uncaught Error: Undefined class constant 'FOO' in ...```
+
+While supporting class constants in Mockery would be possible, it does require
+an awful lot of work, for a small number of use cases.
+
+Named Mocks
+-----------
+
+We can, however, deal with these constants in a way supported by Mockery - by
+using :ref:`creating-test-doubles-named-mocks`.
+
+A named mock is a test double that has a name of the class we want to mock, but
+under it is a stubbed out class that mimics the real class with canned responses.
+
+Lets look at the following made up, but not impossible scenario:
+
+.. code-block:: php
+
+ class Fetcher
+ {
+ const SUCCESS = 0;
+ const FAILURE = 1;
+
+ public static function fetch()
+ {
+ // Fetcher gets something for us from somewhere...
+ return self::SUCCESS;
+ }
+ }
+
+ class MyClass
+ {
+ public function doFetching()
+ {
+ $response = Fetcher::fetch();
+
+ if ($response == Fetcher::SUCCESS) {
+ echo "Thanks!" . PHP_EOL;
+ } else {
+ echo "Try again!" . PHP_EOL;
+ }
+ }
+ }
+
+Our ``MyClass`` calls a ``Fetcher`` that fetches some resource from somewhere -
+maybe it downloads a file from a remote web service. Our ``MyClass`` prints out
+a response message depending on the response from the ``Fetcher::fetch()`` call.
+
+When testing ``MyClass`` we don't really want ``Fetcher`` to go and download
+random stuff from the internet every time we run our test suite. So we mock it
+out:
+
+.. code-block:: php
+
+ // Using alias: because fetch is called statically!
+ \Mockery::mock('alias:Fetcher')
+ ->shouldReceive('fetch')
+ ->andReturn(0);
+
+ $myClass = new MyClass();
+ $myClass->doFetching();
+
+If we run this, our test will error out with a nasty
+``PHP Fatal error: Uncaught Error: Undefined class constant 'SUCCESS' in ..``.
+
+Here's how a ``namedMock()`` can help us in a situation like this.
+
+We create a stub for the ``Fetcher`` class, stubbing out the class constants,
+and then use ``namedMock()`` to create a mock named ``Fetcher`` based on our
+stub:
+
+.. code-block:: php
+
+ class FetcherStub
+ {
+ const SUCCESS = 0;
+ const FAILURE = 1;
+ }
+
+ \Mockery::mock('Fetcher', 'FetcherStub')
+ ->shouldReceive('fetch')
+ ->andReturn(0);
+
+ $myClass = new MyClass();
+ $myClass->doFetching();
+
+This works because under the hood, Mockery creates a class called ``Fetcher``
+that extends ``FetcherStub``.
+
+The same approach will work even if ``Fetcher::fetch()`` is not a static
+dependency:
+
+.. code-block:: php
+
+ class Fetcher
+ {
+ const SUCCESS = 0;
+ const FAILURE = 1;
+
+ public function fetch()
+ {
+ // Fetcher gets something for us from somewhere...
+ return self::SUCCESS;
+ }
+ }
+
+ class MyClass
+ {
+ public function doFetching($fetcher)
+ {
+ $response = $fetcher->fetch();
+
+ if ($response == Fetcher::SUCCESS) {
+ echo "Thanks!" . PHP_EOL;
+ } else {
+ echo "Try again!" . PHP_EOL;
+ }
+ }
+ }
+
+And the test will have something like this:
+
+.. code-block:: php
+
+ class FetcherStub
+ {
+ const SUCCESS = 0;
+ const FAILURE = 1;
+ }
+
+ $mock = \Mockery::mock('Fetcher', 'FetcherStub')
+ $mock->shouldReceive('fetch')
+ ->andReturn(0);
+
+ $myClass = new MyClass();
+ $myClass->doFetching($mock);
+
+
+Constants Map
+-------------
+
+Another way of mocking class constants can be with the use of the constants map configuration.
+
+Given a class with constants:
+
+.. code-block:: php
+
+ class Fetcher
+ {
+ const SUCCESS = 0;
+ const FAILURE = 1;
+
+ public function fetch()
+ {
+ // Fetcher gets something for us from somewhere...
+ return self::SUCCESS;
+ }
+ }
+
+It can be mocked with:
+
+.. code-block:: php
+
+ \Mockery::getConfiguration()->setConstantsMap([
+ 'Fetcher' => [
+ 'SUCCESS' => 'success',
+ 'FAILURE' => 'fail',
+ ]
+ ]);
+
+ $mock = \Mockery::mock('Fetcher');
+ var_dump($mock::SUCCESS); // (string) 'success'
+ var_dump($mock::FAILURE); // (string) 'fail'
diff --git a/vendor/mockery/mockery/docs/cookbook/default_expectations.rst b/vendor/mockery/mockery/docs/cookbook/default_expectations.rst
new file mode 100644
index 0000000..2c6fcae
--- /dev/null
+++ b/vendor/mockery/mockery/docs/cookbook/default_expectations.rst
@@ -0,0 +1,17 @@
+.. index::
+ single: Cookbook; Default Mock Expectations
+
+Default Mock Expectations
+=========================
+
+Often in unit testing, we end up with sets of tests which use the same object
+dependency over and over again. Rather than mocking this class/object within
+every single unit test (requiring a mountain of duplicate code), we can
+instead define reusable default mocks within the test case's ``setup()``
+method. This even works where unit tests use varying expectations on the same
+or similar mock object.
+
+How this works, is that you can define mocks with default expectations. Then,
+in a later unit test, you can add or fine-tune expectations for that specific
+test. Any expectation can be set as a default using the ``byDefault()``
+declaration.
diff --git a/vendor/mockery/mockery/docs/cookbook/detecting_mock_objects.rst b/vendor/mockery/mockery/docs/cookbook/detecting_mock_objects.rst
new file mode 100644
index 0000000..0210c69
--- /dev/null
+++ b/vendor/mockery/mockery/docs/cookbook/detecting_mock_objects.rst
@@ -0,0 +1,13 @@
+.. index::
+ single: Cookbook; Detecting Mock Objects
+
+Detecting Mock Objects
+======================
+
+Users may find it useful to check whether a given object is a real object or a
+simulated Mock Object. All Mockery mocks implement the
+``\Mockery\MockInterface`` interface which can be used in a type check.
+
+.. code-block:: php
+
+ assert($mightBeMocked instanceof \Mockery\MockInterface);
diff --git a/vendor/mockery/mockery/docs/cookbook/index.rst b/vendor/mockery/mockery/docs/cookbook/index.rst
new file mode 100644
index 0000000..48acbab
--- /dev/null
+++ b/vendor/mockery/mockery/docs/cookbook/index.rst
@@ -0,0 +1,15 @@
+Cookbook
+========
+
+.. toctree::
+ :hidden:
+
+ default_expectations
+ detecting_mock_objects
+ not_calling_the_constructor
+ mocking_hard_dependencies
+ class_constants
+ big_parent_class
+ mockery_on
+
+.. include:: map.rst.inc
diff --git a/vendor/mockery/mockery/docs/cookbook/map.rst.inc b/vendor/mockery/mockery/docs/cookbook/map.rst.inc
new file mode 100644
index 0000000..c9dd99e
--- /dev/null
+++ b/vendor/mockery/mockery/docs/cookbook/map.rst.inc
@@ -0,0 +1,7 @@
+* :doc:`/cookbook/default_expectations`
+* :doc:`/cookbook/detecting_mock_objects`
+* :doc:`/cookbook/not_calling_the_constructor`
+* :doc:`/cookbook/mocking_hard_dependencies`
+* :doc:`/cookbook/class_constants`
+* :doc:`/cookbook/big_parent_class`
+* :doc:`/cookbook/mockery_on`
diff --git a/vendor/mockery/mockery/docs/cookbook/mockery_on.rst b/vendor/mockery/mockery/docs/cookbook/mockery_on.rst
new file mode 100644
index 0000000..631f124
--- /dev/null
+++ b/vendor/mockery/mockery/docs/cookbook/mockery_on.rst
@@ -0,0 +1,85 @@
+.. index::
+ single: Cookbook; Complex Argument Matching With Mockery::on
+
+Complex Argument Matching With Mockery::on
+==========================================
+
+When we need to do a more complex argument matching for an expected method call,
+the ``\Mockery::on()`` matcher comes in really handy. It accepts a closure as an
+argument and that closure in turn receives the argument passed in to the method,
+when called. If the closure returns ``true``, Mockery will consider that the
+argument has passed the expectation. If the closure returns ``false``, or a
+"falsey" value, the expectation will not pass.
+
+The ``\Mockery::on()`` matcher can be used in various scenarios — validating
+an array argument based on multiple keys and values, complex string matching...
+
+Say, for example, we have the following code. It doesn't do much; publishes a
+post by setting the ``published`` flag in the database to ``1`` and sets the
+``published_at`` to the current date and time:
+
+.. code-block:: php
+
+ model = $model;
+ }
+
+ public function publishPost($id)
+ {
+ $saveData = [
+ 'post_id' => $id,
+ 'published' => 1,
+ 'published_at' => gmdate('Y-m-d H:i:s'),
+ ];
+ $this->model->save($saveData);
+ }
+ }
+
+In a test we would mock the model and set some expectations on the call of the
+``save()`` method:
+
+.. code-block:: php
+
+ shouldReceive('save')
+ ->once()
+ ->with(\Mockery::on(function ($argument) use ($postId) {
+ $postIdIsSet = isset($argument['post_id']) && $argument['post_id'] === $postId;
+ $publishedFlagIsSet = isset($argument['published']) && $argument['published'] === 1;
+ $publishedAtIsSet = isset($argument['published_at']);
+
+ return $postIdIsSet && $publishedFlagIsSet && $publishedAtIsSet;
+ }));
+
+ $service = new \Service\Post($modelMock);
+ $service->publishPost($postId);
+
+ \Mockery::close();
+
+The important part of the example is inside the closure we pass to the
+``\Mockery::on()`` matcher. The ``$argument`` is actually the ``$saveData`` argument
+the ``save()`` method gets when it is called. We check for a couple of things in
+this argument:
+
+* the post ID is set, and is same as the post ID we passed in to the
+ ``publishPost()`` method,
+* the ``published`` flag is set, and is ``1``, and
+* the ``published_at`` key is present.
+
+If any of these requirements is not satisfied, the closure will return ``false``,
+the method call expectation will not be met, and Mockery will throw a
+``NoMatchingExpectationException``.
+
+.. note::
+
+ This cookbook entry is an adaption of the blog post titled
+ `"Complex argument matching in Mockery" `_,
+ published by Robert Basic on his blog.
diff --git a/vendor/mockery/mockery/docs/cookbook/mocking_hard_dependencies.rst b/vendor/mockery/mockery/docs/cookbook/mocking_hard_dependencies.rst
new file mode 100644
index 0000000..b9381fd
--- /dev/null
+++ b/vendor/mockery/mockery/docs/cookbook/mocking_hard_dependencies.rst
@@ -0,0 +1,99 @@
+.. index::
+ single: Cookbook; Mocking Hard Dependencies
+
+Mocking Hard Dependencies (new Keyword)
+=======================================
+
+One prerequisite to mock hard dependencies is that the code we are trying to test uses autoloading.
+
+Let's take the following code for an example:
+
+.. code-block:: php
+
+ sendSomething($param);
+ return $externalService->getSomething();
+ }
+ }
+
+The way we can test this without doing any changes to the code itself is by creating :doc:`instance mocks ` by using the ``overload`` prefix.
+
+.. code-block:: php
+
+ shouldReceive('sendSomething')
+ ->once()
+ ->with($param);
+ $externalMock->shouldReceive('getSomething')
+ ->once()
+ ->andReturn('Tested!');
+
+ $service = new \App\Service();
+
+ $result = $service->callExternalService($param);
+
+ $this->assertSame('Tested!', $result);
+ }
+ }
+
+If we run this test now, it should pass. Mockery does its job and our ``App\Service`` will use the mocked external service instead of the real one.
+
+The problem with this is when we want to, for example, test the ``App\Service\External`` itself, or if we use that class somewhere else in our tests.
+
+When Mockery overloads a class, because of how PHP works with files, that overloaded class file must not be included otherwise Mockery will throw a "class already exists" exception. This is where autoloading kicks in and makes our job a lot easier.
+
+To make this possible, we'll tell PHPUnit to run the tests that have overloaded classes in separate processes and to not preserve global state. That way we'll avoid having the overloaded class included more than once. Of course this has its downsides as these tests will run slower.
+
+Our test example from above now becomes:
+
+.. code-block:: php
+
+ shouldReceive('sendSomething')
+ ->once()
+ ->with($param);
+ $externalMock->shouldReceive('getSomething')
+ ->once()
+ ->andReturn('Tested!');
+
+ $service = new \App\Service();
+
+ $result = $service->callExternalService($param);
+
+ $this->assertSame('Tested!', $result);
+ }
+ }
+
+.. note::
+
+ This cookbook entry is an adaption of the blog post titled
+ `"Mocking hard dependencies with Mockery" `_,
+ published by Robert Basic on his blog.
diff --git a/vendor/mockery/mockery/docs/cookbook/not_calling_the_constructor.rst b/vendor/mockery/mockery/docs/cookbook/not_calling_the_constructor.rst
new file mode 100644
index 0000000..b8157ae
--- /dev/null
+++ b/vendor/mockery/mockery/docs/cookbook/not_calling_the_constructor.rst
@@ -0,0 +1,63 @@
+.. index::
+ single: Cookbook; Not Calling the Original Constructor
+
+Not Calling the Original Constructor
+====================================
+
+When creating generated partial test doubles, Mockery mocks out only the method
+which we specifically told it to. This means that the original constructor of
+the class we are mocking will be called.
+
+In some cases this is not a desired behavior, as the constructor might issue
+calls to other methods, or other object collaborators, and as such, can create
+undesired side-effects in the application's environment when running the tests.
+
+If this happens, we need to use runtime partial test doubles, as they don't
+call the original constructor.
+
+.. code-block:: php
+
+ class MyClass
+ {
+ public function __construct()
+ {
+ echo "Original constructor called." . PHP_EOL;
+ // Other side-effects can happen...
+ }
+ }
+
+ // This will print "Original constructor called."
+ $mock = \Mockery::mock('MyClass[foo]');
+
+A better approach is to use runtime partial doubles:
+
+.. code-block:: php
+
+ class MyClass
+ {
+ public function __construct()
+ {
+ echo "Original constructor called." . PHP_EOL;
+ // Other side-effects can happen...
+ }
+ }
+
+ // This will not print anything
+ $mock = \Mockery::mock('MyClass')->makePartial();
+ $mock->shouldReceive('foo');
+
+This is one of the reason why we don't recommend using generated partial test
+doubles, but if possible, always use the runtime partials.
+
+Read more about :ref:`creating-test-doubles-partial-test-doubles`.
+
+.. note::
+
+ The way generated partial test doubles work, is a BC break. If you use a
+ really old version of Mockery, it might behave in a way that the constructor
+ is not being called for these generated partials. In the case if you upgrade
+ to a more recent version of Mockery, you'll probably have to change your
+ tests to use runtime partials, instead of generated ones.
+
+ This change was introduced in early 2013, so it is highly unlikely that you
+ are using a Mockery from before that, so this should not be an issue.
diff --git a/vendor/mockery/mockery/docs/getting_started/index.rst b/vendor/mockery/mockery/docs/getting_started/index.rst
new file mode 100644
index 0000000..434755c
--- /dev/null
+++ b/vendor/mockery/mockery/docs/getting_started/index.rst
@@ -0,0 +1,12 @@
+Getting Started
+===============
+
+.. toctree::
+ :hidden:
+
+ installation
+ upgrading
+ simple_example
+ quick_reference
+
+.. include:: map.rst.inc
diff --git a/vendor/mockery/mockery/docs/getting_started/installation.rst b/vendor/mockery/mockery/docs/getting_started/installation.rst
new file mode 100644
index 0000000..8019567
--- /dev/null
+++ b/vendor/mockery/mockery/docs/getting_started/installation.rst
@@ -0,0 +1,43 @@
+.. index::
+ single: Installation
+
+Installation
+============
+
+Mockery can be installed using Composer or by cloning it from its GitHub
+repository. These two options are outlined below.
+
+Composer
+--------
+
+You can read more about Composer on `getcomposer.org `_.
+To install Mockery using Composer, first install Composer for your project
+using the instructions on the `Composer download page `_.
+You can then define your development dependency on Mockery using the suggested
+parameters below. While every effort is made to keep the master branch stable,
+you may prefer to use the current stable version tag instead (use the
+``@stable`` tag).
+
+.. code-block:: json
+
+ {
+ "require-dev": {
+ "mockery/mockery": "dev-master"
+ }
+ }
+
+To install, you then may call:
+
+.. code-block:: bash
+
+ php composer.phar update
+
+This will install Mockery as a development dependency, meaning it won't be
+installed when using ``php composer.phar update --no-dev`` in production.
+
+Git
+---
+
+The Git repository hosts the development version in its master branch. You can
+install this using Composer by referencing ``dev-master`` as your preferred
+version in your project's ``composer.json`` file as the earlier example shows.
diff --git a/vendor/mockery/mockery/docs/getting_started/map.rst.inc b/vendor/mockery/mockery/docs/getting_started/map.rst.inc
new file mode 100644
index 0000000..1055945
--- /dev/null
+++ b/vendor/mockery/mockery/docs/getting_started/map.rst.inc
@@ -0,0 +1,4 @@
+* :doc:`/getting_started/installation`
+* :doc:`/getting_started/upgrading`
+* :doc:`/getting_started/simple_example`
+* :doc:`/getting_started/quick_reference`
diff --git a/vendor/mockery/mockery/docs/getting_started/quick_reference.rst b/vendor/mockery/mockery/docs/getting_started/quick_reference.rst
new file mode 100644
index 0000000..e729a85
--- /dev/null
+++ b/vendor/mockery/mockery/docs/getting_started/quick_reference.rst
@@ -0,0 +1,200 @@
+.. index::
+ single: Quick Reference
+
+Quick Reference
+===============
+
+The purpose of this page is to give a quick and short overview of some of the
+most common Mockery features.
+
+Do read the :doc:`../reference/index` to learn about all the Mockery features.
+
+Integrate Mockery with PHPUnit, either by extending the ``MockeryTestCase``:
+
+.. code-block:: php
+
+ use \Mockery\Adapter\Phpunit\MockeryTestCase;
+
+ class MyTest extends MockeryTestCase
+ {
+ }
+
+or by using the ``MockeryPHPUnitIntegration`` trait:
+
+.. code-block:: php
+
+ use \PHPUnit\Framework\TestCase;
+ use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
+
+ class MyTest extends TestCase
+ {
+ use MockeryPHPUnitIntegration;
+ }
+
+Creating a test double:
+
+.. code-block:: php
+
+ $testDouble = \Mockery::mock('MyClass');
+
+Creating a test double that implements a certain interface:
+
+.. code-block:: php
+
+ $testDouble = \Mockery::mock('MyClass, MyInterface');
+
+Expecting a method to be called on a test double:
+
+.. code-block:: php
+
+ $testDouble = \Mockery::mock('MyClass');
+ $testDouble->shouldReceive('foo');
+
+Expecting a method to **not** be called on a test double:
+
+.. code-block:: php
+
+ $testDouble = \Mockery::mock('MyClass');
+ $testDouble->shouldNotReceive('foo');
+
+Expecting a method to be called on a test double, once, with a certain argument,
+and to return a value:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->once()
+ ->with($arg)
+ ->andReturn($returnValue);
+
+Expecting a method to be called on a test double and to return a different value
+for each successive call:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->andReturn(1, 2, 3);
+
+ $mock->foo(); // int(1);
+ $mock->foo(); // int(2);
+ $mock->foo(); // int(3);
+ $mock->foo(); // int(3);
+
+Creating a runtime partial test double:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass')->makePartial();
+
+Creating a spy:
+
+.. code-block:: php
+
+ $spy = \Mockery::spy('MyClass');
+
+Expecting that a spy should have received a method call:
+
+.. code-block:: php
+
+ $spy = \Mockery::spy('MyClass');
+
+ $spy->foo();
+
+ $spy->shouldHaveReceived()->foo();
+
+Not so simple examples
+^^^^^^^^^^^^^^^^^^^^^^
+
+Creating a mock object to return a sequence of values from a set of method
+calls:
+
+.. code-block:: php
+
+ use \Mockery\Adapter\Phpunit\MockeryTestCase;
+
+ class SimpleTest extends MockeryTestCase
+ {
+ public function testSimpleMock()
+ {
+ $mock = \Mockery::mock(array('pi' => 3.1416, 'e' => 2.71));
+ $this->assertEquals(3.1416, $mock->pi());
+ $this->assertEquals(2.71, $mock->e());
+ }
+ }
+
+Creating a mock object which returns a self-chaining Undefined object for a
+method call:
+
+.. code-block:: php
+
+ use \Mockery\Adapter\Phpunit\MockeryTestCase;
+
+ class UndefinedTest extends MockeryTestCase
+ {
+ public function testUndefinedValues()
+ {
+ $mock = \Mockery::mock('mymock');
+ $mock->shouldReceive('divideBy')->with(0)->andReturnUndefined();
+ $this->assertTrue($mock->divideBy(0) instanceof \Mockery\Undefined);
+ }
+ }
+
+Creating a mock object with multiple query calls and a single update call:
+
+.. code-block:: php
+
+ use \Mockery\Adapter\Phpunit\MockeryTestCase;
+
+ class DbTest extends MockeryTestCase
+ {
+ public function testDbAdapter()
+ {
+ $mock = \Mockery::mock('db');
+ $mock->shouldReceive('query')->andReturn(1, 2, 3);
+ $mock->shouldReceive('update')->with(5)->andReturn(NULL)->once();
+
+ // ... test code here using the mock
+ }
+ }
+
+Expecting all queries to be executed before any updates:
+
+.. code-block:: php
+
+ use \Mockery\Adapter\Phpunit\MockeryTestCase;
+
+ class DbTest extends MockeryTestCase
+ {
+ public function testQueryAndUpdateOrder()
+ {
+ $mock = \Mockery::mock('db');
+ $mock->shouldReceive('query')->andReturn(1, 2, 3)->ordered();
+ $mock->shouldReceive('update')->andReturn(NULL)->once()->ordered();
+
+ // ... test code here using the mock
+ }
+ }
+
+Creating a mock object where all queries occur after startup, but before finish,
+and where queries are expected with several different params:
+
+.. code-block:: php
+
+ use \Mockery\Adapter\Phpunit\MockeryTestCase;
+
+ class DbTest extends MockeryTestCase
+ {
+ public function testOrderedQueries()
+ {
+ $db = \Mockery::mock('db');
+ $db->shouldReceive('startup')->once()->ordered();
+ $db->shouldReceive('query')->with('CPWR')->andReturn(12.3)->once()->ordered('queries');
+ $db->shouldReceive('query')->with('MSFT')->andReturn(10.0)->once()->ordered('queries');
+ $db->shouldReceive('query')->with(\Mockery::pattern("/^....$/"))->andReturn(3.3)->atLeast()->once()->ordered('queries');
+ $db->shouldReceive('finish')->once()->ordered();
+
+ // ... test code here using the mock
+ }
+ }
diff --git a/vendor/mockery/mockery/docs/getting_started/simple_example.rst b/vendor/mockery/mockery/docs/getting_started/simple_example.rst
new file mode 100644
index 0000000..1fb252e
--- /dev/null
+++ b/vendor/mockery/mockery/docs/getting_started/simple_example.rst
@@ -0,0 +1,70 @@
+.. index::
+ single: Getting Started; Simple Example
+
+Simple Example
+==============
+
+Imagine we have a ``Temperature`` class which samples the temperature of a
+locale before reporting an average temperature. The data could come from a web
+service or any other data source, but we do not have such a class at present.
+We can, however, assume some basic interactions with such a class based on its
+interaction with the ``Temperature`` class:
+
+.. code-block:: php
+
+ class Temperature
+ {
+ private $service;
+
+ public function __construct($service)
+ {
+ $this->service = $service;
+ }
+
+ public function average()
+ {
+ $total = 0;
+ for ($i=0; $i<3; $i++) {
+ $total += $this->service->readTemp();
+ }
+ return $total/3;
+ }
+ }
+
+Even without an actual service class, we can see how we expect it to operate.
+When writing a test for the ``Temperature`` class, we can now substitute a
+mock object for the real service which allows us to test the behaviour of the
+``Temperature`` class without actually needing a concrete service instance.
+
+.. code-block:: php
+
+ use \Mockery;
+
+ class TemperatureTest extends PHPUnit_Framework_TestCase
+ {
+ public function tearDown()
+ {
+ Mockery::close();
+ }
+
+ public function testGetsAverageTemperatureFromThreeServiceReadings()
+ {
+ $service = Mockery::mock('service');
+ $service->shouldReceive('readTemp')
+ ->times(3)
+ ->andReturn(10, 12, 14);
+
+ $temperature = new Temperature($service);
+
+ $this->assertEquals(12, $temperature->average());
+ }
+ }
+
+We create a mock object which our ``Temperature`` class will use and set some
+expectations for that mock — that it should receive three calls to the ``readTemp``
+method, and these calls will return 10, 12, and 14 as results.
+
+.. note::
+
+ PHPUnit integration can remove the need for a ``tearDown()`` method. See
+ ":doc:`/reference/phpunit_integration`" for more information.
diff --git a/vendor/mockery/mockery/docs/getting_started/upgrading.rst b/vendor/mockery/mockery/docs/getting_started/upgrading.rst
new file mode 100644
index 0000000..7201e59
--- /dev/null
+++ b/vendor/mockery/mockery/docs/getting_started/upgrading.rst
@@ -0,0 +1,82 @@
+.. index::
+ single: Upgrading
+
+Upgrading
+=========
+
+Upgrading to 1.0.0
+------------------
+
+Minimum PHP version
++++++++++++++++++++
+
+As of Mockery 1.0.0 the minimum PHP version required is 5.6.
+
+Using Mockery with PHPUnit
+++++++++++++++++++++++++++
+
+In the "old days", 0.9.x and older, the way Mockery was integrated with PHPUnit was
+through a PHPUnit listener. That listener would in turn call the ``\Mockery::close()``
+method for us.
+
+As of 1.0.0, PHPUnit test cases where we want to use Mockery, should either use the
+``\Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration`` trait, or extend the
+``\Mockery\Adapter\Phpunit\MockeryTestCase`` test case. This will in turn call the
+``\Mockery::close()`` method for us.
+
+Read the documentation for a detailed overview of ":doc:`/reference/phpunit_integration`".
+
+``\Mockery\Matcher\MustBe`` is deprecated
++++++++++++++++++++++++++++++++++++++++++
+
+As of 1.0.0 the ``\Mockery\Matcher\MustBe`` matcher is deprecated and will be removed in
+Mockery 2.0.0. We recommend instead to use the PHPUnit or Hamcrest equivalents of the
+MustBe matcher.
+
+``allows`` and ``expects``
+++++++++++++++++++++++++++
+
+As of 1.0.0, Mockery has two new methods to set up expectations: ``allows`` and ``expects``.
+This means that these methods names are now "reserved" for Mockery, or in other words
+classes you want to mock with Mockery, can't have methods called ``allows`` or ``expects``.
+
+Read more in the documentation about this ":doc:`/reference/alternative_should_receive_syntax`".
+
+No more implicit regex matching for string arguments
+++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+When setting up string arguments in method expectations, Mockery 0.9.x and older, would try
+to match arguments using a regular expression in a "last attempt" scenario.
+
+As of 1.0.0, Mockery will no longer attempt to do this regex matching, but will only try
+first the identical operator ``===``, and failing that, the equals operator ``==``.
+
+If you want to match an argument using regular expressions, please use the new
+``\Mockery\Matcher\Pattern`` matcher. Read more in the documentation about this
+pattern matcher in the ":doc:`/reference/argument_validation`" section.
+
+``andThrow`` ``\Throwable``
++++++++++++++++++++++++++++
+
+As of 1.0.0, the ``andThrow`` can now throw any ``\Throwable``.
+
+Upgrading to 0.9
+----------------
+
+The generator was completely rewritten, so any code with a deep integration to
+mockery will need evaluating.
+
+Upgrading to 0.8
+----------------
+
+Since the release of 0.8.0 the following behaviours were altered:
+
+1. The ``shouldIgnoreMissing()`` behaviour optionally applied to mock objects
+ returned an instance of ``\Mockery\Undefined`` when methods called did not
+ match a known expectation. Since 0.8.0, this behaviour was switched to
+ returning ``null`` instead. You can restore the 0.7.2 behaviour by using the
+ following:
+
+ .. code-block:: php
+
+ $mock = \Mockery::mock('stdClass')->shouldIgnoreMissing()->asUndefined();
diff --git a/vendor/mockery/mockery/docs/index.rst b/vendor/mockery/mockery/docs/index.rst
new file mode 100644
index 0000000..f8cbbd3
--- /dev/null
+++ b/vendor/mockery/mockery/docs/index.rst
@@ -0,0 +1,76 @@
+Mockery
+=======
+
+Mockery is a simple yet flexible PHP mock object framework for use in unit
+testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is
+to offer a test double framework with a succinct API capable of clearly
+defining all possible object operations and interactions using a human
+readable Domain Specific Language (DSL). Designed as a drop in alternative to
+PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with
+PHPUnit and can operate alongside phpunit-mock-objects without the World
+ending.
+
+Mock Objects
+------------
+
+In unit tests, mock objects simulate the behaviour of real objects. They are
+commonly utilised to offer test isolation, to stand in for objects which do
+not yet exist, or to allow for the exploratory design of class APIs without
+requiring actual implementation up front.
+
+The benefits of a mock object framework are to allow for the flexible
+generation of such mock objects (and stubs). They allow the setting of
+expected method calls and return values using a flexible API which is capable
+of capturing every possible real object behaviour in way that is stated as
+close as possible to a natural language description.
+
+Getting Started
+---------------
+
+Ready to dive into the Mockery framework? Then you can get started by reading
+the "Getting Started" section!
+
+.. toctree::
+ :hidden:
+
+ getting_started/index
+
+.. include:: getting_started/map.rst.inc
+
+Reference
+---------
+
+The reference contains a complete overview of all features of the Mockery
+framework.
+
+.. toctree::
+ :hidden:
+
+ reference/index
+
+.. include:: reference/map.rst.inc
+
+Mockery
+-------
+
+Learn about Mockery's configuration, reserved method names, exceptions...
+
+.. toctree::
+ :hidden:
+
+ mockery/index
+
+.. include:: mockery/map.rst.inc
+
+Cookbook
+--------
+
+Want to learn some easy tips and tricks? Take a look at the cookbook articles!
+
+.. toctree::
+ :hidden:
+
+ cookbook/index
+
+.. include:: cookbook/map.rst.inc
+
diff --git a/vendor/mockery/mockery/docs/mockery/configuration.rst b/vendor/mockery/mockery/docs/mockery/configuration.rst
new file mode 100644
index 0000000..3a89579
--- /dev/null
+++ b/vendor/mockery/mockery/docs/mockery/configuration.rst
@@ -0,0 +1,77 @@
+.. index::
+ single: Mockery; Configuration
+
+Mockery Global Configuration
+============================
+
+To allow for a degree of fine-tuning, Mockery utilises a singleton
+configuration object to store a small subset of core behaviours. The two
+currently present include:
+
+* Option to allow/disallow the mocking of methods which do not actually exist
+ fulfilled (i.e. unused)
+* Setter/Getter for added a parameter map for internal PHP class methods
+ (``Reflection`` cannot detect these automatically)
+
+By default, the first behaviour is enabled. Of course, there are
+situations where this can lead to unintended consequences. The mocking of
+non-existent methods may allow mocks based on real classes/objects to fall out
+of sync with the actual implementations, especially when some degree of
+integration testing (testing of object wiring) is not being performed.
+
+You may allow or disallow this behaviour (whether for whole test suites or
+just select tests) by using the following call:
+
+.. code-block:: php
+
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(bool);
+
+Passing a true allows the behaviour, false disallows it. It takes effect
+immediately until switched back. If the behaviour is detected when not allowed,
+it will result in an Exception being thrown at that point. Note that disallowing
+this behaviour should be carefully considered since it necessarily removes at
+least some of Mockery's flexibility.
+
+The other two methods are:
+
+.. code-block:: php
+
+ \Mockery::getConfiguration()->setInternalClassMethodParamMap($class, $method, array $paramMap)
+ \Mockery::getConfiguration()->getInternalClassMethodParamMap($class, $method)
+
+These are used to define parameters (i.e. the signature string of each) for the
+methods of internal PHP classes (e.g. SPL, or PECL extension classes like
+ext/mongo's MongoCollection. Reflection cannot analyse the parameters of internal
+classes. Most of the time, you never need to do this. It's mainly needed where an
+internal class method uses pass-by-reference for a parameter - you MUST in such
+cases ensure the parameter signature includes the ``&`` symbol correctly as Mockery
+won't correctly add it automatically for internal classes.
+
+Disabling reflection caching
+----------------------------
+
+Mockery heavily uses `"reflection" `_
+to do it's job. To speed up things, Mockery caches internally the information it
+gathers via reflection. In some cases, this caching can cause problems.
+
+The **only** known situation when this occurs is when PHPUnit's ``--static-backup`` option
+is used. If you use ``--static-backup`` and you get an error that looks like the
+following:
+
+.. code-block:: php
+
+ Error: Internal error: Failed to retrieve the reflection object
+
+We suggest turning off the reflection cache as so:
+
+.. code-block:: php
+
+ \Mockery::getConfiguration()->disableReflectionCache();
+
+Turning it back on can be done like so:
+
+.. code-block:: php
+
+ \Mockery::getConfiguration()->enableReflectionCache();
+
+In no other situation should you be required turn this reflection cache off.
diff --git a/vendor/mockery/mockery/docs/mockery/exceptions.rst b/vendor/mockery/mockery/docs/mockery/exceptions.rst
new file mode 100644
index 0000000..623b158
--- /dev/null
+++ b/vendor/mockery/mockery/docs/mockery/exceptions.rst
@@ -0,0 +1,65 @@
+.. index::
+ single: Mockery; Exceptions
+
+Mockery Exceptions
+==================
+
+Mockery throws three types of exceptions when it cannot verify a mock object.
+
+#. ``\Mockery\Exception\InvalidCountException``
+#. ``\Mockery\Exception\InvalidOrderException``
+#. ``\Mockery\Exception\NoMatchingExpectationException``
+
+You can capture any of these exceptions in a try...catch block to query them
+for specific information which is also passed along in the exception message
+but is provided separately from getters should they be useful when logging or
+reformatting output.
+
+\Mockery\Exception\InvalidCountException
+----------------------------------------
+
+The exception class is used when a method is called too many (or too few)
+times and offers the following methods:
+
+* ``getMock()`` - return actual mock object
+* ``getMockName()`` - return the name of the mock object
+* ``getMethodName()`` - return the name of the method the failing expectation
+ is attached to
+* ``getExpectedCount()`` - return expected calls
+* ``getExpectedCountComparative()`` - returns a string, e.g. ``<=`` used to
+ compare to actual count
+* ``getActualCount()`` - return actual calls made with given argument
+ constraints
+
+\Mockery\Exception\InvalidOrderException
+----------------------------------------
+
+The exception class is used when a method is called outside the expected order
+set using the ``ordered()`` and ``globally()`` expectation modifiers. It
+offers the following methods:
+
+* ``getMock()`` - return actual mock object
+* ``getMockName()`` - return the name of the mock object
+* ``getMethodName()`` - return the name of the method the failing expectation
+ is attached to
+* ``getExpectedOrder()`` - returns an integer represented the expected index
+ for which this call was expected
+* ``getActualOrder()`` - return the actual index at which this method call
+ occurred.
+
+\Mockery\Exception\NoMatchingExpectationException
+-------------------------------------------------
+
+The exception class is used when a method call does not match any known
+expectation. All expectations are uniquely identified in a mock object by the
+method name and the list of expected arguments. You can disable this exception
+and opt for returning NULL from all unexpected method calls by using the
+earlier mentioned shouldIgnoreMissing() behaviour modifier. This exception
+class offers the following methods:
+
+* ``getMock()`` - return actual mock object
+* ``getMockName()`` - return the name of the mock object
+* ``getMethodName()`` - return the name of the method the failing expectation
+ is attached to
+* ``getActualArguments()`` - return actual arguments used to search for a
+ matching expectation
diff --git a/vendor/mockery/mockery/docs/mockery/gotchas.rst b/vendor/mockery/mockery/docs/mockery/gotchas.rst
new file mode 100644
index 0000000..ebd690f
--- /dev/null
+++ b/vendor/mockery/mockery/docs/mockery/gotchas.rst
@@ -0,0 +1,48 @@
+.. index::
+ single: Mockery; Gotchas
+
+Gotchas!
+========
+
+Mocking objects in PHP has its limitations and gotchas. Some functionality
+can't be mocked or can't be mocked YET! If you locate such a circumstance,
+please please (pretty please with sugar on top) create a new issue on GitHub
+so it can be documented and resolved where possible. Here is a list to note:
+
+1. Classes containing public ``__wakeup()`` methods can be mocked but the
+ mocked ``__wakeup()`` method will perform no actions and cannot have
+ expectations set for it. This is necessary since Mockery must serialize and
+ unserialize objects to avoid some ``__construct()`` insanity and attempting
+ to mock a ``__wakeup()`` method as normal leads to a
+ ``BadMethodCallException`` being thrown.
+
+2. Classes using non-real methods, i.e. where a method call triggers a
+ ``__call()`` method, will throw an exception that the non-real method does
+ not exist unless you first define at least one expectation (a simple
+ ``shouldReceive()`` call would suffice). This is necessary since there is
+ no other way for Mockery to be aware of the method name.
+
+3. Mockery has two scenarios where real classes are replaced: Instance mocks
+ and alias mocks. Both will generate PHP fatal errors if the real class is
+ loaded, usually via a require or include statement. Only use these two mock
+ types where autoloading is in place and where classes are not explicitly
+ loaded on a per-file basis using ``require()``, ``require_once()``, etc.
+
+4. Internal PHP classes are not entirely capable of being fully analysed using
+ ``Reflection``. For example, ``Reflection`` cannot reveal details of
+ expected parameters to the methods of such internal classes. As a result,
+ there will be problems where a method parameter is defined to accept a
+ value by reference (Mockery cannot detect this condition and will assume a
+ pass by value on scalars and arrays). If references as internal class
+ method parameters are needed, you should use the
+ ``\Mockery\Configuration::setInternalClassMethodParamMap()`` method.
+
+5. Creating a mock implementing a certain interface with incorrect case in the
+ interface name, and then creating a second mock implementing the same
+ interface, but this time with the correct case, will have undefined behavior
+ due to PHP's ``class_exists`` and related functions being case insensitive.
+ Using the ``::class`` keyword in PHP can help you avoid these mistakes.
+
+The gotchas noted above are largely down to PHP's architecture and are assumed
+to be unavoidable. But - if you figure out a solution (or a better one than
+what may exist), let us know!
diff --git a/vendor/mockery/mockery/docs/mockery/index.rst b/vendor/mockery/mockery/docs/mockery/index.rst
new file mode 100644
index 0000000..b698d6c
--- /dev/null
+++ b/vendor/mockery/mockery/docs/mockery/index.rst
@@ -0,0 +1,12 @@
+Mockery
+=======
+
+.. toctree::
+ :hidden:
+
+ configuration
+ exceptions
+ reserved_method_names
+ gotchas
+
+.. include:: map.rst.inc
diff --git a/vendor/mockery/mockery/docs/mockery/map.rst.inc b/vendor/mockery/mockery/docs/mockery/map.rst.inc
new file mode 100644
index 0000000..46ffa97
--- /dev/null
+++ b/vendor/mockery/mockery/docs/mockery/map.rst.inc
@@ -0,0 +1,4 @@
+* :doc:`/mockery/configuration`
+* :doc:`/mockery/exceptions`
+* :doc:`/mockery/reserved_method_names`
+* :doc:`/mockery/gotchas`
diff --git a/vendor/mockery/mockery/docs/mockery/reserved_method_names.rst b/vendor/mockery/mockery/docs/mockery/reserved_method_names.rst
new file mode 100644
index 0000000..112d6f0
--- /dev/null
+++ b/vendor/mockery/mockery/docs/mockery/reserved_method_names.rst
@@ -0,0 +1,20 @@
+.. index::
+ single: Reserved Method Names
+
+Reserved Method Names
+=====================
+
+As you may have noticed, Mockery uses a number of methods called directly on
+all mock objects, for example ``shouldReceive()``. Such methods are necessary
+in order to setup expectations on the given mock, and so they cannot be
+implemented on the classes or objects being mocked without creating a method
+name collision (reported as a PHP fatal error). The methods reserved by
+Mockery are:
+
+* ``shouldReceive()``
+* ``shouldBeStrict()``
+
+In addition, all mocks utilise a set of added methods and protected properties
+which cannot exist on the class or object being mocked. These are far less
+likely to cause collisions. All properties are prefixed with ``_mockery`` and
+all method names with ``mockery_``.
diff --git a/vendor/mockery/mockery/docs/reference/alternative_should_receive_syntax.rst b/vendor/mockery/mockery/docs/reference/alternative_should_receive_syntax.rst
new file mode 100644
index 0000000..78c1e83
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/alternative_should_receive_syntax.rst
@@ -0,0 +1,91 @@
+.. index::
+ single: Alternative shouldReceive Syntax
+
+Alternative shouldReceive Syntax
+================================
+
+As of Mockery 1.0.0, we support calling methods as we would call any PHP method,
+and not as string arguments to Mockery ``should*`` methods.
+
+The two Mockery methods that enable this are ``allows()`` and ``expects()``.
+
+Allows
+------
+
+We use ``allows()`` when we create stubs for methods that return a predefined
+return value, but for these method stubs we don't care how many times, or if at
+all, were they called.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->allows([
+ 'name_of_method_1' => 'return value',
+ 'name_of_method_2' => 'return value',
+ ]);
+
+This is equivalent with the following ``shouldReceive`` syntax:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive([
+ 'name_of_method_1' => 'return value',
+ 'name_of_method_2' => 'return value',
+ ]);
+
+Note that with this format, we also tell Mockery that we don't care about the
+arguments to the stubbed methods.
+
+If we do care about the arguments, we would do it like so:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->allows()
+ ->name_of_method_1($arg1)
+ ->andReturn('return value');
+
+This is equivalent with the following ``shouldReceive`` syntax:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method_1')
+ ->with($arg1)
+ ->andReturn('return value');
+
+Expects
+-------
+
+We use ``expects()`` when we want to verify that a particular method was called:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->expects()
+ ->name_of_method_1($arg1)
+ ->andReturn('return value');
+
+This is equivalent with the following ``shouldReceive`` syntax:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method_1')
+ ->once()
+ ->with($arg1)
+ ->andReturn('return value');
+
+By default ``expects()`` sets up an expectation that the method should be called
+once and once only. If we expect more than one call to the method, we can change
+that expectation:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->expects()
+ ->name_of_method_1($arg1)
+ ->twice()
+ ->andReturn('return value');
+
diff --git a/vendor/mockery/mockery/docs/reference/argument_validation.rst b/vendor/mockery/mockery/docs/reference/argument_validation.rst
new file mode 100644
index 0000000..735407c
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/argument_validation.rst
@@ -0,0 +1,317 @@
+.. index::
+ single: Argument Validation
+
+Argument Validation
+===================
+
+The arguments passed to the ``with()`` declaration when setting up an
+expectation determine the criteria for matching method calls to expectations.
+Thus, we can setup up many expectations for a single method, each
+differentiated by the expected arguments. Such argument matching is done on a
+"best fit" basis. This ensures explicit matches take precedence over
+generalised matches.
+
+An explicit match is merely where the expected argument and the actual
+argument are easily equated (i.e. using ``===`` or ``==``). More generalised
+matches are possible using regular expressions, class hinting and the
+available generic matchers. The purpose of generalised matchers is to allow
+arguments be defined in non-explicit terms, e.g. ``Mockery::any()`` passed to
+``with()`` will match **any** argument in that position.
+
+Mockery's generic matchers do not cover all possibilities but offers optional
+support for the Hamcrest library of matchers. Hamcrest is a PHP port of the
+similarly named Java library (which has been ported also to Python, Erlang,
+etc). By using Hamcrest, Mockery does not need to duplicate Hamcrest's already
+impressive utility which itself promotes a natural English DSL.
+
+The examples below show Mockery matchers and their Hamcrest equivalent, if there
+is one. Hamcrest uses functions (no namespacing).
+
+.. note::
+
+ If you don't wish to use the global Hamcrest functions, they are all exposed
+ through the ``\Hamcrest\Matchers`` class as well, as static methods. Thus,
+ ``identicalTo($arg)`` is the same as ``\Hamcrest\Matchers::identicalTo($arg)``
+
+The most common matcher is the ``with()`` matcher:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(1):
+
+It tells mockery that it should receive a call to the ``foo`` method with the
+integer ``1`` as an argument. In cases like this, Mockery first tries to match
+the arguments using ``===`` (identical) comparison operator. If the argument is
+a primitive, and if it fails the identical comparison, Mockery does a fallback
+to the ``==`` (equals) comparison operator.
+
+When matching objects as arguments, Mockery only does the strict ``===``
+comparison, which means only the same ``$object`` will match:
+
+.. code-block:: php
+
+ $object = new stdClass();
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive("foo")
+ ->with($object);
+
+ // Hamcrest equivalent
+ $mock->shouldReceive("foo")
+ ->with(identicalTo($object));
+
+A different instance of ``stdClass`` will **not** match.
+
+.. note::
+
+ The ``Mockery\Matcher\MustBe`` matcher has been deprecated.
+
+If we need a loose comparison of objects, we can do that using Hamcrest's
+``equalTo`` matcher:
+
+.. code-block:: php
+
+ $mock->shouldReceive("foo")
+ ->with(equalTo(new stdClass));
+
+In cases when we don't care about the type, or the value of an argument, just
+that any argument is present, we use ``any()``:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive("foo")
+ ->with(\Mockery::any());
+
+ // Hamcrest equivalent
+ $mock->shouldReceive("foo")
+ ->with(anything())
+
+Anything and everything passed in this argument slot is passed unconstrained.
+
+Validating Types and Resources
+------------------------------
+
+The ``type()`` matcher accepts any string which can be attached to ``is_`` to
+form a valid type check.
+
+To match any PHP resource, we could do the following:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive("foo")
+ ->with(\Mockery::type('resource'));
+
+ // Hamcrest equivalents
+ $mock->shouldReceive("foo")
+ ->with(resourceValue());
+ $mock->shouldReceive("foo")
+ ->with(typeOf('resource'));
+
+It will return a ``true`` from an ``is_resource()`` call, if the provided
+argument to the method is a PHP resource. For example, ``\Mockery::type('float')``
+or Hamcrest's ``floatValue()`` and ``typeOf('float')`` checks use ``is_float()``,
+and ``\Mockery::type('callable')`` or Hamcrest's ``callable()`` uses
+``is_callable()``.
+
+The ``type()`` matcher also accepts a class or interface name to be used in an
+``instanceof`` evaluation of the actual argument. Hamcrest uses ``anInstanceOf()``.
+
+A full list of the type checkers is available at
+`php.net `_ or browse Hamcrest's function
+list in
+`the Hamcrest code `_.
+
+.. _argument-validation-complex-argument-validation:
+
+Complex Argument Validation
+---------------------------
+
+If we want to perform a complex argument validation, the ``on()`` matcher is
+invaluable. It accepts a closure (anonymous function) to which the actual
+argument will be passed.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive("foo")
+ ->with(\Mockery::on(closure));
+
+If the closure evaluates to (i.e. returns) boolean ``true`` then the argument is
+assumed to have matched the expectation.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::on(function ($argument) {
+ if ($argument % 2 == 0) {
+ return true;
+ }
+ return false;
+ }));
+
+ $mock->foo(4); // matches the expectation
+ $mock->foo(3); // throws a NoMatchingExpectationException
+
+.. note::
+
+ There is no Hamcrest version of the ``on()`` matcher.
+
+We can also perform argument validation by passing a closure to ``withArgs()``
+method. The closure will receive all arguments passed in the call to the expected
+method and if it evaluates (i.e. returns) to boolean ``true``, then the list of
+arguments is assumed to have matched the expectation:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive("foo")
+ ->withArgs(closure);
+
+The closure can also handle optional parameters, so if an optional parameter is
+missing in the call to the expected method, it doesn't necessary means that the
+list of arguments doesn't match the expectation.
+
+.. code-block:: php
+
+ $closure = function ($odd, $even, $sum = null) {
+ $result = ($odd % 2 != 0) && ($even % 2 == 0);
+ if (!is_null($sum)) {
+ return $result && ($odd + $even == $sum);
+ }
+ return $result;
+ };
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')->withArgs($closure);
+
+ $mock->foo(1, 2); // It matches the expectation: the optional argument is not needed
+ $mock->foo(1, 2, 3); // It also matches the expectation: the optional argument pass the validation
+ $mock->foo(1, 2, 4); // It doesn't match the expectation: the optional doesn't pass the validation
+
+.. note::
+
+ In previous versions, Mockery's ``with()`` would attempt to do a pattern
+ matching against the arguments, attempting to use the argument as a
+ regular expression. Over time this proved to be not such a great idea, so
+ we removed this functionality, and have introduced ``Mockery::pattern()``
+ instead.
+
+If we would like to match an argument against a regular expression, we can use
+the ``\Mockery::pattern()``:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::pattern('/^foo/'));
+
+ // Hamcrest equivalent
+ $mock->shouldReceive('foo')
+ with(matchesPattern('/^foo/'));
+
+The ``ducktype()`` matcher is an alternative to matching by class type:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::ducktype('foo', 'bar'));
+
+It matches any argument which is an object containing the provided list of
+methods to call.
+
+.. note::
+
+ There is no Hamcrest version of the ``ducktype()`` matcher.
+
+Additional Argument Matchers
+----------------------------
+
+The ``not()`` matcher matches any argument which is not equal or identical to
+the matcher's parameter:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::not(2));
+
+ // Hamcrest equivalent
+ $mock->shouldReceive('foo')
+ ->with(not(2));
+
+``anyOf()`` matches any argument which equals any one of the given parameters:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::anyOf(1, 2));
+
+ // Hamcrest equivalent
+ $mock->shouldReceive('foo')
+ ->with(anyOf(1,2));
+
+``notAnyOf()`` matches any argument which is not equal or identical to any of
+the given parameters:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::notAnyOf(1, 2));
+
+.. note::
+
+ There is no Hamcrest version of the ``notAnyOf()`` matcher.
+
+``subset()`` matches any argument which is any array containing the given array
+subset:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::subset(array(0 => 'foo')));
+
+This enforces both key naming and values, i.e. both the key and value of each
+actual element is compared.
+
+.. note::
+
+ There is no Hamcrest version of this functionality, though Hamcrest can check
+ a single entry using ``hasEntry()`` or ``hasKeyValuePair()``.
+
+``contains()`` matches any argument which is an array containing the listed
+values:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::contains(value1, value2));
+
+The naming of keys is ignored.
+
+``hasKey()`` matches any argument which is an array containing the given key
+name:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::hasKey(key));
+
+``hasValue()`` matches any argument which is an array containing the given
+value:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('foo')
+ ->with(\Mockery::hasValue(value));
diff --git a/vendor/mockery/mockery/docs/reference/creating_test_doubles.rst b/vendor/mockery/mockery/docs/reference/creating_test_doubles.rst
new file mode 100644
index 0000000..377812d
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/creating_test_doubles.rst
@@ -0,0 +1,419 @@
+.. index::
+ single: Reference; Creating Test Doubles
+
+Creating Test Doubles
+=====================
+
+Mockery's main goal is to help us create test doubles. It can create stubs,
+mocks, and spies.
+
+Stubs and mocks are created the same. The difference between the two is that a
+stub only returns a preset result when called, while a mock needs to have
+expectations set on the method calls it expects to receive.
+
+Spies are a type of test doubles that keep track of the calls they received, and
+allow us to inspect these calls after the fact.
+
+When creating a test double object, we can pass in an identifier as a name for
+our test double. If we pass it no identifier, the test double name will be
+unknown. Furthermore, the identifier must not be a class name. It is a
+good practice, and our recommendation, to always name the test doubles with the
+same name as the underlying class we are creating test doubles for.
+
+If the identifier we use for our test double is a name of an existing class,
+the test double will inherit the type of the class (via inheritance), i.e. the
+mock object will pass type hints or ``instanceof`` evaluations for the existing
+class. This is useful when a test double must be of a specific type, to satisfy
+the expectations our code has.
+
+Stubs and mocks
+---------------
+
+Stubs and mocks are created by calling the ``\Mockery::mock()`` method. The
+following example shows how to create a stub, or a mock, object named "foo":
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('foo');
+
+The mock object created like this is the loosest form of mocks possible, and is
+an instance of ``\Mockery\MockInterface``.
+
+.. note::
+
+ All test doubles created with Mockery are an instance of
+ ``\Mockery\MockInterface``, regardless are they a stub, mock or a spy.
+
+To create a stub or a mock object with no name, we can call the ``mock()``
+method with no parameters:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock();
+
+As we stated earlier, we don't recommend creating stub or mock objects without
+a name.
+
+Classes, abstracts, interfaces
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The recommended way to create a stub or a mock object is by using a name of
+an existing class we want to create a test double of:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+
+This stub or mock object will have the type of ``MyClass``, through inheritance.
+
+Stub or mock objects can be based on any concrete class, abstract class or even
+an interface. The primary purpose is to ensure the mock object inherits a
+specific type for type hinting.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyInterface');
+
+This stub or mock object will implement the ``MyInterface`` interface.
+
+.. note::
+
+ Classes marked final, or classes that have methods marked final cannot be
+ mocked fully. Mockery supports creating partial mocks for these cases.
+ Partial mocks will be explained later in the documentation.
+
+Mockery also supports creating stub or mock objects based on a single existing
+class, which must implement one or more interfaces. We can do this by providing
+a comma-separated list of the class and interfaces as the first argument to the
+``\Mockery::mock()`` method:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass, MyInterface, OtherInterface');
+
+This stub or mock object will now be of type ``MyClass`` and implement the
+``MyInterface`` and ``OtherInterface`` interfaces.
+
+.. note::
+
+ The class name doesn't need to be the first member of the list but it's a
+ friendly convention to use for readability.
+
+We can tell a mock to implement the desired interfaces by passing the list of
+interfaces as the second argument:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass', 'MyInterface, OtherInterface');
+
+For all intents and purposes, this is the same as the previous example.
+
+Spies
+-----
+
+The third type of test doubles Mockery supports are spies. The main difference
+between spies and mock objects is that with spies we verify the calls made
+against our test double after the calls were made. We would use a spy when we
+don't necessarily care about all of the calls that are going to be made to an
+object.
+
+A spy will return ``null`` for all method calls it receives. It is not possible
+to tell a spy what will be the return value of a method call. If we do that, then
+we would deal with a mock object, and not with a spy.
+
+We create a spy by calling the ``\Mockery::spy()`` method:
+
+.. code-block:: php
+
+ $spy = \Mockery::spy('MyClass');
+
+Just as with stubs or mocks, we can tell Mockery to base a spy on any concrete
+or abstract class, or to implement any number of interfaces:
+
+.. code-block:: php
+
+ $spy = \Mockery::spy('MyClass, MyInterface, OtherInterface');
+
+This spy will now be of type ``MyClass`` and implement the ``MyInterface`` and
+``OtherInterface`` interfaces.
+
+.. note::
+
+ The ``\Mockery::spy()`` method call is actually a shorthand for calling
+ ``\Mockery::mock()->shouldIgnoreMissing()``. The ``shouldIgnoreMissing``
+ method is a "behaviour modifier". We'll discuss them a bit later.
+
+Mocks vs. Spies
+---------------
+
+Let's try and illustrate the difference between mocks and spies with the
+following example:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $spy = \Mockery::spy('MyClass');
+
+ $mock->shouldReceive('foo')->andReturn(42);
+
+ $mockResult = $mock->foo();
+ $spyResult = $spy->foo();
+
+ $spy->shouldHaveReceived()->foo();
+
+ var_dump($mockResult); // int(42)
+ var_dump($spyResult); // null
+
+As we can see from this example, with a mock object we set the call expectations
+before the call itself, and we get the return result we expect it to return.
+With a spy object on the other hand, we verify the call has happened after the
+fact. The return result of a method call against a spy is always ``null``.
+
+We also have a dedicated chapter to :doc:`spies` only.
+
+.. _creating-test-doubles-partial-test-doubles:
+
+Partial Test Doubles
+--------------------
+
+Partial doubles are useful when we want to stub out, set expectations for, or
+spy on *some* methods of a class, but run the actual code for other methods.
+
+We differentiate between three types of partial test doubles:
+
+ * runtime partial test doubles,
+ * generated partial test doubles, and
+ * proxied partial test doubles.
+
+Runtime partial test doubles
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+What we call a runtime partial, involves creating a test double and then telling
+it to make itself partial. Any method calls that the double hasn't been told to
+allow or expect, will act as they would on a normal instance of the object.
+
+.. code-block:: php
+
+ class Foo {
+ function foo() { return 123; }
+ function bar() { return $this->foo(); }
+ }
+
+ $foo = mock(Foo::class)->makePartial();
+ $foo->foo(); // int(123);
+
+We can then tell the test double to allow or expect calls as with any other
+Mockery double.
+
+.. code-block:: php
+
+ $foo->shouldReceive('foo')->andReturn(456);
+ $foo->bar(); // int(456)
+
+See the cookbook entry on :doc:`../cookbook/big_parent_class` for an example
+usage of runtime partial test doubles.
+
+Generated partial test doubles
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The second type of partial double we can create is what we call a generated
+partial. With generated partials, we specifically tell Mockery which methods
+we want to be able to allow or expect calls to. All other methods will run the
+actual code *directly*, so stubs and expectations on these methods will not
+work.
+
+.. code-block:: php
+
+ class Foo {
+ function foo() { return 123; }
+ function bar() { return $this->foo(); }
+ }
+
+ $foo = mock("Foo[foo]");
+
+ $foo->foo(); // error, no expectation set
+
+ $foo->shouldReceive('foo')->andReturn(456);
+ $foo->foo(); // int(456)
+
+ // setting an expectation for this has no effect
+ $foo->shouldReceive('bar')->andReturn(999);
+ $foo->bar(); // int(456)
+
+.. note::
+
+ Even though we support generated partial test doubles, we do not recommend
+ using them.
+
+ One of the reasons why is because a generated partial will call the original
+ constructor of the mocked class. This can have unwanted side-effects during
+ testing application code.
+
+ See :doc:`../cookbook/not_calling_the_constructor` for more details.
+
+Proxied partial test doubles
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A proxied partial mock is a partial of last resort. We may encounter a class
+which is simply not capable of being mocked because it has been marked as
+final. Similarly, we may find a class with methods marked as final. In such a
+scenario, we cannot simply extend the class and override methods to mock - we
+need to get creative.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock(new MyClass);
+
+Yes, the new mock is a Proxy. It intercepts calls and reroutes them to the
+proxied object (which we construct and pass in) for methods which are not
+subject to any expectations. Indirectly, this allows us to mock methods
+marked final since the Proxy is not subject to those limitations. The tradeoff
+should be obvious - a proxied partial will fail any typehint checks for the
+class being mocked since it cannot extend that class.
+
+.. _creating-test-doubles-aliasing:
+
+Aliasing
+--------
+
+Prefixing the valid name of a class (which is NOT currently loaded) with
+"alias:" will generate an "alias mock". Alias mocks create a class alias with
+the given classname to stdClass and are generally used to enable the mocking
+of public static methods. Expectations set on the new mock object which refer
+to static methods will be used by all static calls to this class.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('alias:MyClass');
+
+
+.. note::
+
+ Even though aliasing classes is supported, we do not recommend it.
+
+Overloading
+-----------
+
+Prefixing the valid name of a class (which is NOT currently loaded) with
+"overload:" will generate an alias mock (as with "alias:") except that created
+new instances of that class will import any expectations set on the origin
+mock (``$mock``). The origin mock is never verified since it's used an
+expectation store for new instances. For this purpose we use the term "instance
+mock" to differentiate it from the simpler "alias mock".
+
+In other words, an instance mock will "intercept" when a new instance of the
+mocked class is created, then the mock will be used instead. This is useful
+especially when mocking hard dependencies which will be discussed later.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('overload:MyClass');
+
+.. note::
+
+ Using alias/instance mocks across more than one test will generate a fatal
+ error since we can't have two classes of the same name. To avoid this,
+ run each test of this kind in a separate PHP process (which is supported
+ out of the box by both PHPUnit and PHPT).
+
+
+.. _creating-test-doubles-named-mocks:
+
+Named Mocks
+-----------
+
+The ``namedMock()`` method will generate a class called by the first argument,
+so in this example ``MyClassName``. The rest of the arguments are treated in the
+same way as the ``mock`` method:
+
+.. code-block:: php
+
+ $mock = \Mockery::namedMock('MyClassName', 'DateTime');
+
+This example would create a class called ``MyClassName`` that extends
+``DateTime``.
+
+Named mocks are quite an edge case, but they can be useful when code depends
+on the ``__CLASS__`` magic constant, or when we need two derivatives of an
+abstract type, that are actually different classes.
+
+See the cookbook entry on :doc:`../cookbook/class_constants` for an example
+usage of named mocks.
+
+.. note::
+
+ We can only create a named mock once, any subsequent calls to
+ ``namedMock``, with different arguments are likely to cause exceptions.
+
+.. _creating-test-doubles-constructor-arguments:
+
+Constructor Arguments
+---------------------
+
+Sometimes the mocked class has required constructor arguments. We can pass these
+to Mockery as an indexed array, as the 2nd argument:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass', [$constructorArg1, $constructorArg2]);
+
+or if we need the ``MyClass`` to implement an interface as well, as the 3rd
+argument:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass', 'MyInterface', [$constructorArg1, $constructorArg2]);
+
+Mockery now knows to pass in ``$constructorArg1`` and ``$constructorArg2`` as
+arguments to the constructor.
+
+.. _creating-test-doubles-behavior-modifiers:
+
+Behavior Modifiers
+------------------
+
+When creating a mock object, we may wish to use some commonly preferred
+behaviours that are not the default in Mockery.
+
+The use of the ``shouldIgnoreMissing()`` behaviour modifier will label this
+mock object as a Passive Mock:
+
+.. code-block:: php
+
+ \Mockery::mock('MyClass')->shouldIgnoreMissing();
+
+In such a mock object, calls to methods which are not covered by expectations
+will return ``null`` instead of the usual error about there being no expectation
+matching the call.
+
+On PHP >= 7.0.0, methods with missing expectations that have a return type
+will return either a mock of the object (if return type is a class) or a
+"falsy" primitive value, e.g. empty string, empty array, zero for ints and
+floats, false for bools, or empty closures.
+
+On PHP >= 7.1.0, methods with missing expectations and nullable return type
+will return null.
+
+We can optionally prefer to return an object of type ``\Mockery\Undefined``
+(i.e. a ``null`` object) (which was the 0.7.2 behaviour) by using an
+additional modifier:
+
+.. code-block:: php
+
+ \Mockery::mock('MyClass')->shouldIgnoreMissing()->asUndefined();
+
+The returned object is nothing more than a placeholder so if, by some act of
+fate, it's erroneously used somewhere it shouldn't it will likely not pass a
+logic check.
+
+We have encountered the ``makePartial()`` method before, as it is the method we
+use to create runtime partial test doubles:
+
+.. code-block:: php
+
+ \Mockery::mock('MyClass')->makePartial();
+
+This form of mock object will defer all methods not subject to an expectation to
+the parent class of the mock, i.e. ``MyClass``. Whereas the previous
+``shouldIgnoreMissing()`` returned ``null``, this behaviour simply calls the
+parent's matching method.
diff --git a/vendor/mockery/mockery/docs/reference/demeter_chains.rst b/vendor/mockery/mockery/docs/reference/demeter_chains.rst
new file mode 100644
index 0000000..1dad5ef
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/demeter_chains.rst
@@ -0,0 +1,38 @@
+.. index::
+ single: Mocking; Demeter Chains
+
+Mocking Demeter Chains And Fluent Interfaces
+============================================
+
+Both of these terms refer to the growing practice of invoking statements
+similar to:
+
+.. code-block:: php
+
+ $object->foo()->bar()->zebra()->alpha()->selfDestruct();
+
+The long chain of method calls isn't necessarily a bad thing, assuming they
+each link back to a local object the calling class knows. As a fun example,
+Mockery's long chains (after the first ``shouldReceive()`` method) all call to
+the same instance of ``\Mockery\Expectation``. However, sometimes this is not
+the case and the chain is constantly crossing object boundaries.
+
+In either case, mocking such a chain can be a horrible task. To make it easier
+Mockery supports demeter chain mocking. Essentially, we shortcut through the
+chain and return a defined value from the final call. For example, let's
+assume ``selfDestruct()`` returns the string "Ten!" to $object (an instance of
+``CaptainsConsole``). Here's how we could mock it.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('CaptainsConsole');
+ $mock->shouldReceive('foo->bar->zebra->alpha->selfDestruct')->andReturn('Ten!');
+
+The above expectation can follow any previously seen format or expectation,
+except that the method name is simply the string of all expected chain calls
+separated by ``->``. Mockery will automatically setup the chain of expected
+calls with its final return values, regardless of whatever intermediary object
+might be used in the real implementation.
+
+Arguments to all members of the chain (except the final call) are ignored in
+this process.
diff --git a/vendor/mockery/mockery/docs/reference/expectations.rst b/vendor/mockery/mockery/docs/reference/expectations.rst
new file mode 100644
index 0000000..fb1d736
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/expectations.rst
@@ -0,0 +1,465 @@
+.. index::
+ single: Expectations
+
+Expectation Declarations
+========================
+
+.. note::
+
+ In order for our expectations to work we MUST call ``Mockery::close()``,
+ preferably in a callback method such as ``tearDown`` or ``_before``
+ (depending on whether or not we're integrating Mockery with another
+ framework). This static call cleans up the Mockery container used by the
+ current test, and run any verification tasks needed for our expectations.
+
+Once we have created a mock object, we'll often want to start defining how
+exactly it should behave (and how it should be called). This is where the
+Mockery expectation declarations take over.
+
+Declaring Method Call Expectations
+----------------------------------
+
+To tell our test double to expect a call for a method with a given name, we use
+the ``shouldReceive`` method:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method');
+
+This is the starting expectation upon which all other expectations and
+constraints are appended.
+
+We can declare more than one method call to be expected:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method_1', 'name_of_method_2');
+
+All of these will adopt any chained expectations or constraints.
+
+It is possible to declare the expectations for the method calls, along with
+their return values:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive([
+ 'name_of_method_1' => 'return value 1',
+ 'name_of_method_2' => 'return value 2',
+ ]);
+
+There's also a shorthand way of setting up method call expectations and their
+return values:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass', ['name_of_method_1' => 'return value 1', 'name_of_method_2' => 'return value 2']);
+
+All of these will adopt any additional chained expectations or constraints.
+
+We can declare that a test double should not expect a call to the given method
+name:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldNotReceive('name_of_method');
+
+This method is a convenience method for calling ``shouldReceive()->never()``.
+
+Declaring Method Argument Expectations
+--------------------------------------
+
+For every method we declare expectation for, we can add constraints that the
+defined expectations apply only to the method calls that match the expected
+argument list:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->with($arg1, $arg2, ...);
+ // or
+ $mock->shouldReceive('name_of_method')
+ ->withArgs([$arg1, $arg2, ...]);
+
+We can add a lot more flexibility to argument matching using the built in
+matcher classes (see later). For example, ``\Mockery::any()`` matches any
+argument passed to that position in the ``with()`` parameter list. Mockery also
+allows Hamcrest library matchers - for example, the Hamcrest function
+``anything()`` is equivalent to ``\Mockery::any()``.
+
+It's important to note that this means all expectations attached only apply to
+the given method when it is called with these exact arguments:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+
+ $mock->shouldReceive('foo')->with('Hello');
+
+ $mock->foo('Goodbye'); // throws a NoMatchingExpectationException
+
+This allows for setting up differing expectations based on the arguments
+provided to expected calls.
+
+Argument matching with closures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Instead of providing a built-in matcher for each argument, we can provide a
+closure that matches all passed arguments at once:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->withArgs(closure);
+
+The given closure receives all the arguments passed in the call to the expected
+method. In this way, this expectation only applies to method calls where passed
+arguments make the closure evaluate to true:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+
+ $mock->shouldReceive('foo')->withArgs(function ($arg) {
+ if ($arg % 2 == 0) {
+ return true;
+ }
+ return false;
+ });
+
+ $mock->foo(4); // matches the expectation
+ $mock->foo(3); // throws a NoMatchingExpectationException
+
+Any, or no arguments
+^^^^^^^^^^^^^^^^^^^^
+
+We can declare that the expectation matches a method call regardless of what
+arguments are passed:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->withAnyArgs();
+
+This is set by default unless otherwise specified.
+
+We can declare that the expectation matches method calls with zero arguments:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->withNoArgs();
+
+Declaring Return Value Expectations
+-----------------------------------
+
+For mock objects, we can tell Mockery what return values to return from the
+expected method calls.
+
+For that we can use the ``andReturn()`` method:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->andReturn($value);
+
+This sets a value to be returned from the expected method call.
+
+It is possible to set up expectation for multiple return values. By providing
+a sequence of return values, we tell Mockery what value to return on every
+subsequent call to the method:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->andReturn($value1, $value2, ...)
+
+The first call will return ``$value1`` and the second call will return ``$value2``.
+
+If we call the method more times than the number of return values we declared,
+Mockery will return the final value for any subsequent method call:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+
+ $mock->shouldReceive('foo')->andReturn(1, 2, 3);
+
+ $mock->foo(); // int(1)
+ $mock->foo(); // int(2)
+ $mock->foo(); // int(3)
+ $mock->foo(); // int(3)
+
+The same can be achieved using the alternative syntax:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->andReturnValues([$value1, $value2, ...])
+
+It accepts a simple array instead of a list of parameters. The order of return
+is determined by the numerical index of the given array with the last array
+member being returned on all calls once previous return values are exhausted.
+
+The following two options are primarily for communication with test readers:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->andReturnNull();
+ // or
+ $mock->shouldReceive('name_of_method')
+ ->andReturn([null]);
+
+They mark the mock object method call as returning ``null`` or nothing.
+
+Sometimes we want to calculate the return results of the method calls, based on
+the arguments passed to the method. We can do that with the ``andReturnUsing()``
+method which accepts one or more closure:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->andReturnUsing(closure, ...);
+
+Closures can be queued by passing them as extra parameters as for ``andReturn()``.
+
+.. note::
+
+ We cannot currently mix ``andReturnUsing()`` with ``andReturn()``.
+
+If we are mocking fluid interfaces, the following method will be helpful:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->andReturnSelf();
+
+It sets the return value to the mocked class name.
+
+Throwing Exceptions
+-------------------
+
+We can tell the method of mock objects to throw exceptions:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->andThrow(Exception);
+
+It will throw the given ``Exception`` object when called.
+
+Rather than an object, we can pass in the ``Exception`` class and message to
+use when throwing an ``Exception`` from the mocked method:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->andThrow(exception_name, message);
+
+.. _expectations-setting-public-properties:
+
+Setting Public Properties
+-------------------------
+
+Used with an expectation so that when a matching method is called, we can cause
+a mock object's public property to be set to a specified value, by using
+``andSet()`` or ``set()``:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->andSet($property, $value);
+ // or
+ $mock->shouldReceive('name_of_method')
+ ->set($property, $value);
+
+In cases where we want to call the real method of the class that was mocked and
+return its result, the ``passthru()`` method tells the expectation to bypass
+a return queue:
+
+.. code-block:: php
+
+ passthru()
+
+It allows expectation matching and call count validation to be applied against
+real methods while still calling the real class method with the expected
+arguments.
+
+Declaring Call Count Expectations
+---------------------------------
+
+Besides setting expectations on the arguments of the method calls, and the
+return values of those same calls, we can set expectations on how many times
+should any method be called.
+
+When a call count expectation is not met, a
+``\Mockery\Expectation\InvalidCountException`` will be thrown.
+
+.. note::
+
+ It is absolutely required to call ``\Mockery::close()`` at the end of our
+ tests, for example in the ``tearDown()`` method of PHPUnit. Otherwise
+ Mockery will not verify the calls made against our mock objects.
+
+We can declare that the expected method may be called zero or more times:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->zeroOrMoreTimes();
+
+This is the default for all methods unless otherwise set.
+
+To tell Mockery to expect an exact number of calls to a method, we can use the
+following:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->times($n);
+
+where ``$n`` is the number of times the method should be called.
+
+A couple of most common cases got their shorthand methods.
+
+To declare that the expected method must be called one time only:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->once();
+
+To declare that the expected method must be called two times:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->twice();
+
+To declare that the expected method must never be called:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->never();
+
+Call count modifiers
+^^^^^^^^^^^^^^^^^^^^
+
+The call count expectations can have modifiers set.
+
+If we want to tell Mockery the minimum number of times a method should be called,
+we use ``atLeast()``:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->atLeast()
+ ->times(3);
+
+``atLeast()->times(3)`` means the call must be called at least three times
+(given matching method args) but never less than three times.
+
+Similarly, we can tell Mockery the maximum number of times a method should be
+called, using ``atMost()``:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->atMost()
+ ->times(3);
+
+``atMost()->times(3)`` means the call must be called no more than three times.
+If the method gets no calls at all, the expectation will still be met.
+
+We can also set a range of call counts, using ``between()``:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass');
+ $mock->shouldReceive('name_of_method')
+ ->between($min, $max);
+
+This is actually identical to using ``atLeast()->times($min)->atMost()->times($max)``
+but is provided as a shorthand. It may be followed by a ``times()`` call with no
+parameter to preserve the APIs natural language readability.
+
+Expectation Declaration Utilities
+---------------------------------
+
+Declares that this method is expected to be called in a specific order in
+relation to similarly marked methods.
+
+.. code-block:: php
+
+ ordered()
+
+The order is dictated by the order in which this modifier is actually used when
+setting up mocks.
+
+Declares the method as belonging to an order group (which can be named or
+numbered). Methods within a group can be called in any order, but the ordered
+calls from outside the group are ordered in relation to the group:
+
+.. code-block:: php
+
+ ordered(group)
+
+We can set up so that method1 is called before group1 which is in turn called
+before method2.
+
+When called prior to ``ordered()`` or ``ordered(group)``, it declares this
+ordering to apply across all mock objects (not just the current mock):
+
+.. code-block:: php
+
+ globally()
+
+This allows for dictating order expectations across multiple mocks.
+
+The ``byDefault()`` marks an expectation as a default. Default expectations are
+applied unless a non-default expectation is created:
+
+.. code-block:: php
+
+ byDefault()
+
+These later expectations immediately replace the previously defined default.
+This is useful so we can setup default mocks in our unit test ``setup()`` and
+later tweak them in specific tests as needed.
+
+Returns the current mock object from an expectation chain:
+
+.. code-block:: php
+
+ getMock()
+
+Useful where we prefer to keep mock setups as a single statement, e.g.:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('foo')->shouldReceive('foo')->andReturn(1)->getMock();
diff --git a/vendor/mockery/mockery/docs/reference/final_methods_classes.rst b/vendor/mockery/mockery/docs/reference/final_methods_classes.rst
new file mode 100644
index 0000000..3b2c443
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/final_methods_classes.rst
@@ -0,0 +1,28 @@
+.. index::
+ single: Mocking; Final Classes/Methods
+
+Dealing with Final Classes/Methods
+==================================
+
+One of the primary restrictions of mock objects in PHP, is that mocking
+classes or methods marked final is hard. The final keyword prevents methods so
+marked from being replaced in subclasses (subclassing is how mock objects can
+inherit the type of the class or object being mocked).
+
+The simplest solution is to not mark classes or methods as final!
+
+However, in a compromise between mocking functionality and type safety,
+Mockery does allow creating "proxy mocks" from classes marked final, or from
+classes with methods marked final. This offers all the usual mock object
+goodness but the resulting mock will not inherit the class type of the object
+being mocked, i.e. it will not pass any instanceof comparison. Methods marked
+as final will be proxied to the original method, i.e., final methods can't be
+mocked.
+
+We can create a proxy mock by passing the instantiated object we wish to
+mock into ``\Mockery::mock()``, i.e. Mockery will then generate a Proxy to the
+real object and selectively intercept method calls for the purposes of setting
+and meeting expectations.
+
+See the :ref:`creating-test-doubles-partial-test-doubles` chapter, the subsection
+about proxied partial test doubles.
diff --git a/vendor/mockery/mockery/docs/reference/index.rst b/vendor/mockery/mockery/docs/reference/index.rst
new file mode 100644
index 0000000..1e5bf04
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/index.rst
@@ -0,0 +1,22 @@
+Reference
+=========
+
+.. toctree::
+ :hidden:
+
+ creating_test_doubles
+ expectations
+ argument_validation
+ alternative_should_receive_syntax
+ spies
+ partial_mocks
+ protected_methods
+ public_properties
+ public_static_properties
+ pass_by_reference_behaviours
+ demeter_chains
+ final_methods_classes
+ magic_methods
+ phpunit_integration
+
+.. include:: map.rst.inc
diff --git a/vendor/mockery/mockery/docs/reference/instance_mocking.rst b/vendor/mockery/mockery/docs/reference/instance_mocking.rst
new file mode 100644
index 0000000..9d1aa28
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/instance_mocking.rst
@@ -0,0 +1,22 @@
+.. index::
+ single: Mocking; Instance
+
+Instance Mocking
+================
+
+Instance mocking means that a statement like:
+
+.. code-block:: php
+
+ $obj = new \MyNamespace\Foo;
+
+...will actually generate a mock object. This is done by replacing the real
+class with an instance mock (similar to an alias mock), as with mocking public
+methods. The alias will import its expectations from the original mock of
+that type (note that the original is never verified and should be ignored
+after its expectations are setup). This lets you intercept instantiation where
+you can't simply inject a replacement object.
+
+As before, this does not prevent a require statement from including the real
+class and triggering a fatal PHP error. It's intended for use where
+autoloading is the primary class loading mechanism.
diff --git a/vendor/mockery/mockery/docs/reference/magic_methods.rst b/vendor/mockery/mockery/docs/reference/magic_methods.rst
new file mode 100644
index 0000000..39591cf
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/magic_methods.rst
@@ -0,0 +1,16 @@
+.. index::
+ single: Mocking; Magic Methods
+
+PHP Magic Methods
+=================
+
+PHP magic methods which are prefixed with a double underscore, e.g.
+``__set()``, pose a particular problem in mocking and unit testing in general.
+It is strongly recommended that unit tests and mock objects do not directly
+refer to magic methods. Instead, refer only to the virtual methods and
+properties these magic methods simulate.
+
+Following this piece of advice will ensure we are testing the real API of
+classes and also ensures there is no conflict should Mockery override these
+magic methods, which it will inevitably do in order to support its role in
+intercepting method calls and properties.
diff --git a/vendor/mockery/mockery/docs/reference/map.rst.inc b/vendor/mockery/mockery/docs/reference/map.rst.inc
new file mode 100644
index 0000000..883bc3c
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/map.rst.inc
@@ -0,0 +1,14 @@
+* :doc:`/reference/creating_test_doubles`
+* :doc:`/reference/expectations`
+* :doc:`/reference/argument_validation`
+* :doc:`/reference/alternative_should_receive_syntax`
+* :doc:`/reference/spies`
+* :doc:`/reference/partial_mocks`
+* :doc:`/reference/protected_methods`
+* :doc:`/reference/public_properties`
+* :doc:`/reference/public_static_properties`
+* :doc:`/reference/pass_by_reference_behaviours`
+* :doc:`/reference/demeter_chains`
+* :doc:`/reference/final_methods_classes`
+* :doc:`/reference/magic_methods`
+* :doc:`/reference/phpunit_integration`
diff --git a/vendor/mockery/mockery/docs/reference/partial_mocks.rst b/vendor/mockery/mockery/docs/reference/partial_mocks.rst
new file mode 100644
index 0000000..457eb8d
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/partial_mocks.rst
@@ -0,0 +1,108 @@
+.. index::
+ single: Mocking; Partial Mocks
+
+Creating Partial Mocks
+======================
+
+Partial mocks are useful when we only need to mock several methods of an
+object leaving the remainder free to respond to calls normally (i.e. as
+implemented). Mockery implements three distinct strategies for creating
+partials. Each has specific advantages and disadvantages so which strategy we
+use will depend on our own preferences and the source code in need of
+mocking.
+
+We have previously talked a bit about :ref:`creating-test-doubles-partial-test-doubles`,
+but we'd like to expand on the subject a bit here.
+
+#. Runtime partial test doubles
+#. Generated partial test doubles
+#. Proxied Partial Mock
+
+Runtime partial test doubles
+----------------------------
+
+A runtime partial test double, also known as a passive partial mock, is a kind
+of a default state of being for a mocked object.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass')->makePartial();
+
+With a runtime partial, we assume that all methods will simply defer to the
+parent class (``MyClass``) original methods unless a method call matches a
+known expectation. If we have no matching expectation for a specific method
+call, that call is deferred to the class being mocked. Since the division
+between mocked and unmocked calls depends entirely on the expectations we
+define, there is no need to define which methods to mock in advance.
+
+See the cookbook entry on :doc:`../cookbook/big_parent_class` for an example
+usage of runtime partial test doubles.
+
+Generated Partial Test Doubles
+------------------------------
+
+A generated partial test double, also known as a traditional partial mock,
+defines ahead of time which methods of a class are to be mocked and which are
+to be left unmocked (i.e. callable as normal). The syntax for creating
+traditional mocks is:
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyClass[foo,bar]');
+
+In the above example, the ``foo()`` and ``bar()`` methods of MyClass will be
+mocked but no other MyClass methods are touched. We will need to define
+expectations for the ``foo()`` and ``bar()`` methods to dictate their mocked
+behaviour.
+
+Don't forget that we can pass in constructor arguments since unmocked methods
+may rely on those!
+
+.. code-block:: php
+
+ $mock = \Mockery::mock('MyNamespace\MyClass[foo]', array($arg1, $arg2));
+
+See the :ref:`creating-test-doubles-constructor-arguments` section to read up
+on them.
+
+.. note::
+
+ Even though we support generated partial test doubles, we do not recommend
+ using them.
+
+Proxied Partial Mock
+--------------------
+
+A proxied partial mock is a partial of last resort. We may encounter a class
+which is simply not capable of being mocked because it has been marked as
+final. Similarly, we may find a class with methods marked as final. In such a
+scenario, we cannot simply extend the class and override methods to mock - we
+need to get creative.
+
+.. code-block:: php
+
+ $mock = \Mockery::mock(new MyClass);
+
+Yes, the new mock is a Proxy. It intercepts calls and reroutes them to the
+proxied object (which we construct and pass in) for methods which are not
+subject to any expectations. Indirectly, this allows us to mock methods
+marked final since the Proxy is not subject to those limitations. The tradeoff
+should be obvious - a proxied partial will fail any typehint checks for the
+class being mocked since it cannot extend that class.
+
+Special Internal Cases
+----------------------
+
+All mock objects, with the exception of Proxied Partials, allows us to make
+any expectation call to the underlying real class method using the ``passthru()``
+expectation call. This will return values from the real call and bypass any
+mocked return queue (which can simply be omitted obviously).
+
+There is a fourth kind of partial mock reserved for internal use. This is
+automatically generated when we attempt to mock a class containing methods
+marked final. Since we cannot override such methods, they are simply left
+unmocked. Typically, we don't need to worry about this but if we really
+really must mock a final method, the only possible means is through a Proxied
+Partial Mock. SplFileInfo, for example, is a common class subject to this form
+of automatic internal partial since it contains public final methods used
+internally.
diff --git a/vendor/mockery/mockery/docs/reference/pass_by_reference_behaviours.rst b/vendor/mockery/mockery/docs/reference/pass_by_reference_behaviours.rst
new file mode 100644
index 0000000..5e2e457
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/pass_by_reference_behaviours.rst
@@ -0,0 +1,130 @@
+.. index::
+ single: Pass-By-Reference Method Parameter Behaviour
+
+Preserving Pass-By-Reference Method Parameter Behaviour
+=======================================================
+
+PHP Class method may accept parameters by reference. In this case, changes
+made to the parameter (a reference to the original variable passed to the
+method) are reflected in the original variable. An example:
+
+.. code-block:: php
+
+ class Foo
+ {
+
+ public function bar(&$a)
+ {
+ $a++;
+ }
+
+ }
+
+ $baz = 1;
+ $foo = new Foo;
+ $foo->bar($baz);
+
+ echo $baz; // will echo the integer 2
+
+In the example above, the variable ``$baz`` is passed by reference to
+``Foo::bar()`` (notice the ``&`` symbol in front of the parameter?). Any
+change ``bar()`` makes to the parameter reference is reflected in the original
+variable, ``$baz``.
+
+Mockery handles references correctly for all methods where it can analyse
+the parameter (using ``Reflection``) to see if it is passed by reference. To
+mock how a reference is manipulated by the class method, we can use a closure
+argument matcher to manipulate it, i.e. ``\Mockery::on()`` - see the
+:ref:`argument-validation-complex-argument-validation` chapter.
+
+There is an exception for internal PHP classes where Mockery cannot analyse
+method parameters using ``Reflection`` (a limitation in PHP). To work around
+this, we can explicitly declare method parameters for an internal class using
+``\Mockery\Configuration::setInternalClassMethodParamMap()``.
+
+Here's an example using ``MongoCollection::insert()``. ``MongoCollection`` is
+an internal class offered by the mongo extension from PECL. Its ``insert()``
+method accepts an array of data as the first parameter, and an optional
+options array as the second parameter. The original data array is updated
+(i.e. when a ``insert()`` pass-by-reference parameter) to include a new
+``_id`` field. We can mock this behaviour using a configured parameter map (to
+tell Mockery to expect a pass by reference parameter) and a ``Closure``
+attached to the expected method parameter to be updated.
+
+Here's a PHPUnit unit test verifying that this pass-by-reference behaviour is
+preserved:
+
+.. code-block:: php
+
+ public function testCanOverrideExpectedParametersOfInternalPHPClassesToPreserveRefs()
+ {
+ \Mockery::getConfiguration()->setInternalClassMethodParamMap(
+ 'MongoCollection',
+ 'insert',
+ array('&$data', '$options = array()')
+ );
+ $m = \Mockery::mock('MongoCollection');
+ $m->shouldReceive('insert')->with(
+ \Mockery::on(function(&$data) {
+ if (!is_array($data)) return false;
+ $data['_id'] = 123;
+ return true;
+ }),
+ \Mockery::any()
+ );
+
+ $data = array('a'=>1,'b'=>2);
+ $m->insert($data);
+
+ $this->assertTrue(isset($data['_id']));
+ $this->assertEquals(123, $data['_id']);
+
+ \Mockery::resetContainer();
+ }
+
+Protected Methods
+-----------------
+
+When dealing with protected methods, and trying to preserve pass by reference
+behavior for them, a different approach is required.
+
+.. code-block:: php
+
+ class Model
+ {
+ public function test(&$data)
+ {
+ return $this->doTest($data);
+ }
+
+ protected function doTest(&$data)
+ {
+ $data['something'] = 'wrong';
+ return $this;
+ }
+ }
+
+ class Test extends \PHPUnit\Framework\TestCase
+ {
+ public function testModel()
+ {
+ $mock = \Mockery::mock('Model[test]')->shouldAllowMockingProtectedMethods();
+
+ $mock->shouldReceive('test')
+ ->with(\Mockery::on(function(&$data) {
+ $data['something'] = 'wrong';
+ return true;
+ }));
+
+ $data = array('foo' => 'bar');
+
+ $mock->test($data);
+ $this->assertTrue(isset($data['something']));
+ $this->assertEquals('wrong', $data['something']);
+ }
+ }
+
+This is quite an edge case, so we need to change the original code a little bit,
+by creating a public method that will call our protected method, and then mock
+that, instead of the protected method. This new public method will act as a
+proxy to our protected method.
diff --git a/vendor/mockery/mockery/docs/reference/phpunit_integration.rst b/vendor/mockery/mockery/docs/reference/phpunit_integration.rst
new file mode 100644
index 0000000..7528b5a
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/phpunit_integration.rst
@@ -0,0 +1,151 @@
+.. index::
+ single: PHPUnit Integration
+
+PHPUnit Integration
+===================
+
+Mockery was designed as a simple-to-use *standalone* mock object framework, so
+its need for integration with any testing framework is entirely optional. To
+integrate Mockery, we need to define a ``tearDown()`` method for our tests
+containing the following (we may use a shorter ``\Mockery`` namespace
+alias):
+
+.. code-block:: php
+
+ public function tearDown() {
+ \Mockery::close();
+ }
+
+This static call cleans up the Mockery container used by the current test, and
+run any verification tasks needed for our expectations.
+
+For some added brevity when it comes to using Mockery, we can also explicitly
+use the Mockery namespace with a shorter alias. For example:
+
+.. code-block:: php
+
+ use \Mockery as m;
+
+ class SimpleTest extends \PHPUnit\Framework\TestCase
+ {
+ public function testSimpleMock() {
+ $mock = m::mock('simplemock');
+ $mock->shouldReceive('foo')->with(5, m::any())->once()->andReturn(10);
+
+ $this->assertEquals(10, $mock->foo(5));
+ }
+
+ public function tearDown() {
+ m::close();
+ }
+ }
+
+Mockery ships with an autoloader so we don't need to litter our tests with
+``require_once()`` calls. To use it, ensure Mockery is on our
+``include_path`` and add the following to our test suite's ``Bootstrap.php``
+or ``TestHelper.php`` file:
+
+.. code-block:: php
+
+ require_once 'Mockery/Loader.php';
+ require_once 'Hamcrest/Hamcrest.php';
+
+ $loader = new \Mockery\Loader;
+ $loader->register();
+
+If we are using Composer, we can simplify this to including the Composer
+generated autoloader file:
+
+.. code-block:: php
+
+ require __DIR__ . '/../vendor/autoload.php'; // assuming vendor is one directory up
+
+.. caution::
+
+ Prior to Hamcrest 1.0.0, the ``Hamcrest.php`` file name had a small "h"
+ (i.e. ``hamcrest.php``). If upgrading Hamcrest to 1.0.0 remember to check
+ the file name is updated for all your projects.)
+
+To integrate Mockery into PHPUnit and avoid having to call the close method
+and have Mockery remove itself from code coverage reports, have your test case
+extends the ``\Mockery\Adapter\Phpunit\MockeryTestCase``:
+
+.. code-block:: php
+
+ class MyTest extends \Mockery\Adapter\Phpunit\MockeryTestCase
+ {
+
+ }
+
+An alternative is to use the supplied trait:
+
+.. code-block:: php
+
+ class MyTest extends \PHPUnit\Framework\TestCase
+ {
+ use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
+ }
+
+Extending ``MockeryTestCase`` or using the ``MockeryPHPUnitIntegration``
+trait is **the recommended way** of integrating Mockery with PHPUnit,
+since Mockery 1.0.0.
+
+PHPUnit listener
+----------------
+
+Before the 1.0.0 release, Mockery provided a PHPUnit listener that would
+call ``Mockery::close()`` for us at the end of a test. This has changed
+significantly since the 1.0.0 version.
+
+Now, Mockery provides a PHPUnit listener that makes tests fail if
+``Mockery::close()`` has not been called. It can help identify tests where
+we've forgotten to include the trait or extend the ``MockeryTestCase``.
+
+If we are using PHPUnit's XML configuration approach, we can include the
+following to load the ``TestListener``:
+
+.. code-block:: xml
+
+
+
+
+
+Make sure Composer's or Mockery's autoloader is present in the bootstrap file
+or we will need to also define a "file" attribute pointing to the file of the
+``TestListener`` class.
+
+.. caution::
+
+ The ``TestListener`` will only work for PHPUnit 6+ versions.
+
+ For PHPUnit versions 5 and lower, the test listener does not work.
+
+If we are creating the test suite programmatically we may add the listener
+like this:
+
+.. code-block:: php
+
+ // Create the suite.
+ $suite = new PHPUnit\Framework\TestSuite();
+
+ // Create the listener and add it to the suite.
+ $result = new PHPUnit\Framework\TestResult();
+ $result->addListener(new \Mockery\Adapter\Phpunit\TestListener());
+
+ // Run the tests.
+ $suite->run($result);
+
+.. caution::
+
+ PHPUnit provides a functionality that allows
+ `tests to run in a separated process `_,
+ to ensure better isolation. Mockery verifies the mocks expectations using the
+ ``Mockery::close()`` method, and provides a PHPUnit listener, that automatically
+ calls this method for us after every test.
+
+ However, this listener is not called in the right process when using
+ PHPUnit's process isolation, resulting in expectations that might not be
+ respected, but without raising any ``Mockery\Exception``. To avoid this,
+ we cannot rely on the supplied Mockery PHPUnit ``TestListener``, and we need
+ to explicitly call ``Mockery::close``. The easiest solution to include this
+ call in the ``tearDown()`` method, as explained previously.
diff --git a/vendor/mockery/mockery/docs/reference/protected_methods.rst b/vendor/mockery/mockery/docs/reference/protected_methods.rst
new file mode 100644
index 0000000..ec4a5ba
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/protected_methods.rst
@@ -0,0 +1,26 @@
+.. index::
+ single: Mocking; Protected Methods
+
+Mocking Protected Methods
+=========================
+
+By default, Mockery does not allow mocking protected methods. We do not recommend
+mocking protected methods, but there are cases when there is no other solution.
+
+For those cases we have the ``shouldAllowMockingProtectedMethods()`` method. It
+instructs Mockery to specifically allow mocking of protected methods, for that
+one class only:
+
+.. code-block:: php
+
+ class MyClass
+ {
+ protected function foo()
+ {
+ }
+ }
+
+ $mock = \Mockery::mock('MyClass')
+ ->shouldAllowMockingProtectedMethods();
+ $mock->shouldReceive('foo');
+
diff --git a/vendor/mockery/mockery/docs/reference/public_properties.rst b/vendor/mockery/mockery/docs/reference/public_properties.rst
new file mode 100644
index 0000000..3165668
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/public_properties.rst
@@ -0,0 +1,20 @@
+.. index::
+ single: Mocking; Public Properties
+
+Mocking Public Properties
+=========================
+
+Mockery allows us to mock properties in several ways. One way is that we can set
+a public property and its value on any mock object. The second is that we can
+use the expectation methods ``set()`` and ``andSet()`` to set property values if
+that expectation is ever met.
+
+You can read more about :ref:`expectations-setting-public-properties`.
+
+.. note::
+
+ In general, Mockery does not support mocking any magic methods since these
+ are generally not considered a public API (and besides it is a bit difficult
+ to differentiate them when you badly need them for mocking!). So please mock
+ virtual properties (those relying on ``__get()`` and ``__set()``) as if they
+ were actually declared on the class.
diff --git a/vendor/mockery/mockery/docs/reference/public_static_properties.rst b/vendor/mockery/mockery/docs/reference/public_static_properties.rst
new file mode 100644
index 0000000..2396efc
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/public_static_properties.rst
@@ -0,0 +1,15 @@
+.. index::
+ single: Mocking; Public Static Methods
+
+Mocking Public Static Methods
+=============================
+
+Static methods are not called on real objects, so normal mock objects can't
+mock them. Mockery supports class aliased mocks, mocks representing a class
+name which would normally be loaded (via autoloading or a require statement)
+in the system under test. These aliases block that loading (unless via a
+require statement - so please use autoloading!) and allow Mockery to intercept
+static method calls and add expectations for them.
+
+See the :ref:`creating-test-doubles-aliasing` section for more information on
+creating aliased mocks, for the purpose of mocking public static methods.
diff --git a/vendor/mockery/mockery/docs/reference/spies.rst b/vendor/mockery/mockery/docs/reference/spies.rst
new file mode 100644
index 0000000..77f37f3
--- /dev/null
+++ b/vendor/mockery/mockery/docs/reference/spies.rst
@@ -0,0 +1,154 @@
+.. index::
+ single: Reference; Spies
+
+Spies
+=====
+
+Spies are a type of test doubles, but they differ from stubs or mocks in that,
+that the spies record any interaction between the spy and the System Under Test
+(SUT), and allow us to make assertions against those interactions after the fact.
+
+Creating a spy means we don't have to set up expectations for every method call
+the double might receive during the test, some of which may not be relevant to
+the current test. A spy allows us to make assertions about the calls we care
+about for this test only, reducing the chances of over-specification and making
+our tests more clear.
+
+Spies also allow us to follow the more familiar Arrange-Act-Assert or
+Given-When-Then style within our tests. With mocks, we have to follow a less
+familiar style, something along the lines of Arrange-Expect-Act-Assert, where
+we have to tell our mocks what to expect before we act on the sut, then assert
+that those expectations where met:
+
+.. code-block:: php
+
+ // arrange
+ $mock = \Mockery::mock('MyDependency');
+ $sut = new MyClass($mock);
+
+ // expect
+ $mock->shouldReceive('foo')
+ ->once()
+ ->with('bar');
+
+ // act
+ $sut->callFoo();
+
+ // assert
+ \Mockery::close();
+
+Spies allow us to skip the expect part and move the assertion to after we have
+acted on the SUT, usually making our tests more readable:
+
+.. code-block:: php
+
+ // arrange
+ $spy = \Mockery::spy('MyDependency');
+ $sut = new MyClass($spy);
+
+ // act
+ $sut->callFoo();
+
+ // assert
+ $spy->shouldHaveReceived()
+ ->foo()
+ ->with('bar');
+
+On the other hand, spies are far less restrictive than mocks, meaning tests are
+usually less precise, as they let us get away with more. This is usually a
+good thing, they should only be as precise as they need to be, but while spies
+make our tests more intent-revealing, they do tend to reveal less about the
+design of the SUT. If we're having to setup lots of expectations for a mock,
+in lots of different tests, our tests are trying to tell us something - the SUT
+is doing too much and probably should be refactored. We don't get this with
+spies, they simply ignore the calls that aren't relevant to them.
+
+Another downside to using spies is debugging. When a mock receives a call that
+it wasn't expecting, it immediately throws an exception (failing fast), giving
+us a nice stack trace or possibly even invoking our debugger. With spies, we're
+simply asserting calls were made after the fact, so if the wrong calls were made,
+we don't have quite the same just in time context we have with the mocks.
+
+Finally, if we need to define a return value for our test double, we can't do
+that with a spy, only with a mock object.
+
+.. note::
+
+ This documentation page is an adaption of the blog post titled
+ `"Mockery Spies" `_,
+ published by Dave Marshall on his blog. Dave is the original author of spies
+ in Mockery.
+
+Spies Reference
+---------------
+
+To verify that a method was called on a spy, we use the ``shouldHaveReceived()``
+method:
+
+.. code-block:: php
+
+ $spy->shouldHaveReceived('foo');
+
+To verify that a method was **not** called on a spy, we use the
+``shouldNotHaveReceived()`` method:
+
+.. code-block:: php
+
+ $spy->shouldNotHaveReceived('foo');
+
+We can also do argument matching with spies:
+
+.. code-block:: php
+
+ $spy->shouldHaveReceived('foo')
+ ->with('bar');
+
+Argument matching is also possible by passing in an array of arguments to
+match:
+
+.. code-block:: php
+
+ $spy->shouldHaveReceived('foo', ['bar']);
+
+Although when verifying a method was not called, the argument matching can only
+be done by supplying the array of arguments as the 2nd argument to the
+``shouldNotHaveReceived()`` method:
+
+.. code-block:: php
+
+ $spy->shouldNotHaveReceived('foo', ['bar']);
+
+This is due to Mockery's internals.
+
+Finally, when expecting calls that should have been received, we can also verify
+the number of calls:
+
+.. code-block:: php
+
+ $spy->shouldHaveReceived('foo')
+ ->with('bar')
+ ->twice();
+
+Alternative shouldReceive syntax
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As of Mockery 1.0.0, we support calling methods as we would call any PHP method,
+and not as string arguments to Mockery ``should*`` methods.
+
+In cases of spies, this only applies to the ``shouldHaveReceived()`` method:
+
+.. code-block:: php
+
+ $spy->shouldHaveReceived()
+ ->foo('bar');
+
+We can set expectation on number of calls as well:
+
+.. code-block:: php
+
+ $spy->shouldHaveReceived()
+ ->foo('bar')
+ ->twice();
+
+Unfortunately, due to limitations we can't support the same syntax for the
+``shouldNotHaveReceived()`` method.
diff --git a/vendor/mockery/mockery/library/Mockery.php b/vendor/mockery/mockery/library/Mockery.php
new file mode 100644
index 0000000..8725f91
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery.php
@@ -0,0 +1,950 @@
+= 0) {
+ $builtInTypes[] = 'object';
+ }
+
+ return $builtInTypes;
+ }
+
+ /**
+ * @param string $type
+ * @return bool
+ */
+ public static function isBuiltInType($type)
+ {
+ return in_array($type, \Mockery::builtInTypes());
+ }
+
+ /**
+ * Static shortcut to \Mockery\Container::mock().
+ *
+ * @param array ...$args
+ *
+ * @return \Mockery\MockInterface
+ */
+ public static function mock(...$args)
+ {
+ return call_user_func_array(array(self::getContainer(), 'mock'), $args);
+ }
+
+ /**
+ * Static and semantic shortcut for getting a mock from the container
+ * and applying the spy's expected behavior into it.
+ *
+ * @param array ...$args
+ *
+ * @return \Mockery\MockInterface
+ */
+ public static function spy(...$args)
+ {
+ if (count($args) && $args[0] instanceof \Closure) {
+ $args[0] = new ClosureWrapper($args[0]);
+ }
+
+ return call_user_func_array(array(self::getContainer(), 'mock'), $args)->shouldIgnoreMissing();
+ }
+
+ /**
+ * Static and Semantic shortcut to \Mockery\Container::mock().
+ *
+ * @param array ...$args
+ *
+ * @return \Mockery\MockInterface
+ */
+ public static function instanceMock(...$args)
+ {
+ return call_user_func_array(array(self::getContainer(), 'mock'), $args);
+ }
+
+ /**
+ * Static shortcut to \Mockery\Container::mock(), first argument names the mock.
+ *
+ * @param array ...$args
+ *
+ * @return \Mockery\MockInterface
+ */
+ public static function namedMock(...$args)
+ {
+ $name = array_shift($args);
+
+ $builder = new MockConfigurationBuilder();
+ $builder->setName($name);
+
+ array_unshift($args, $builder);
+
+ return call_user_func_array(array(self::getContainer(), 'mock'), $args);
+ }
+
+ /**
+ * Static shortcut to \Mockery\Container::self().
+ *
+ * @throws LogicException
+ *
+ * @return \Mockery\MockInterface
+ */
+ public static function self()
+ {
+ if (is_null(self::$_container)) {
+ throw new \LogicException('You have not declared any mocks yet');
+ }
+
+ return self::$_container->self();
+ }
+
+ /**
+ * Static shortcut to closing up and verifying all mocks in the global
+ * container, and resetting the container static variable to null.
+ *
+ * @return void
+ */
+ public static function close()
+ {
+ foreach (self::$_filesToCleanUp as $fileName) {
+ @unlink($fileName);
+ }
+ self::$_filesToCleanUp = [];
+
+ if (is_null(self::$_container)) {
+ return;
+ }
+
+ $container = self::$_container;
+ self::$_container = null;
+
+ $container->mockery_teardown();
+ $container->mockery_close();
+ }
+
+ /**
+ * Static fetching of a mock associated with a name or explicit class poser.
+ *
+ * @param string $name
+ *
+ * @return \Mockery\Mock
+ */
+ public static function fetchMock($name)
+ {
+ return self::$_container->fetchMock($name);
+ }
+
+ /**
+ * Lazy loader and getter for
+ * the container property.
+ *
+ * @return Mockery\Container
+ */
+ public static function getContainer()
+ {
+ if (is_null(self::$_container)) {
+ self::$_container = new Mockery\Container(self::getGenerator(), self::getLoader());
+ }
+
+ return self::$_container;
+ }
+
+ /**
+ * Setter for the $_generator static propery.
+ *
+ * @param \Mockery\Generator\Generator $generator
+ */
+ public static function setGenerator(Generator $generator)
+ {
+ self::$_generator = $generator;
+ }
+
+ /**
+ * Lazy loader method and getter for
+ * the generator property.
+ *
+ * @return Generator
+ */
+ public static function getGenerator()
+ {
+ if (is_null(self::$_generator)) {
+ self::$_generator = self::getDefaultGenerator();
+ }
+
+ return self::$_generator;
+ }
+
+ /**
+ * Creates and returns a default generator
+ * used inside this class.
+ *
+ * @return CachingGenerator
+ */
+ public static function getDefaultGenerator()
+ {
+ return new CachingGenerator(StringManipulationGenerator::withDefaultPasses());
+ }
+
+ /**
+ * Setter for the $_loader static property.
+ *
+ * @param Loader $loader
+ */
+ public static function setLoader(Loader $loader)
+ {
+ self::$_loader = $loader;
+ }
+
+ /**
+ * Lazy loader method and getter for
+ * the $_loader property.
+ *
+ * @return Loader
+ */
+ public static function getLoader()
+ {
+ if (is_null(self::$_loader)) {
+ self::$_loader = self::getDefaultLoader();
+ }
+
+ return self::$_loader;
+ }
+
+ /**
+ * Gets an EvalLoader to be used as default.
+ *
+ * @return EvalLoader
+ */
+ public static function getDefaultLoader()
+ {
+ return new EvalLoader();
+ }
+
+ /**
+ * Set the container.
+ *
+ * @param \Mockery\Container $container
+ *
+ * @return \Mockery\Container
+ */
+ public static function setContainer(Mockery\Container $container)
+ {
+ return self::$_container = $container;
+ }
+
+ /**
+ * Reset the container to null.
+ *
+ * @return void
+ */
+ public static function resetContainer()
+ {
+ self::$_container = null;
+ }
+
+ /**
+ * Return instance of ANY matcher.
+ *
+ * @return \Mockery\Matcher\Any
+ */
+ public static function any()
+ {
+ return new \Mockery\Matcher\Any();
+ }
+
+ /**
+ * Return instance of AndAnyOtherArgs matcher.
+ *
+ * An alternative name to `andAnyOtherArgs` so
+ * the API stays closer to `any` as well.
+ *
+ * @return \Mockery\Matcher\AndAnyOtherArgs
+ */
+ public static function andAnyOthers()
+ {
+ return new \Mockery\Matcher\AndAnyOtherArgs();
+ }
+
+ /**
+ * Return instance of AndAnyOtherArgs matcher.
+ *
+ * @return \Mockery\Matcher\AndAnyOtherArgs
+ */
+ public static function andAnyOtherArgs()
+ {
+ return new \Mockery\Matcher\AndAnyOtherArgs();
+ }
+
+ /**
+ * Return instance of TYPE matcher.
+ *
+ * @param mixed $expected
+ *
+ * @return \Mockery\Matcher\Type
+ */
+ public static function type($expected)
+ {
+ return new \Mockery\Matcher\Type($expected);
+ }
+
+ /**
+ * Return instance of DUCKTYPE matcher.
+ *
+ * @param array ...$args
+ *
+ * @return \Mockery\Matcher\Ducktype
+ */
+ public static function ducktype(...$args)
+ {
+ return new \Mockery\Matcher\Ducktype($args);
+ }
+
+ /**
+ * Return instance of SUBSET matcher.
+ *
+ * @param array $part
+ * @param bool $strict - (Optional) True for strict comparison, false for loose
+ *
+ * @return \Mockery\Matcher\Subset
+ */
+ public static function subset(array $part, $strict = true)
+ {
+ return new \Mockery\Matcher\Subset($part, $strict);
+ }
+
+ /**
+ * Return instance of CONTAINS matcher.
+ *
+ * @param array ...$args
+ *
+ * @return \Mockery\Matcher\Contains
+ */
+ public static function contains(...$args)
+ {
+ return new \Mockery\Matcher\Contains($args);
+ }
+
+ /**
+ * Return instance of HASKEY matcher.
+ *
+ * @param mixed $key
+ *
+ * @return \Mockery\Matcher\HasKey
+ */
+ public static function hasKey($key)
+ {
+ return new \Mockery\Matcher\HasKey($key);
+ }
+
+ /**
+ * Return instance of HASVALUE matcher.
+ *
+ * @param mixed $val
+ *
+ * @return \Mockery\Matcher\HasValue
+ */
+ public static function hasValue($val)
+ {
+ return new \Mockery\Matcher\HasValue($val);
+ }
+
+ /**
+ * Return instance of CLOSURE matcher.
+ *
+ * @param mixed $closure
+ *
+ * @return \Mockery\Matcher\Closure
+ */
+ public static function on($closure)
+ {
+ return new \Mockery\Matcher\Closure($closure);
+ }
+
+ /**
+ * Return instance of MUSTBE matcher.
+ *
+ * @param mixed $expected
+ *
+ * @return \Mockery\Matcher\MustBe
+ */
+ public static function mustBe($expected)
+ {
+ return new \Mockery\Matcher\MustBe($expected);
+ }
+
+ /**
+ * Return instance of NOT matcher.
+ *
+ * @param mixed $expected
+ *
+ * @return \Mockery\Matcher\Not
+ */
+ public static function not($expected)
+ {
+ return new \Mockery\Matcher\Not($expected);
+ }
+
+ /**
+ * Return instance of ANYOF matcher.
+ *
+ * @param array ...$args
+ *
+ * @return \Mockery\Matcher\AnyOf
+ */
+ public static function anyOf(...$args)
+ {
+ return new \Mockery\Matcher\AnyOf($args);
+ }
+
+ /**
+ * Return instance of NOTANYOF matcher.
+ *
+ * @param array ...$args
+ *
+ * @return \Mockery\Matcher\NotAnyOf
+ */
+ public static function notAnyOf(...$args)
+ {
+ return new \Mockery\Matcher\NotAnyOf($args);
+ }
+
+ /**
+ * Return instance of PATTERN matcher.
+ *
+ * @param mixed $expected
+ *
+ * @return \Mockery\Matcher\Pattern
+ */
+ public static function pattern($expected)
+ {
+ return new \Mockery\Matcher\Pattern($expected);
+ }
+
+ /**
+ * Lazy loader and Getter for the global
+ * configuration container.
+ *
+ * @return \Mockery\Configuration
+ */
+ public static function getConfiguration()
+ {
+ if (is_null(self::$_config)) {
+ self::$_config = new \Mockery\Configuration();
+ }
+
+ return self::$_config;
+ }
+
+ /**
+ * Utility method to format method name and arguments into a string.
+ *
+ * @param string $method
+ * @param array $arguments
+ *
+ * @return string
+ */
+ public static function formatArgs($method, array $arguments = null)
+ {
+ if (is_null($arguments)) {
+ return $method . '()';
+ }
+
+ $formattedArguments = array();
+ foreach ($arguments as $argument) {
+ $formattedArguments[] = self::formatArgument($argument);
+ }
+
+ return $method . '(' . implode(', ', $formattedArguments) . ')';
+ }
+
+ /**
+ * Gets the string representation
+ * of any passed argument.
+ *
+ * @param mixed $argument
+ * @param int $depth
+ *
+ * @return mixed
+ */
+ private static function formatArgument($argument, $depth = 0)
+ {
+ if ($argument instanceof MatcherAbstract) {
+ return (string) $argument;
+ }
+
+ if (is_object($argument)) {
+ return 'object(' . get_class($argument) . ')';
+ }
+
+ if (is_int($argument) || is_float($argument)) {
+ return $argument;
+ }
+
+ if (is_array($argument)) {
+ if ($depth === 1) {
+ $argument = '[...]';
+ } else {
+ $sample = array();
+ foreach ($argument as $key => $value) {
+ $key = is_int($key) ? $key : "'$key'";
+ $value = self::formatArgument($value, $depth + 1);
+ $sample[] = "$key => $value";
+ }
+
+ $argument = "[".implode(", ", $sample)."]";
+ }
+
+ return ((strlen($argument) > 1000) ? substr($argument, 0, 1000).'...]' : $argument);
+ }
+
+ if (is_bool($argument)) {
+ return $argument ? 'true' : 'false';
+ }
+
+ if (is_resource($argument)) {
+ return 'resource(...)';
+ }
+
+ if (is_null($argument)) {
+ return 'NULL';
+ }
+
+ return "'".(string) $argument."'";
+ }
+
+ /**
+ * Utility function to format objects to printable arrays.
+ *
+ * @param array $objects
+ *
+ * @return string
+ */
+ public static function formatObjects(array $objects = null)
+ {
+ static $formatting;
+
+ if ($formatting) {
+ return '[Recursion]';
+ }
+
+ if (is_null($objects)) {
+ return '';
+ }
+
+ $objects = array_filter($objects, 'is_object');
+ if (empty($objects)) {
+ return '';
+ }
+
+ $formatting = true;
+ $parts = array();
+
+ foreach ($objects as $object) {
+ $parts[get_class($object)] = self::objectToArray($object);
+ }
+
+ $formatting = false;
+
+ return 'Objects: ( ' . var_export($parts, true) . ')';
+ }
+
+ /**
+ * Utility function to turn public properties and public get* and is* method values into an array.
+ *
+ * @param object $object
+ * @param int $nesting
+ *
+ * @return array
+ */
+ private static function objectToArray($object, $nesting = 3)
+ {
+ if ($nesting == 0) {
+ return array('...');
+ }
+
+ return array(
+ 'class' => get_class($object),
+ 'properties' => self::extractInstancePublicProperties($object, $nesting)
+ );
+ }
+
+ /**
+ * Returns all public instance properties.
+ *
+ * @param mixed $object
+ * @param int $nesting
+ *
+ * @return array
+ */
+ private static function extractInstancePublicProperties($object, $nesting)
+ {
+ $reflection = new \ReflectionClass(get_class($object));
+ $properties = $reflection->getProperties(\ReflectionProperty::IS_PUBLIC);
+ $cleanedProperties = array();
+
+ foreach ($properties as $publicProperty) {
+ if (!$publicProperty->isStatic()) {
+ $name = $publicProperty->getName();
+ $cleanedProperties[$name] = self::cleanupNesting($object->$name, $nesting);
+ }
+ }
+
+ return $cleanedProperties;
+ }
+
+ /**
+ * Utility method used for recursively generating
+ * an object or array representation.
+ *
+ * @param mixed $argument
+ * @param int $nesting
+ *
+ * @return mixed
+ */
+ private static function cleanupNesting($argument, $nesting)
+ {
+ if (is_object($argument)) {
+ $object = self::objectToArray($argument, $nesting - 1);
+ $object['class'] = get_class($argument);
+
+ return $object;
+ }
+
+ if (is_array($argument)) {
+ return self::cleanupArray($argument, $nesting - 1);
+ }
+
+ return $argument;
+ }
+
+ /**
+ * Utility method for recursively
+ * gerating a representation
+ * of the given array.
+ *
+ * @param array $argument
+ * @param int $nesting
+ *
+ * @return mixed
+ */
+ private static function cleanupArray($argument, $nesting = 3)
+ {
+ if ($nesting == 0) {
+ return '...';
+ }
+
+ foreach ($argument as $key => $value) {
+ if (is_array($value)) {
+ $argument[$key] = self::cleanupArray($value, $nesting - 1);
+ } elseif (is_object($value)) {
+ $argument[$key] = self::objectToArray($value, $nesting - 1);
+ }
+ }
+
+ return $argument;
+ }
+
+ /**
+ * Utility function to parse shouldReceive() arguments and generate
+ * expectations from such as needed.
+ *
+ * @param Mockery\MockInterface $mock
+ * @param array ...$args
+ * @param callable $add
+ * @return \Mockery\CompositeExpectation
+ */
+ public static function parseShouldReturnArgs(\Mockery\MockInterface $mock, $args, $add)
+ {
+ $composite = new \Mockery\CompositeExpectation();
+
+ foreach ($args as $arg) {
+ if (is_array($arg)) {
+ foreach ($arg as $k => $v) {
+ $expectation = self::buildDemeterChain($mock, $k, $add)->andReturn($v);
+ $composite->add($expectation);
+ }
+ } elseif (is_string($arg)) {
+ $expectation = self::buildDemeterChain($mock, $arg, $add);
+ $composite->add($expectation);
+ }
+ }
+
+ return $composite;
+ }
+
+ /**
+ * Sets up expectations on the members of the CompositeExpectation and
+ * builds up any demeter chain that was passed to shouldReceive.
+ *
+ * @param \Mockery\MockInterface $mock
+ * @param string $arg
+ * @param callable $add
+ * @throws Mockery\Exception
+ * @return \Mockery\ExpectationInterface
+ */
+ protected static function buildDemeterChain(\Mockery\MockInterface $mock, $arg, $add)
+ {
+ /** @var Mockery\Container $container */
+ $container = $mock->mockery_getContainer();
+ $methodNames = explode('->', $arg);
+ reset($methodNames);
+
+ if (!\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed()
+ && !$mock->mockery_isAnonymous()
+ && !in_array(current($methodNames), $mock->mockery_getMockableMethods())
+ ) {
+ throw new \Mockery\Exception(
+ 'Mockery\'s configuration currently forbids mocking the method '
+ . current($methodNames) . ' as it does not exist on the class or object '
+ . 'being mocked'
+ );
+ }
+
+ /** @var ExpectationInterface|null $expectations */
+ $expectations = null;
+
+ /** @var Callable $nextExp */
+ $nextExp = function ($method) use ($add) {
+ return $add($method);
+ };
+
+ $parent = get_class($mock);
+
+ while (true) {
+ $method = array_shift($methodNames);
+ $expectations = $mock->mockery_getExpectationsFor($method);
+
+ if (is_null($expectations) || self::noMoreElementsInChain($methodNames)) {
+ $expectations = $nextExp($method);
+ if (self::noMoreElementsInChain($methodNames)) {
+ break;
+ }
+
+ $mock = self::getNewDemeterMock($container, $parent, $method, $expectations);
+ } else {
+ $demeterMockKey = $container->getKeyOfDemeterMockFor($method, $parent);
+ if ($demeterMockKey) {
+ $mock = self::getExistingDemeterMock($container, $demeterMockKey);
+ }
+ }
+
+ $parent .= '->' . $method;
+
+ $nextExp = function ($n) use ($mock) {
+ return $mock->shouldReceive($n);
+ };
+ }
+
+ return $expectations;
+ }
+
+ /**
+ * Gets a new demeter configured
+ * mock from the container.
+ *
+ * @param \Mockery\Container $container
+ * @param string $parent
+ * @param string $method
+ * @param Mockery\ExpectationInterface $exp
+ *
+ * @return \Mockery\Mock
+ */
+ private static function getNewDemeterMock(
+ Mockery\Container $container,
+ $parent,
+ $method,
+ Mockery\ExpectationInterface $exp
+ ) {
+ $newMockName = 'demeter_' . md5($parent) . '_' . $method;
+
+ if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
+ $parRef = null;
+ $parRefMethod = null;
+ $parRefMethodRetType = null;
+
+ $parentMock = $exp->getMock();
+ if ($parentMock !== null) {
+ $parRef = new ReflectionObject($parentMock);
+ }
+
+ if ($parRef !== null && $parRef->hasMethod($method)) {
+ $parRefMethod = $parRef->getMethod($method);
+ $parRefMethodRetType = $parRefMethod->getReturnType();
+
+ if ($parRefMethodRetType !== null) {
+ $mock = self::namedMock($newMockName, (string) $parRefMethodRetType);
+ $exp->andReturn($mock);
+
+ return $mock;
+ }
+ }
+ }
+
+ $mock = $container->mock($newMockName);
+ $exp->andReturn($mock);
+
+ return $mock;
+ }
+
+ /**
+ * Gets an specific demeter mock from
+ * the ones kept by the container.
+ *
+ * @param \Mockery\Container $container
+ * @param string $demeterMockKey
+ *
+ * @return mixed
+ */
+ private static function getExistingDemeterMock(
+ Mockery\Container $container,
+ $demeterMockKey
+ ) {
+ $mocks = $container->getMocks();
+ $mock = $mocks[$demeterMockKey];
+
+ return $mock;
+ }
+
+ /**
+ * Checks if the passed array representing a demeter
+ * chain with the method names is empty.
+ *
+ * @param array $methodNames
+ *
+ * @return bool
+ */
+ private static function noMoreElementsInChain(array $methodNames)
+ {
+ return empty($methodNames);
+ }
+
+ public static function declareClass($fqn)
+ {
+ return static::declareType($fqn, "class");
+ }
+
+ public static function declareInterface($fqn)
+ {
+ return static::declareType($fqn, "interface");
+ }
+
+ private static function declareType($fqn, $type)
+ {
+ $targetCode = "trait = new TestListenerTrait();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function endTest(\PHPUnit_Framework_Test $test, $time)
+ {
+ $this->trait->endTest($test, $time);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function startTestSuite(\PHPUnit_Framework_TestSuite $suite)
+ {
+ $this->trait->startTestSuite();
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/Legacy/TestListenerForV6.php b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/Legacy/TestListenerForV6.php
new file mode 100644
index 0000000..815b13c
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/Legacy/TestListenerForV6.php
@@ -0,0 +1,51 @@
+trait = new TestListenerTrait();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function endTest(Test $test, $time)
+ {
+ $this->trait->endTest($test, $time);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function startTestSuite(TestSuite $suite)
+ {
+ $this->trait->startTestSuite();
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/Legacy/TestListenerForV7.php b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/Legacy/TestListenerForV7.php
new file mode 100644
index 0000000..d590825
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/Legacy/TestListenerForV7.php
@@ -0,0 +1,55 @@
+trait = new TestListenerTrait();
+ }
+
+
+ /**
+ * {@inheritdoc}
+ */
+ public function endTest(Test $test, float $time): void
+ {
+ $this->trait->endTest($test, $time);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function startTestSuite(TestSuite $suite): void
+ {
+ $this->trait->startTestSuite();
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/Legacy/TestListenerTrait.php b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/Legacy/TestListenerTrait.php
new file mode 100644
index 0000000..08848b8
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/Legacy/TestListenerTrait.php
@@ -0,0 +1,90 @@
+getStatus() !== BaseTestRunner::STATUS_PASSED) {
+ // If the test didn't pass there is no guarantee that
+ // verifyMockObjects and assertPostConditions have been called.
+ // And even if it did, the point here is to prevent false
+ // negatives, not to make failing tests fail for more reasons.
+ return;
+ }
+
+ try {
+ // The self() call is used as a sentinel. Anything that throws if
+ // the container is closed already will do.
+ \Mockery::self();
+ } catch (\LogicException $_) {
+ return;
+ }
+
+ $e = new ExpectationFailedException(
+ \sprintf(
+ "Mockery's expectations have not been verified. Make sure that \Mockery::close() is called at the end of the test. Consider using %s\MockeryPHPUnitIntegration or extending %s\MockeryTestCase.",
+ __NAMESPACE__,
+ __NAMESPACE__
+ )
+ );
+
+ /** @var \PHPUnit\Framework\TestResult $result */
+ $result = $test->getTestResultObject();
+
+ if ($result !== null) {
+ $result->addFailure($test, $e, $time);
+ }
+ }
+
+ public function startTestSuite()
+ {
+ Blacklist::$blacklistedClassNames[\Mockery::class] = 1;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryPHPUnitIntegration.php b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryPHPUnitIntegration.php
new file mode 100644
index 0000000..9d34293
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryPHPUnitIntegration.php
@@ -0,0 +1,88 @@
+addMockeryExpectationsToAssertionCount();
+ $this->checkMockeryExceptions();
+ $this->closeMockery();
+
+ parent::assertPostConditions();
+ }
+
+ protected function addMockeryExpectationsToAssertionCount()
+ {
+ $this->addToAssertionCount(Mockery::getContainer()->mockery_getExpectationCount());
+ }
+
+ protected function checkMockeryExceptions()
+ {
+ if (!method_exists($this, "markAsRisky")) {
+ return;
+ }
+
+ foreach (Mockery::getContainer()->mockery_thrownExceptions() as $e) {
+ if (!$e->dismissed()) {
+ $this->markAsRisky();
+ }
+ }
+ }
+
+ protected function closeMockery()
+ {
+ Mockery::close();
+ $this->mockeryOpen = false;
+ }
+
+ /**
+ * @before
+ */
+ protected function startMockery()
+ {
+ $this->mockeryOpen = true;
+ }
+
+ /**
+ * @after
+ */
+ protected function purgeMockeryContainer()
+ {
+ if ($this->mockeryOpen) {
+ // post conditions wasn't called, so test probably failed
+ Mockery::close();
+ }
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryTestCase.php b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryTestCase.php
new file mode 100644
index 0000000..f4e9a86
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Adapter/Phpunit/MockeryTestCase.php
@@ -0,0 +1,26 @@
+closure = $closure;
+ }
+
+ public function __invoke()
+ {
+ return call_user_func_array($this->closure, func_get_args());
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/CompositeExpectation.php b/vendor/mockery/mockery/library/Mockery/CompositeExpectation.php
new file mode 100644
index 0000000..86e3904
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/CompositeExpectation.php
@@ -0,0 +1,154 @@
+_expectations[] = $expectation;
+ }
+
+ /**
+ * @param mixed ...$args
+ */
+ public function andReturn(...$args)
+ {
+ return $this->__call(__FUNCTION__, $args);
+ }
+
+ /**
+ * Set a return value, or sequential queue of return values
+ *
+ * @param mixed ...$args
+ * @return self
+ */
+ public function andReturns(...$args)
+ {
+ return call_user_func_array([$this, 'andReturn'], $args);
+ }
+
+ /**
+ * Intercept any expectation calls and direct against all expectations
+ *
+ * @param string $method
+ * @param array $args
+ * @return self
+ */
+ public function __call($method, array $args)
+ {
+ foreach ($this->_expectations as $expectation) {
+ call_user_func_array(array($expectation, $method), $args);
+ }
+ return $this;
+ }
+
+ /**
+ * Return order number of the first expectation
+ *
+ * @return int
+ */
+ public function getOrderNumber()
+ {
+ reset($this->_expectations);
+ $first = current($this->_expectations);
+ return $first->getOrderNumber();
+ }
+
+ /**
+ * Return the parent mock of the first expectation
+ *
+ * @return \Mockery\MockInterface
+ */
+ public function getMock()
+ {
+ reset($this->_expectations);
+ $first = current($this->_expectations);
+ return $first->getMock();
+ }
+
+ /**
+ * Mockery API alias to getMock
+ *
+ * @return \Mockery\MockInterface
+ */
+ public function mock()
+ {
+ return $this->getMock();
+ }
+
+ /**
+ * Starts a new expectation addition on the first mock which is the primary
+ * target outside of a demeter chain
+ *
+ * @param mixed ...$args
+ * @return \Mockery\Expectation
+ */
+ public function shouldReceive(...$args)
+ {
+ reset($this->_expectations);
+ $first = current($this->_expectations);
+ return call_user_func_array(array($first->getMock(), 'shouldReceive'), $args);
+ }
+
+ /**
+ * Starts a new expectation addition on the first mock which is the primary
+ * target outside of a demeter chain
+ *
+ * @param mixed ...$args
+ * @return \Mockery\Expectation
+ */
+ public function shouldNotReceive(...$args)
+ {
+ reset($this->_expectations);
+ $first = current($this->_expectations);
+ return call_user_func_array(array($first->getMock(), 'shouldNotReceive'), $args);
+ }
+
+ /**
+ * Return the string summary of this composite expectation
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $return = '[';
+ $parts = array();
+ foreach ($this->_expectations as $exp) {
+ $parts[] = (string) $exp;
+ }
+ $return .= implode(', ', $parts) . ']';
+ return $return;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Configuration.php b/vendor/mockery/mockery/library/Mockery/Configuration.php
new file mode 100644
index 0000000..eaf7ffe
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Configuration.php
@@ -0,0 +1,190 @@
+_allowMockingNonExistentMethod = (bool) $flag;
+ }
+
+ /**
+ * Return flag indicating whether mocking non-existent methods allowed
+ *
+ * @return bool
+ */
+ public function mockingNonExistentMethodsAllowed()
+ {
+ return $this->_allowMockingNonExistentMethod;
+ }
+
+ /**
+ * @deprecated
+ *
+ * Set boolean to allow/prevent unnecessary mocking of methods
+ *
+ * @param bool $flag
+ */
+ public function allowMockingMethodsUnnecessarily($flag = true)
+ {
+ trigger_error(sprintf("The %s method is deprecated and will be removed in a future version of Mockery", __METHOD__), E_USER_DEPRECATED);
+
+ $this->_allowMockingMethodsUnnecessarily = (bool) $flag;
+ }
+
+ /**
+ * Return flag indicating whether mocking non-existent methods allowed
+ *
+ * @return bool
+ */
+ public function mockingMethodsUnnecessarilyAllowed()
+ {
+ trigger_error(sprintf("The %s method is deprecated and will be removed in a future version of Mockery", __METHOD__), E_USER_DEPRECATED);
+
+ return $this->_allowMockingMethodsUnnecessarily;
+ }
+
+ /**
+ * Set a parameter map (array of param signature strings) for the method
+ * of an internal PHP class.
+ *
+ * @param string $class
+ * @param string $method
+ * @param array $map
+ */
+ public function setInternalClassMethodParamMap($class, $method, array $map)
+ {
+ if (!isset($this->_internalClassParamMap[strtolower($class)])) {
+ $this->_internalClassParamMap[strtolower($class)] = array();
+ }
+ $this->_internalClassParamMap[strtolower($class)][strtolower($method)] = $map;
+ }
+
+ /**
+ * Remove all overriden parameter maps from internal PHP classes.
+ */
+ public function resetInternalClassMethodParamMaps()
+ {
+ $this->_internalClassParamMap = array();
+ }
+
+ /**
+ * Get the parameter map of an internal PHP class method
+ *
+ * @return array
+ */
+ public function getInternalClassMethodParamMap($class, $method)
+ {
+ if (isset($this->_internalClassParamMap[strtolower($class)][strtolower($method)])) {
+ return $this->_internalClassParamMap[strtolower($class)][strtolower($method)];
+ }
+ }
+
+ public function getInternalClassMethodParamMaps()
+ {
+ return $this->_internalClassParamMap;
+ }
+
+ public function setConstantsMap(array $map)
+ {
+ $this->_constantsMap = $map;
+ }
+
+ public function getConstantsMap()
+ {
+ return $this->_constantsMap;
+ }
+
+ /**
+ * Disable reflection caching
+ *
+ * It should be always enabled, except when using
+ * PHPUnit's --static-backup option.
+ *
+ * @see https://github.com/mockery/mockery/issues/268
+ */
+ public function disableReflectionCache()
+ {
+ $this->_reflectionCacheEnabled = false;
+ }
+
+ /**
+ * Enable reflection caching
+ *
+ * It should be always enabled, except when using
+ * PHPUnit's --static-backup option.
+ *
+ * @see https://github.com/mockery/mockery/issues/268
+ */
+ public function enableReflectionCache()
+ {
+ $this->_reflectionCacheEnabled = true;
+ }
+
+ /**
+ * Is reflection cache enabled?
+ */
+ public function reflectionCacheEnabled()
+ {
+ return $this->_reflectionCacheEnabled;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Container.php b/vendor/mockery/mockery/library/Mockery/Container.php
new file mode 100644
index 0000000..5287ac4
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Container.php
@@ -0,0 +1,539 @@
+_generator = $generator ?: \Mockery::getDefaultGenerator();
+ $this->_loader = $loader ?: \Mockery::getDefaultLoader();
+ }
+
+ /**
+ * Generates a new mock object for this container
+ *
+ * I apologies in advance for this. A God Method just fits the API which
+ * doesn't require differentiating between classes, interfaces, abstracts,
+ * names or partials - just so long as it's something that can be mocked.
+ * I'll refactor it one day so it's easier to follow.
+ *
+ * @param array ...$args
+ *
+ * @return Mock
+ * @throws Exception\RuntimeException
+ */
+ public function mock(...$args)
+ {
+ $expectationClosure = null;
+ $quickdefs = array();
+ $constructorArgs = null;
+ $blocks = array();
+ $class = null;
+
+ if (count($args) > 1) {
+ $finalArg = end($args);
+ reset($args);
+ if (is_callable($finalArg) && is_object($finalArg)) {
+ $expectationClosure = array_pop($args);
+ }
+ }
+
+ $builder = new MockConfigurationBuilder();
+
+ foreach ($args as $k => $arg) {
+ if ($arg instanceof MockConfigurationBuilder) {
+ $builder = $arg;
+ unset($args[$k]);
+ }
+ }
+ reset($args);
+
+ $builder->setParameterOverrides(\Mockery::getConfiguration()->getInternalClassMethodParamMaps());
+ $builder->setConstantsMap(\Mockery::getConfiguration()->getConstantsMap());
+
+ while (count($args) > 0) {
+ $arg = current($args);
+ // check for multiple interfaces
+ if (is_string($arg) && strpos($arg, ',') && !strpos($arg, ']')) {
+ $interfaces = explode(',', str_replace(' ', '', $arg));
+ $builder->addTargets($interfaces);
+ array_shift($args);
+
+ continue;
+ } elseif (is_string($arg) && substr($arg, 0, 6) == 'alias:') {
+ $name = array_shift($args);
+ $name = str_replace('alias:', '', $name);
+ $builder->addTarget('stdClass');
+ $builder->setName($name);
+ continue;
+ } elseif (is_string($arg) && substr($arg, 0, 9) == 'overload:') {
+ $name = array_shift($args);
+ $name = str_replace('overload:', '', $name);
+ $builder->setInstanceMock(true);
+ $builder->addTarget('stdClass');
+ $builder->setName($name);
+ continue;
+ } elseif (is_string($arg) && substr($arg, strlen($arg)-1, 1) == ']') {
+ $parts = explode('[', $arg);
+ if (!class_exists($parts[0], true) && !interface_exists($parts[0], true)) {
+ throw new \Mockery\Exception('Can only create a partial mock from'
+ . ' an existing class or interface');
+ }
+ $class = $parts[0];
+ $parts[1] = str_replace(' ', '', $parts[1]);
+ $partialMethods = explode(',', strtolower(rtrim($parts[1], ']')));
+ $builder->addTarget($class);
+ $builder->setWhiteListedMethods($partialMethods);
+ array_shift($args);
+ continue;
+ } elseif (is_string($arg) && (class_exists($arg, true) || interface_exists($arg, true) || trait_exists($arg, true))) {
+ $class = array_shift($args);
+ $builder->addTarget($class);
+ continue;
+ } elseif (is_string($arg) && !\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed() && (!class_exists($arg, true) && !interface_exists($arg, true))) {
+ throw new \Mockery\Exception("Mockery can't find '$arg' so can't mock it");
+ } elseif (is_string($arg)) {
+ if (!$this->isValidClassName($arg)) {
+ throw new \Mockery\Exception('Class name contains invalid characters');
+ }
+ $class = array_shift($args);
+ $builder->addTarget($class);
+ continue;
+ } elseif (is_object($arg)) {
+ $partial = array_shift($args);
+ $builder->addTarget($partial);
+ continue;
+ } elseif (is_array($arg) && !empty($arg) && array_keys($arg) !== range(0, count($arg) - 1)) {
+ // if associative array
+ if (array_key_exists(self::BLOCKS, $arg)) {
+ $blocks = $arg[self::BLOCKS];
+ }
+ unset($arg[self::BLOCKS]);
+ $quickdefs = array_shift($args);
+ continue;
+ } elseif (is_array($arg)) {
+ $constructorArgs = array_shift($args);
+ continue;
+ }
+
+ throw new \Mockery\Exception(
+ 'Unable to parse arguments sent to '
+ . get_class($this) . '::mock()'
+ );
+ }
+
+ $builder->addBlackListedMethods($blocks);
+
+ if (defined('HHVM_VERSION')
+ && ($class === 'Exception' || is_subclass_of($class, 'Exception'))) {
+ $builder->addBlackListedMethod("setTraceOptions");
+ $builder->addBlackListedMethod("getTraceOptions");
+ }
+
+ if (!is_null($constructorArgs)) {
+ $builder->addBlackListedMethod("__construct"); // we need to pass through
+ } else {
+ $builder->setMockOriginalDestructor(true);
+ }
+
+ if (!empty($partialMethods) && $constructorArgs === null) {
+ $constructorArgs = array();
+ }
+
+ $config = $builder->getMockConfiguration();
+
+ $this->checkForNamedMockClashes($config);
+
+ $def = $this->getGenerator()->generate($config);
+
+ if (class_exists($def->getClassName(), $attemptAutoload = false)) {
+ $rfc = new \ReflectionClass($def->getClassName());
+ if (!$rfc->implementsInterface("Mockery\MockInterface")) {
+ throw new \Mockery\Exception\RuntimeException("Could not load mock {$def->getClassName()}, class already exists");
+ }
+ }
+
+ $this->getLoader()->load($def);
+
+ $mock = $this->_getInstance($def->getClassName(), $constructorArgs);
+ $mock->mockery_init($this, $config->getTargetObject());
+
+ if (!empty($quickdefs)) {
+ $mock->shouldReceive($quickdefs)->byDefault();
+ }
+ if (!empty($expectationClosure)) {
+ $expectationClosure($mock);
+ }
+ $this->rememberMock($mock);
+ return $mock;
+ }
+
+ public function instanceMock()
+ {
+ }
+
+ public function getLoader()
+ {
+ return $this->_loader;
+ }
+
+ public function getGenerator()
+ {
+ return $this->_generator;
+ }
+
+ /**
+ * @param string $method
+ * @param string $parent
+ * @return string|null
+ */
+ public function getKeyOfDemeterMockFor($method, $parent)
+ {
+ $keys = array_keys($this->_mocks);
+ $match = preg_grep("/__demeter_" . md5($parent) . "_{$method}$/", $keys);
+ if (count($match) == 1) {
+ $res = array_values($match);
+ if (count($res) > 0) {
+ return $res[0];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return array
+ */
+ public function getMocks()
+ {
+ return $this->_mocks;
+ }
+
+ /**
+ * Tear down tasks for this container
+ *
+ * @throws \Exception
+ * @return void
+ */
+ public function mockery_teardown()
+ {
+ try {
+ $this->mockery_verify();
+ } catch (\Exception $e) {
+ $this->mockery_close();
+ throw $e;
+ }
+ }
+
+ /**
+ * Verify the container mocks
+ *
+ * @return void
+ */
+ public function mockery_verify()
+ {
+ foreach ($this->_mocks as $mock) {
+ $mock->mockery_verify();
+ }
+ }
+
+ /**
+ * Retrieves all exceptions thrown by mocks
+ *
+ * @return array
+ */
+ public function mockery_thrownExceptions()
+ {
+ $e = [];
+
+ foreach ($this->_mocks as $mock) {
+ $e = array_merge($e, $mock->mockery_thrownExceptions());
+ }
+
+ return $e;
+ }
+
+ /**
+ * Reset the container to its original state
+ *
+ * @return void
+ */
+ public function mockery_close()
+ {
+ foreach ($this->_mocks as $mock) {
+ $mock->mockery_teardown();
+ }
+ $this->_mocks = array();
+ }
+
+ /**
+ * Fetch the next available allocation order number
+ *
+ * @return int
+ */
+ public function mockery_allocateOrder()
+ {
+ $this->_allocatedOrder += 1;
+ return $this->_allocatedOrder;
+ }
+
+ /**
+ * Set ordering for a group
+ *
+ * @param mixed $group
+ * @param int $order
+ */
+ public function mockery_setGroup($group, $order)
+ {
+ $this->_groups[$group] = $order;
+ }
+
+ /**
+ * Fetch array of ordered groups
+ *
+ * @return array
+ */
+ public function mockery_getGroups()
+ {
+ return $this->_groups;
+ }
+
+ /**
+ * Set current ordered number
+ *
+ * @param int $order
+ * @return int The current order number that was set
+ */
+ public function mockery_setCurrentOrder($order)
+ {
+ $this->_currentOrder = $order;
+ return $this->_currentOrder;
+ }
+
+ /**
+ * Get current ordered number
+ *
+ * @return int
+ */
+ public function mockery_getCurrentOrder()
+ {
+ return $this->_currentOrder;
+ }
+
+ /**
+ * Validate the current mock's ordering
+ *
+ * @param string $method
+ * @param int $order
+ * @throws \Mockery\Exception
+ * @return void
+ */
+ public function mockery_validateOrder($method, $order, \Mockery\MockInterface $mock)
+ {
+ if ($order < $this->_currentOrder) {
+ $exception = new \Mockery\Exception\InvalidOrderException(
+ 'Method ' . $method . ' called out of order: expected order '
+ . $order . ', was ' . $this->_currentOrder
+ );
+ $exception->setMock($mock)
+ ->setMethodName($method)
+ ->setExpectedOrder($order)
+ ->setActualOrder($this->_currentOrder);
+ throw $exception;
+ }
+ $this->mockery_setCurrentOrder($order);
+ }
+
+ /**
+ * Gets the count of expectations on the mocks
+ *
+ * @return int
+ */
+ public function mockery_getExpectationCount()
+ {
+ $count = 0;
+ foreach ($this->_mocks as $mock) {
+ $count += $mock->mockery_getExpectationCount();
+ }
+ return $count;
+ }
+
+ /**
+ * Store a mock and set its container reference
+ *
+ * @param \Mockery\Mock $mock
+ * @return \Mockery\MockInterface
+ */
+ public function rememberMock(\Mockery\MockInterface $mock)
+ {
+ if (!isset($this->_mocks[get_class($mock)])) {
+ $this->_mocks[get_class($mock)] = $mock;
+ } else {
+ /**
+ * This condition triggers for an instance mock where origin mock
+ * is already remembered
+ */
+ $this->_mocks[] = $mock;
+ }
+ return $mock;
+ }
+
+ /**
+ * Retrieve the last remembered mock object, which is the same as saying
+ * retrieve the current mock being programmed where you have yet to call
+ * mock() to change it - thus why the method name is "self" since it will be
+ * be used during the programming of the same mock.
+ *
+ * @return \Mockery\Mock
+ */
+ public function self()
+ {
+ $mocks = array_values($this->_mocks);
+ $index = count($mocks) - 1;
+ return $mocks[$index];
+ }
+
+ /**
+ * Return a specific remembered mock according to the array index it
+ * was stored to in this container instance
+ *
+ * @return \Mockery\Mock
+ */
+ public function fetchMock($reference)
+ {
+ if (isset($this->_mocks[$reference])) {
+ return $this->_mocks[$reference];
+ }
+ }
+
+ protected function _getInstance($mockName, $constructorArgs = null)
+ {
+ if ($constructorArgs !== null) {
+ $r = new \ReflectionClass($mockName);
+ return $r->newInstanceArgs($constructorArgs);
+ }
+
+ try {
+ $instantiator = new Instantiator;
+ $instance = $instantiator->instantiate($mockName);
+ } catch (\Exception $ex) {
+ $internalMockName = $mockName . '_Internal';
+
+ if (!class_exists($internalMockName)) {
+ eval("class $internalMockName extends $mockName {" .
+ 'public function __construct() {}' .
+ '}');
+ }
+
+ $instance = new $internalMockName();
+ }
+
+ return $instance;
+ }
+
+ protected function checkForNamedMockClashes($config)
+ {
+ $name = $config->getName();
+
+ if (!$name) {
+ return;
+ }
+
+ $hash = $config->getHash();
+
+ if (isset($this->_namedMocks[$name])) {
+ if ($hash !== $this->_namedMocks[$name]) {
+ throw new \Mockery\Exception(
+ "The mock named '$name' has been already defined with a different mock configuration"
+ );
+ }
+ }
+
+ $this->_namedMocks[$name] = $hash;
+ }
+
+ /**
+ * see http://php.net/manual/en/language.oop5.basic.php
+ * @param string $className
+ * @return bool
+ */
+ public function isValidClassName($className)
+ {
+ $pos = strpos($className, '\\');
+ if ($pos === 0) {
+ $className = substr($className, 1); // remove the first backslash
+ }
+ // all the namespaces and class name should match the regex
+ $invalidNames = array_filter(explode('\\', $className), function ($name) {
+ return !preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $name);
+ });
+ return empty($invalidNames);
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/CountValidator/AtLeast.php b/vendor/mockery/mockery/library/Mockery/CountValidator/AtLeast.php
new file mode 100644
index 0000000..f6ac130
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/CountValidator/AtLeast.php
@@ -0,0 +1,62 @@
+_limit > $n) {
+ $exception = new Mockery\Exception\InvalidCountException(
+ 'Method ' . (string) $this->_expectation
+ . ' from ' . $this->_expectation->getMock()->mockery_getName()
+ . ' should be called' . PHP_EOL
+ . ' at least ' . $this->_limit . ' times but called ' . $n
+ . ' times.'
+ );
+ $exception->setMock($this->_expectation->getMock())
+ ->setMethodName((string) $this->_expectation)
+ ->setExpectedCountComparative('>=')
+ ->setExpectedCount($this->_limit)
+ ->setActualCount($n);
+ throw $exception;
+ }
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/CountValidator/AtMost.php b/vendor/mockery/mockery/library/Mockery/CountValidator/AtMost.php
new file mode 100644
index 0000000..4d23e28
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/CountValidator/AtMost.php
@@ -0,0 +1,51 @@
+_limit < $n) {
+ $exception = new Mockery\Exception\InvalidCountException(
+ 'Method ' . (string) $this->_expectation
+ . ' from ' . $this->_expectation->getMock()->mockery_getName()
+ . ' should be called' . PHP_EOL
+ . ' at most ' . $this->_limit . ' times but called ' . $n
+ . ' times.'
+ );
+ $exception->setMock($this->_expectation->getMock())
+ ->setMethodName((string) $this->_expectation)
+ ->setExpectedCountComparative('<=')
+ ->setExpectedCount($this->_limit)
+ ->setActualCount($n);
+ throw $exception;
+ }
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/CountValidator/CountValidatorAbstract.php b/vendor/mockery/mockery/library/Mockery/CountValidator/CountValidatorAbstract.php
new file mode 100644
index 0000000..ae3b0bf
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/CountValidator/CountValidatorAbstract.php
@@ -0,0 +1,69 @@
+_expectation = $expectation;
+ $this->_limit = $limit;
+ }
+
+ /**
+ * Checks if the validator can accept an additional nth call
+ *
+ * @param int $n
+ * @return bool
+ */
+ public function isEligible($n)
+ {
+ return ($n < $this->_limit);
+ }
+
+ /**
+ * Validate the call count against this validator
+ *
+ * @param int $n
+ * @return bool
+ */
+ abstract public function validate($n);
+}
diff --git a/vendor/mockery/mockery/library/Mockery/CountValidator/Exact.php b/vendor/mockery/mockery/library/Mockery/CountValidator/Exact.php
new file mode 100644
index 0000000..504f080
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/CountValidator/Exact.php
@@ -0,0 +1,54 @@
+_limit !== $n) {
+ $because = $this->_expectation->getExceptionMessage();
+
+ $exception = new Mockery\Exception\InvalidCountException(
+ 'Method ' . (string) $this->_expectation
+ . ' from ' . $this->_expectation->getMock()->mockery_getName()
+ . ' should be called' . PHP_EOL
+ . ' exactly ' . $this->_limit . ' times but called ' . $n
+ . ' times.'
+ . ($because ? ' Because ' . $this->_expectation->getExceptionMessage() : '')
+ );
+ $exception->setMock($this->_expectation->getMock())
+ ->setMethodName((string) $this->_expectation)
+ ->setExpectedCountComparative('=')
+ ->setExpectedCount($this->_limit)
+ ->setActualCount($n);
+ throw $exception;
+ }
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/CountValidator/Exception.php b/vendor/mockery/mockery/library/Mockery/CountValidator/Exception.php
new file mode 100644
index 0000000..b43aad3
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/CountValidator/Exception.php
@@ -0,0 +1,25 @@
+dismissed = true;
+
+ // we sometimes stack them
+ if ($this->getPrevious() && $this->getPrevious() instanceof BadMethodCallException) {
+ $this->getPrevious()->dismiss();
+ }
+ }
+
+ public function dismissed()
+ {
+ return $this->dismissed;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Exception/InvalidArgumentException.php b/vendor/mockery/mockery/library/Mockery/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..ccf5c76
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Exception/InvalidArgumentException.php
@@ -0,0 +1,25 @@
+mockObject = $mock;
+ return $this;
+ }
+
+ public function setMethodName($name)
+ {
+ $this->method = $name;
+ return $this;
+ }
+
+ public function setActualCount($count)
+ {
+ $this->actual = $count;
+ return $this;
+ }
+
+ public function setExpectedCount($count)
+ {
+ $this->expected = $count;
+ return $this;
+ }
+
+ public function setExpectedCountComparative($comp)
+ {
+ if (!in_array($comp, array('=', '>', '<', '>=', '<='))) {
+ throw new RuntimeException(
+ 'Illegal comparative for expected call counts set: ' . $comp
+ );
+ }
+ $this->expectedComparative = $comp;
+ return $this;
+ }
+
+ public function getMock()
+ {
+ return $this->mockObject;
+ }
+
+ public function getMethodName()
+ {
+ return $this->method;
+ }
+
+ public function getActualCount()
+ {
+ return $this->actual;
+ }
+
+ public function getExpectedCount()
+ {
+ return $this->expected;
+ }
+
+ public function getMockName()
+ {
+ return $this->getMock()->mockery_getName();
+ }
+
+ public function getExpectedCountComparative()
+ {
+ return $this->expectedComparative;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Exception/InvalidOrderException.php b/vendor/mockery/mockery/library/Mockery/Exception/InvalidOrderException.php
new file mode 100644
index 0000000..2134e09
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Exception/InvalidOrderException.php
@@ -0,0 +1,83 @@
+mockObject = $mock;
+ return $this;
+ }
+
+ public function setMethodName($name)
+ {
+ $this->method = $name;
+ return $this;
+ }
+
+ public function setActualOrder($count)
+ {
+ $this->actual = $count;
+ return $this;
+ }
+
+ public function setExpectedOrder($count)
+ {
+ $this->expected = $count;
+ return $this;
+ }
+
+ public function getMock()
+ {
+ return $this->mockObject;
+ }
+
+ public function getMethodName()
+ {
+ return $this->method;
+ }
+
+ public function getActualOrder()
+ {
+ return $this->actual;
+ }
+
+ public function getExpectedOrder()
+ {
+ return $this->expected;
+ }
+
+ public function getMockName()
+ {
+ return $this->getMock()->mockery_getName();
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Exception/NoMatchingExpectationException.php b/vendor/mockery/mockery/library/Mockery/Exception/NoMatchingExpectationException.php
new file mode 100644
index 0000000..1657403
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Exception/NoMatchingExpectationException.php
@@ -0,0 +1,70 @@
+mockObject = $mock;
+ return $this;
+ }
+
+ public function setMethodName($name)
+ {
+ $this->method = $name;
+ return $this;
+ }
+
+ public function setActualArguments($count)
+ {
+ $this->actual = $count;
+ return $this;
+ }
+
+ public function getMock()
+ {
+ return $this->mockObject;
+ }
+
+ public function getMethodName()
+ {
+ return $this->method;
+ }
+
+ public function getActualArguments()
+ {
+ return $this->actual;
+ }
+
+ public function getMockName()
+ {
+ return $this->getMock()->mockery_getName();
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Exception/RuntimeException.php b/vendor/mockery/mockery/library/Mockery/Exception/RuntimeException.php
new file mode 100644
index 0000000..4b2f53c
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Exception/RuntimeException.php
@@ -0,0 +1,25 @@
+_mock = $mock;
+ $this->_name = $name;
+ $this->withAnyArgs();
+ }
+
+ /**
+ * Return a string with the method name and arguments formatted
+ *
+ * @param string $name Name of the expected method
+ * @param array $args List of arguments to the method
+ * @return string
+ */
+ public function __toString()
+ {
+ return \Mockery::formatArgs($this->_name, $this->_expectedArgs);
+ }
+
+ /**
+ * Verify the current call, i.e. that the given arguments match those
+ * of this expectation
+ *
+ * @param array $args
+ * @return mixed
+ */
+ public function verifyCall(array $args)
+ {
+ $this->validateOrder();
+ $this->_actualCount++;
+ if (true === $this->_passthru) {
+ return $this->_mock->mockery_callSubjectMethod($this->_name, $args);
+ }
+
+ $return = $this->_getReturnValue($args);
+ $this->throwAsNecessary($return);
+ $this->_setValues();
+
+ return $return;
+ }
+
+ /**
+ * Throws an exception if the expectation has been configured to do so
+ *
+ * @throws \Exception|\Throwable
+ * @return void
+ */
+ private function throwAsNecessary($return)
+ {
+ if (!$this->_throw) {
+ return;
+ }
+
+ $type = version_compare(PHP_VERSION, '7.0.0') >= 0
+ ? "\Throwable"
+ : "\Exception";
+
+ if ($return instanceof $type) {
+ throw $return;
+ }
+
+ return;
+ }
+
+ /**
+ * Sets public properties with queued values to the mock object
+ *
+ * @param array $args
+ * @return mixed
+ */
+ protected function _setValues()
+ {
+ $mockClass = get_class($this->_mock);
+ $container = $this->_mock->mockery_getContainer();
+ $mocks = $container->getMocks();
+ foreach ($this->_setQueue as $name => &$values) {
+ if (count($values) > 0) {
+ $value = array_shift($values);
+ foreach ($mocks as $mock) {
+ if (is_a($mock, $mockClass)) {
+ $mock->{$name} = $value;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Fetch the return value for the matching args
+ *
+ * @param array $args
+ * @return mixed
+ */
+ protected function _getReturnValue(array $args)
+ {
+ if (count($this->_closureQueue) > 1) {
+ return call_user_func_array(array_shift($this->_closureQueue), $args);
+ } elseif (count($this->_closureQueue) > 0) {
+ return call_user_func_array(current($this->_closureQueue), $args);
+ } elseif (count($this->_returnQueue) > 1) {
+ return array_shift($this->_returnQueue);
+ } elseif (count($this->_returnQueue) > 0) {
+ return current($this->_returnQueue);
+ }
+
+ return $this->_mock->mockery_returnValueForMethod($this->_name);
+ }
+
+ /**
+ * Checks if this expectation is eligible for additional calls
+ *
+ * @return bool
+ */
+ public function isEligible()
+ {
+ foreach ($this->_countValidators as $validator) {
+ if (!$validator->isEligible($this->_actualCount)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Check if there is a constraint on call count
+ *
+ * @return bool
+ */
+ public function isCallCountConstrained()
+ {
+ return (count($this->_countValidators) > 0);
+ }
+
+ /**
+ * Verify call order
+ *
+ * @return void
+ */
+ public function validateOrder()
+ {
+ if ($this->_orderNumber) {
+ $this->_mock->mockery_validateOrder((string) $this, $this->_orderNumber, $this->_mock);
+ }
+ if ($this->_globalOrderNumber) {
+ $this->_mock->mockery_getContainer()
+ ->mockery_validateOrder((string) $this, $this->_globalOrderNumber, $this->_mock);
+ }
+ }
+
+ /**
+ * Verify this expectation
+ *
+ * @return void
+ */
+ public function verify()
+ {
+ foreach ($this->_countValidators as $validator) {
+ $validator->validate($this->_actualCount);
+ }
+ }
+
+ /**
+ * Check if the registered expectation is an ArgumentListMatcher
+ * @return bool
+ */
+ private function isArgumentListMatcher()
+ {
+ return (count($this->_expectedArgs) === 1 && ($this->_expectedArgs[0] instanceof ArgumentListMatcher));
+ }
+
+ private function isAndAnyOtherArgumentsMatcher($expectedArg)
+ {
+ return $expectedArg instanceof AndAnyOtherArgs;
+ }
+
+ /**
+ * Check if passed arguments match an argument expectation
+ *
+ * @param array $args
+ * @return bool
+ */
+ public function matchArgs(array $args)
+ {
+ if ($this->isArgumentListMatcher()) {
+ return $this->_matchArg($this->_expectedArgs[0], $args);
+ }
+ $argCount = count($args);
+ if ($argCount !== count((array) $this->_expectedArgs)) {
+ $lastExpectedArgument = end($this->_expectedArgs);
+ reset($this->_expectedArgs);
+
+ if ($this->isAndAnyOtherArgumentsMatcher($lastExpectedArgument)) {
+ $argCountToSkipMatching = $argCount - count($this->_expectedArgs);
+ $args = array_slice($args, 0, $argCountToSkipMatching);
+ return $this->_matchArgs($args);
+ }
+
+ return false;
+ }
+
+ return $this->_matchArgs($args);
+ }
+
+ /**
+ * Check if the passed arguments match the expectations, one by one.
+ *
+ * @param array $args
+ * @return bool
+ */
+ protected function _matchArgs($args)
+ {
+ $argCount = count($args);
+ for ($i=0; $i<$argCount; $i++) {
+ $param =& $args[$i];
+ if (!$this->_matchArg($this->_expectedArgs[$i], $param)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Check if passed argument matches an argument expectation
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @return bool
+ */
+ protected function _matchArg($expected, &$actual)
+ {
+ if ($expected === $actual) {
+ return true;
+ }
+ if (!is_object($expected) && !is_object($actual) && $expected == $actual) {
+ return true;
+ }
+ if (is_string($expected) && is_object($actual)) {
+ $result = $actual instanceof $expected;
+ if ($result) {
+ return true;
+ }
+ }
+ if ($expected instanceof \Mockery\Matcher\MatcherAbstract) {
+ return $expected->match($actual);
+ }
+ if ($expected instanceof \Hamcrest\Matcher || $expected instanceof \Hamcrest_Matcher) {
+ return $expected->matches($actual);
+ }
+ return false;
+ }
+
+ /**
+ * Expected argument setter for the expectation
+ *
+ * @param mixed[] ...$args
+ * @return self
+ */
+ public function with(...$args)
+ {
+ return $this->withArgs($args);
+ }
+
+ /**
+ * Expected arguments for the expectation passed as an array
+ *
+ * @param array $arguments
+ * @return self
+ */
+ private function withArgsInArray(array $arguments)
+ {
+ if (empty($arguments)) {
+ return $this->withNoArgs();
+ }
+ $this->_expectedArgs = $arguments;
+ return $this;
+ }
+
+ /**
+ * Expected arguments have to be matched by the given closure.
+ *
+ * @param Closure $closure
+ * @return self
+ */
+ private function withArgsMatchedByClosure(Closure $closure)
+ {
+ $this->_expectedArgs = [new MultiArgumentClosure($closure)];
+ return $this;
+ }
+
+ /**
+ * Expected arguments for the expectation passed as an array or a closure that matches each passed argument on
+ * each function call.
+ *
+ * @param array|Closure $argsOrClosure
+ * @return self
+ */
+ public function withArgs($argsOrClosure)
+ {
+ if (is_array($argsOrClosure)) {
+ $this->withArgsInArray($argsOrClosure);
+ } elseif ($argsOrClosure instanceof Closure) {
+ $this->withArgsMatchedByClosure($argsOrClosure);
+ } else {
+ throw new \InvalidArgumentException(sprintf('Call to %s with an invalid argument (%s), only array and '.
+ 'closure are allowed', __METHOD__, $argsOrClosure));
+ }
+ return $this;
+ }
+
+ /**
+ * Set with() as no arguments expected
+ *
+ * @return self
+ */
+ public function withNoArgs()
+ {
+ $this->_expectedArgs = [new NoArgs()];
+ return $this;
+ }
+
+ /**
+ * Set expectation that any arguments are acceptable
+ *
+ * @return self
+ */
+ public function withAnyArgs()
+ {
+ $this->_expectedArgs = [new AnyArgs()];
+ return $this;
+ }
+
+ /**
+ * Set a return value, or sequential queue of return values
+ *
+ * @param mixed[] ...$args
+ * @return self
+ */
+ public function andReturn(...$args)
+ {
+ $this->_returnQueue = $args;
+ return $this;
+ }
+
+ /**
+ * Set a return value, or sequential queue of return values
+ *
+ * @param mixed[] ...$args
+ * @return self
+ */
+ public function andReturns(...$args)
+ {
+ return call_user_func_array([$this, 'andReturn'], $args);
+ }
+
+ /**
+ * Return this mock, like a fluent interface
+ *
+ * @return self
+ */
+ public function andReturnSelf()
+ {
+ return $this->andReturn($this->_mock);
+ }
+
+ /**
+ * Set a sequential queue of return values with an array
+ *
+ * @param array $values
+ * @return self
+ */
+ public function andReturnValues(array $values)
+ {
+ call_user_func_array(array($this, 'andReturn'), $values);
+ return $this;
+ }
+
+ /**
+ * Set a closure or sequence of closures with which to generate return
+ * values. The arguments passed to the expected method are passed to the
+ * closures as parameters.
+ *
+ * @param callable[] ...$args
+ * @return self
+ */
+ public function andReturnUsing(...$args)
+ {
+ $this->_closureQueue = $args;
+ return $this;
+ }
+
+ /**
+ * Return a self-returning black hole object.
+ *
+ * @return self
+ */
+ public function andReturnUndefined()
+ {
+ $this->andReturn(new \Mockery\Undefined);
+ return $this;
+ }
+
+ /**
+ * Return null. This is merely a language construct for Mock describing.
+ *
+ * @return self
+ */
+ public function andReturnNull()
+ {
+ return $this->andReturn(null);
+ }
+
+ public function andReturnFalse()
+ {
+ return $this->andReturn(false);
+ }
+
+ public function andReturnTrue()
+ {
+ return $this->andReturn(true);
+ }
+
+ /**
+ * Set Exception class and arguments to that class to be thrown
+ *
+ * @param string|\Exception $exception
+ * @param string $message
+ * @param int $code
+ * @param \Exception $previous
+ * @return self
+ */
+ public function andThrow($exception, $message = '', $code = 0, \Exception $previous = null)
+ {
+ $this->_throw = true;
+ if (is_object($exception)) {
+ $this->andReturn($exception);
+ } else {
+ $this->andReturn(new $exception($message, $code, $previous));
+ }
+ return $this;
+ }
+
+ public function andThrows($exception, $message = '', $code = 0, \Exception $previous = null)
+ {
+ return $this->andThrow($exception, $message, $code, $previous);
+ }
+
+ /**
+ * Set Exception classes to be thrown
+ *
+ * @param array $exceptions
+ * @return self
+ */
+ public function andThrowExceptions(array $exceptions)
+ {
+ $this->_throw = true;
+ foreach ($exceptions as $exception) {
+ if (!is_object($exception)) {
+ throw new Exception('You must pass an array of exception objects to andThrowExceptions');
+ }
+ }
+ return $this->andReturnValues($exceptions);
+ }
+
+ /**
+ * Register values to be set to a public property each time this expectation occurs
+ *
+ * @param string $name
+ * @param array ...$values
+ * @return self
+ */
+ public function andSet($name, ...$values)
+ {
+ $this->_setQueue[$name] = $values;
+ return $this;
+ }
+
+ /**
+ * Alias to andSet(). Allows the natural English construct
+ * - set('foo', 'bar')->andReturn('bar')
+ *
+ * @param string $name
+ * @param mixed $value
+ * @return self
+ */
+ public function set($name, $value)
+ {
+ return call_user_func_array(array($this, 'andSet'), func_get_args());
+ }
+
+ /**
+ * Indicates this expectation should occur zero or more times
+ *
+ * @return self
+ */
+ public function zeroOrMoreTimes()
+ {
+ $this->atLeast()->never();
+ }
+
+ /**
+ * Indicates the number of times this expectation should occur
+ *
+ * @param int $limit
+ * @throws \InvalidArgumentException
+ * @return self
+ */
+ public function times($limit = null)
+ {
+ if (is_null($limit)) {
+ return $this;
+ }
+ if (!is_int($limit)) {
+ throw new \InvalidArgumentException('The passed Times limit should be an integer value');
+ }
+ $this->_countValidators[$this->_countValidatorClass] = new $this->_countValidatorClass($this, $limit);
+ $this->_countValidatorClass = 'Mockery\CountValidator\Exact';
+ return $this;
+ }
+
+ /**
+ * Indicates that this expectation is never expected to be called
+ *
+ * @return self
+ */
+ public function never()
+ {
+ return $this->times(0);
+ }
+
+ /**
+ * Indicates that this expectation is expected exactly once
+ *
+ * @return self
+ */
+ public function once()
+ {
+ return $this->times(1);
+ }
+
+ /**
+ * Indicates that this expectation is expected exactly twice
+ *
+ * @return self
+ */
+ public function twice()
+ {
+ return $this->times(2);
+ }
+
+ /**
+ * Sets next count validator to the AtLeast instance
+ *
+ * @return self
+ */
+ public function atLeast()
+ {
+ $this->_countValidatorClass = 'Mockery\CountValidator\AtLeast';
+ return $this;
+ }
+
+ /**
+ * Sets next count validator to the AtMost instance
+ *
+ * @return self
+ */
+ public function atMost()
+ {
+ $this->_countValidatorClass = 'Mockery\CountValidator\AtMost';
+ return $this;
+ }
+
+ /**
+ * Shorthand for setting minimum and maximum constraints on call counts
+ *
+ * @param int $minimum
+ * @param int $maximum
+ */
+ public function between($minimum, $maximum)
+ {
+ return $this->atLeast()->times($minimum)->atMost()->times($maximum);
+ }
+
+
+ /**
+ * Set the exception message
+ *
+ * @param string $message
+ * @return $this
+ */
+ public function because($message)
+ {
+ $this->_because = $message;
+ return $this;
+ }
+
+ /**
+ * Indicates that this expectation must be called in a specific given order
+ *
+ * @param string $group Name of the ordered group
+ * @return self
+ */
+ public function ordered($group = null)
+ {
+ if ($this->_globally) {
+ $this->_globalOrderNumber = $this->_defineOrdered($group, $this->_mock->mockery_getContainer());
+ } else {
+ $this->_orderNumber = $this->_defineOrdered($group, $this->_mock);
+ }
+ $this->_globally = false;
+ return $this;
+ }
+
+ /**
+ * Indicates call order should apply globally
+ *
+ * @return self
+ */
+ public function globally()
+ {
+ $this->_globally = true;
+ return $this;
+ }
+
+ /**
+ * Setup the ordering tracking on the mock or mock container
+ *
+ * @param string $group
+ * @param object $ordering
+ * @return int
+ */
+ protected function _defineOrdered($group, $ordering)
+ {
+ $groups = $ordering->mockery_getGroups();
+ if (is_null($group)) {
+ $result = $ordering->mockery_allocateOrder();
+ } elseif (isset($groups[$group])) {
+ $result = $groups[$group];
+ } else {
+ $result = $ordering->mockery_allocateOrder();
+ $ordering->mockery_setGroup($group, $result);
+ }
+ return $result;
+ }
+
+ /**
+ * Return order number
+ *
+ * @return int
+ */
+ public function getOrderNumber()
+ {
+ return $this->_orderNumber;
+ }
+
+ /**
+ * Mark this expectation as being a default
+ *
+ * @return self
+ */
+ public function byDefault()
+ {
+ $director = $this->_mock->mockery_getExpectationsFor($this->_name);
+ if (!empty($director)) {
+ $director->makeExpectationDefault($this);
+ }
+ return $this;
+ }
+
+ /**
+ * Return the parent mock of the expectation
+ *
+ * @return \Mockery\MockInterface
+ */
+ public function getMock()
+ {
+ return $this->_mock;
+ }
+
+ /**
+ * Flag this expectation as calling the original class method with the
+ * any provided arguments instead of using a return value queue.
+ *
+ * @return self
+ */
+ public function passthru()
+ {
+ if ($this->_mock instanceof Mock) {
+ throw new Exception(
+ 'Mock Objects not created from a loaded/existing class are '
+ . 'incapable of passing method calls through to a parent class'
+ );
+ }
+ $this->_passthru = true;
+ return $this;
+ }
+
+ /**
+ * Cloning logic
+ *
+ */
+ public function __clone()
+ {
+ $newValidators = array();
+ $countValidators = $this->_countValidators;
+ foreach ($countValidators as $validator) {
+ $newValidators[] = clone $validator;
+ }
+ $this->_countValidators = $newValidators;
+ }
+
+ public function getName()
+ {
+ return $this->_name;
+ }
+
+ public function getExceptionMessage()
+ {
+ return $this->_because;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/ExpectationDirector.php b/vendor/mockery/mockery/library/Mockery/ExpectationDirector.php
new file mode 100644
index 0000000..d9bb6fb
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/ExpectationDirector.php
@@ -0,0 +1,218 @@
+_name = $name;
+ $this->_mock = $mock;
+ }
+
+ /**
+ * Add a new expectation to the director
+ *
+ * @param \Mockery\Expectation $expectation
+ */
+ public function addExpectation(\Mockery\Expectation $expectation)
+ {
+ $this->_expectations[] = $expectation;
+ }
+
+ /**
+ * Handle a method call being directed by this instance
+ *
+ * @param array $args
+ * @return mixed
+ */
+ public function call(array $args)
+ {
+ $expectation = $this->findExpectation($args);
+ if (is_null($expectation)) {
+ $exception = new \Mockery\Exception\NoMatchingExpectationException(
+ 'No matching handler found for '
+ . $this->_mock->mockery_getName() . '::'
+ . \Mockery::formatArgs($this->_name, $args)
+ . '. Either the method was unexpected or its arguments matched'
+ . ' no expected argument list for this method'
+ . PHP_EOL . PHP_EOL
+ . \Mockery::formatObjects($args)
+ );
+ $exception->setMock($this->_mock)
+ ->setMethodName($this->_name)
+ ->setActualArguments($args);
+ throw $exception;
+ }
+ return $expectation->verifyCall($args);
+ }
+
+ /**
+ * Verify all expectations of the director
+ *
+ * @throws \Mockery\CountValidator\Exception
+ * @return void
+ */
+ public function verify()
+ {
+ if (!empty($this->_expectations)) {
+ foreach ($this->_expectations as $exp) {
+ $exp->verify();
+ }
+ } else {
+ foreach ($this->_defaults as $exp) {
+ $exp->verify();
+ }
+ }
+ }
+
+ /**
+ * Attempt to locate an expectation matching the provided args
+ *
+ * @param array $args
+ * @return mixed
+ */
+ public function findExpectation(array $args)
+ {
+ $expectation = null;
+
+ if (!empty($this->_expectations)) {
+ $expectation = $this->_findExpectationIn($this->_expectations, $args);
+ }
+
+ if ($expectation === null && !empty($this->_defaults)) {
+ $expectation = $this->_findExpectationIn($this->_defaults, $args);
+ }
+
+ return $expectation;
+ }
+
+ /**
+ * Make the given expectation a default for all others assuming it was
+ * correctly created last
+ *
+ * @param \Mockery\Expectation $expectation
+ */
+ public function makeExpectationDefault(\Mockery\Expectation $expectation)
+ {
+ $last = end($this->_expectations);
+ if ($last === $expectation) {
+ array_pop($this->_expectations);
+ array_unshift($this->_defaults, $expectation);
+ } else {
+ throw new \Mockery\Exception(
+ 'Cannot turn a previously defined expectation into a default'
+ );
+ }
+ }
+
+ /**
+ * Search current array of expectations for a match
+ *
+ * @param array $expectations
+ * @param array $args
+ * @return mixed
+ */
+ protected function _findExpectationIn(array $expectations, array $args)
+ {
+ foreach ($expectations as $exp) {
+ if ($exp->isEligible() && $exp->matchArgs($args)) {
+ return $exp;
+ }
+ }
+ foreach ($expectations as $exp) {
+ if ($exp->matchArgs($args)) {
+ return $exp;
+ }
+ }
+ }
+
+ /**
+ * Return all expectations assigned to this director
+ *
+ * @return array
+ */
+ public function getExpectations()
+ {
+ return $this->_expectations;
+ }
+
+ /**
+ * Return all expectations assigned to this director
+ *
+ * @return array
+ */
+ public function getDefaultExpectations()
+ {
+ return $this->_defaults;
+ }
+
+ /**
+ * Return the number of expectations assigned to this director.
+ *
+ * @return int
+ */
+ public function getExpectationCount()
+ {
+ return count($this->getExpectations()) ?: count($this->getDefaultExpectations());
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/ExpectationInterface.php b/vendor/mockery/mockery/library/Mockery/ExpectationInterface.php
new file mode 100644
index 0000000..7d0b536
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/ExpectationInterface.php
@@ -0,0 +1,46 @@
+once();
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/CachingGenerator.php b/vendor/mockery/mockery/library/Mockery/Generator/CachingGenerator.php
new file mode 100644
index 0000000..6497e88
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/CachingGenerator.php
@@ -0,0 +1,45 @@
+generator = $generator;
+ }
+
+ public function generate(MockConfiguration $config)
+ {
+ $hash = $config->getHash();
+ if (isset($this->cache[$hash])) {
+ return $this->cache[$hash];
+ }
+
+ $definition = $this->generator->generate($config);
+ $this->cache[$hash] = $definition;
+
+ return $definition;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/DefinedTargetClass.php b/vendor/mockery/mockery/library/Mockery/Generator/DefinedTargetClass.php
new file mode 100644
index 0000000..663b225
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/DefinedTargetClass.php
@@ -0,0 +1,108 @@
+rfc = $rfc;
+ }
+
+ public static function factory($name)
+ {
+ return new self(new \ReflectionClass($name));
+ }
+
+ public function getName()
+ {
+ return $this->rfc->getName();
+ }
+
+ public function isAbstract()
+ {
+ return $this->rfc->isAbstract();
+ }
+
+ public function isFinal()
+ {
+ return $this->rfc->isFinal();
+ }
+
+ public function getMethods()
+ {
+ return array_map(function ($method) {
+ return new Method($method);
+ }, $this->rfc->getMethods());
+ }
+
+ public function getInterfaces()
+ {
+ $class = __CLASS__;
+ return array_map(function ($interface) use ($class) {
+ return new $class($interface);
+ }, $this->rfc->getInterfaces());
+ }
+
+ public function __toString()
+ {
+ return $this->getName();
+ }
+
+ public function getNamespaceName()
+ {
+ return $this->rfc->getNamespaceName();
+ }
+
+ public function inNamespace()
+ {
+ return $this->rfc->inNamespace();
+ }
+
+ public function getShortName()
+ {
+ return $this->rfc->getShortName();
+ }
+
+ public function implementsInterface($interface)
+ {
+ return $this->rfc->implementsInterface($interface);
+ }
+
+ public function hasInternalAncestor()
+ {
+ if ($this->rfc->isInternal()) {
+ return true;
+ }
+
+ $child = $this->rfc;
+ while ($parent = $child->getParentClass()) {
+ if ($parent->isInternal()) {
+ return true;
+ }
+ $child = $parent;
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/Generator.php b/vendor/mockery/mockery/library/Mockery/Generator/Generator.php
new file mode 100644
index 0000000..459a93c
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/Generator.php
@@ -0,0 +1,27 @@
+method = $method;
+ }
+
+ public function __call($method, $args)
+ {
+ return call_user_func_array(array($this->method, $method), $args);
+ }
+
+ public function getParameters()
+ {
+ return array_map(function ($parameter) {
+ return new Parameter($parameter);
+ }, $this->method->getParameters());
+ }
+
+ public function getReturnType()
+ {
+ if (defined('HHVM_VERSION') && method_exists($this->method, 'getReturnTypeText') && $this->method->hasReturnType()) {
+ // Available in HHVM
+ $returnType = $this->method->getReturnTypeText();
+
+ // Remove tuple, ImmVector<>, ImmSet<>, ImmMap<>, array<>, anything with <>, void, mixed which cause eval() errors
+ if (preg_match('/(\w+<.*>)|(\(.+\))|(HH\\\\(void|mixed|this))/', $returnType)) {
+ return '';
+ }
+
+ // return directly without going through php logic.
+ return $returnType;
+ }
+
+ if (version_compare(PHP_VERSION, '7.0.0-dev') >= 0 && $this->method->hasReturnType()) {
+ $returnType = (string) $this->method->getReturnType();
+
+ if ('self' === $returnType) {
+ $returnType = "\\".$this->method->getDeclaringClass()->getName();
+ } elseif (!\Mockery::isBuiltInType($returnType)) {
+ $returnType = '\\'.$returnType;
+ }
+
+ if (version_compare(PHP_VERSION, '7.1.0-dev') >= 0 && $this->method->getReturnType()->allowsNull()) {
+ $returnType = '?'.$returnType;
+ }
+
+ return $returnType;
+ }
+ return '';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/MockConfiguration.php b/vendor/mockery/mockery/library/Mockery/Generator/MockConfiguration.php
new file mode 100644
index 0000000..5293118
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/MockConfiguration.php
@@ -0,0 +1,579 @@
+addTargets($targets);
+ $this->blackListedMethods = $blackListedMethods;
+ $this->whiteListedMethods = $whiteListedMethods;
+ $this->name = $name;
+ $this->instanceMock = $instanceMock;
+ $this->parameterOverrides = $parameterOverrides;
+ $this->mockOriginalDestructor = $mockOriginalDestructor;
+ $this->constantsMap = $constantsMap;
+ }
+
+ /**
+ * Attempt to create a hash of the configuration, in order to allow caching
+ *
+ * @TODO workout if this will work
+ *
+ * @return string
+ */
+ public function getHash()
+ {
+ $vars = array(
+ 'targetClassName' => $this->targetClassName,
+ 'targetInterfaceNames' => $this->targetInterfaceNames,
+ 'targetTraitNames' => $this->targetTraitNames,
+ 'name' => $this->name,
+ 'blackListedMethods' => $this->blackListedMethods,
+ 'whiteListedMethod' => $this->whiteListedMethods,
+ 'instanceMock' => $this->instanceMock,
+ 'parameterOverrides' => $this->parameterOverrides,
+ 'mockOriginalDestructor' => $this->mockOriginalDestructor
+ );
+
+ return md5(serialize($vars));
+ }
+
+ /**
+ * Gets a list of methods from the classes, interfaces and objects and
+ * filters them appropriately. Lot's of filtering going on, perhaps we could
+ * have filter classes to iterate through
+ */
+ public function getMethodsToMock()
+ {
+ $methods = $this->getAllMethods();
+
+ foreach ($methods as $key => $method) {
+ if ($method->isFinal()) {
+ unset($methods[$key]);
+ }
+ }
+
+ /**
+ * Whitelist trumps everything else
+ */
+ if (count($this->getWhiteListedMethods())) {
+ $whitelist = array_map('strtolower', $this->getWhiteListedMethods());
+ $methods = array_filter($methods, function ($method) use ($whitelist) {
+ return $method->isAbstract() || in_array(strtolower($method->getName()), $whitelist);
+ });
+
+ return $methods;
+ }
+
+ /**
+ * Remove blacklisted methods
+ */
+ if (count($this->getBlackListedMethods())) {
+ $blacklist = array_map('strtolower', $this->getBlackListedMethods());
+ $methods = array_filter($methods, function ($method) use ($blacklist) {
+ return !in_array(strtolower($method->getName()), $blacklist);
+ });
+ }
+
+ /**
+ * Internal objects can not be instantiated with newInstanceArgs and if
+ * they implement Serializable, unserialize will have to be called. As
+ * such, we can't mock it and will need a pass to add a dummy
+ * implementation
+ */
+ if ($this->getTargetClass()
+ && $this->getTargetClass()->implementsInterface("Serializable")
+ && $this->getTargetClass()->hasInternalAncestor()) {
+ $methods = array_filter($methods, function ($method) {
+ return $method->getName() !== "unserialize";
+ });
+ }
+
+ return array_values($methods);
+ }
+
+ /**
+ * We declare the __call method to handle undefined stuff, if the class
+ * we're mocking has also defined it, we need to comply with their interface
+ */
+ public function requiresCallTypeHintRemoval()
+ {
+ foreach ($this->getAllMethods() as $method) {
+ if ("__call" === $method->getName()) {
+ $params = $method->getParameters();
+ return !$params[1]->isArray();
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * We declare the __callStatic method to handle undefined stuff, if the class
+ * we're mocking has also defined it, we need to comply with their interface
+ */
+ public function requiresCallStaticTypeHintRemoval()
+ {
+ foreach ($this->getAllMethods() as $method) {
+ if ("__callStatic" === $method->getName()) {
+ $params = $method->getParameters();
+ return !$params[1]->isArray();
+ }
+ }
+
+ return false;
+ }
+
+ public function rename($className)
+ {
+ $targets = array();
+
+ if ($this->targetClassName) {
+ $targets[] = $this->targetClassName;
+ }
+
+ if ($this->targetInterfaceNames) {
+ $targets = array_merge($targets, $this->targetInterfaceNames);
+ }
+
+ if ($this->targetTraitNames) {
+ $targets = array_merge($targets, $this->targetTraitNames);
+ }
+
+ if ($this->targetObject) {
+ $targets[] = $this->targetObject;
+ }
+
+ return new self(
+ $targets,
+ $this->blackListedMethods,
+ $this->whiteListedMethods,
+ $className,
+ $this->instanceMock,
+ $this->parameterOverrides,
+ $this->mockOriginalDestructor,
+ $this->constantsMap
+ );
+ }
+
+ protected function addTarget($target)
+ {
+ if (is_object($target)) {
+ $this->setTargetObject($target);
+ $this->setTargetClassName(get_class($target));
+ return $this;
+ }
+
+ if ($target[0] !== "\\") {
+ $target = "\\" . $target;
+ }
+
+ if (class_exists($target)) {
+ $this->setTargetClassName($target);
+ return $this;
+ }
+
+ if (interface_exists($target)) {
+ $this->addTargetInterfaceName($target);
+ return $this;
+ }
+
+ if (trait_exists($target)) {
+ $this->addTargetTraitName($target);
+ return $this;
+ }
+
+ /**
+ * Default is to set as class, or interface if class already set
+ *
+ * Don't like this condition, can't remember what the default
+ * targetClass is for
+ */
+ if ($this->getTargetClassName()) {
+ $this->addTargetInterfaceName($target);
+ return $this;
+ }
+
+ $this->setTargetClassName($target);
+ }
+
+ protected function addTargets($interfaces)
+ {
+ foreach ($interfaces as $interface) {
+ $this->addTarget($interface);
+ }
+ }
+
+ public function getTargetClassName()
+ {
+ return $this->targetClassName;
+ }
+
+ public function getTargetClass()
+ {
+ if ($this->targetClass) {
+ return $this->targetClass;
+ }
+
+ if (!$this->targetClassName) {
+ return null;
+ }
+
+ if (class_exists($this->targetClassName)) {
+ $dtc = DefinedTargetClass::factory($this->targetClassName);
+
+ if ($this->getTargetObject() == false && $dtc->isFinal()) {
+ throw new \Mockery\Exception(
+ 'The class ' . $this->targetClassName . ' is marked final and its methods'
+ . ' cannot be replaced. Classes marked final can be passed in'
+ . ' to \Mockery::mock() as instantiated objects to create a'
+ . ' partial mock, but only if the mock is not subject to type'
+ . ' hinting checks.'
+ );
+ }
+
+ $this->targetClass = $dtc;
+ } else {
+ $this->targetClass = UndefinedTargetClass::factory($this->targetClassName);
+ }
+
+ return $this->targetClass;
+ }
+
+ public function getTargetTraits()
+ {
+ if (!empty($this->targetTraits)) {
+ return $this->targetTraits;
+ }
+
+ foreach ($this->targetTraitNames as $targetTrait) {
+ $this->targetTraits[] = DefinedTargetClass::factory($targetTrait);
+ }
+
+ $this->targetTraits = array_unique($this->targetTraits); // just in case
+ return $this->targetTraits;
+ }
+
+ public function getTargetInterfaces()
+ {
+ if (!empty($this->targetInterfaces)) {
+ return $this->targetInterfaces;
+ }
+
+ foreach ($this->targetInterfaceNames as $targetInterface) {
+ if (!interface_exists($targetInterface)) {
+ $this->targetInterfaces[] = UndefinedTargetClass::factory($targetInterface);
+ return;
+ }
+
+ $dtc = DefinedTargetClass::factory($targetInterface);
+ $extendedInterfaces = array_keys($dtc->getInterfaces());
+ $extendedInterfaces[] = $targetInterface;
+
+ $traversableFound = false;
+ $iteratorShiftedToFront = false;
+ foreach ($extendedInterfaces as $interface) {
+ if (!$traversableFound && preg_match("/^\\?Iterator(|Aggregate)$/i", $interface)) {
+ break;
+ }
+
+ if (preg_match("/^\\\\?IteratorAggregate$/i", $interface)) {
+ $this->targetInterfaces[] = DefinedTargetClass::factory("\\IteratorAggregate");
+ $iteratorShiftedToFront = true;
+ } elseif (preg_match("/^\\\\?Iterator$/i", $interface)) {
+ $this->targetInterfaces[] = DefinedTargetClass::factory("\\Iterator");
+ $iteratorShiftedToFront = true;
+ } elseif (preg_match("/^\\\\?Traversable$/i", $interface)) {
+ $traversableFound = true;
+ }
+ }
+
+ if ($traversableFound && !$iteratorShiftedToFront) {
+ $this->targetInterfaces[] = DefinedTargetClass::factory("\\IteratorAggregate");
+ }
+
+ /**
+ * We never straight up implement Traversable
+ */
+ if (!preg_match("/^\\\\?Traversable$/i", $targetInterface)) {
+ $this->targetInterfaces[] = $dtc;
+ }
+ }
+ $this->targetInterfaces = array_unique($this->targetInterfaces); // just in case
+ return $this->targetInterfaces;
+ }
+
+ public function getTargetObject()
+ {
+ return $this->targetObject;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Generate a suitable name based on the config
+ */
+ public function generateName()
+ {
+ $name = 'Mockery_' . static::$mockCounter++;
+
+ if ($this->getTargetObject()) {
+ $name .= "_" . str_replace("\\", "_", get_class($this->getTargetObject()));
+ }
+
+ if ($this->getTargetClass()) {
+ $name .= "_" . str_replace("\\", "_", $this->getTargetClass()->getName());
+ }
+
+ if ($this->getTargetInterfaces()) {
+ $name .= array_reduce($this->getTargetInterfaces(), function ($tmpname, $i) {
+ $tmpname .= '_' . str_replace("\\", "_", $i->getName());
+ return $tmpname;
+ }, '');
+ }
+
+ return $name;
+ }
+
+ public function getShortName()
+ {
+ $parts = explode("\\", $this->getName());
+ return array_pop($parts);
+ }
+
+ public function getNamespaceName()
+ {
+ $parts = explode("\\", $this->getName());
+ array_pop($parts);
+
+ if (count($parts)) {
+ return implode("\\", $parts);
+ }
+
+ return "";
+ }
+
+ public function getBlackListedMethods()
+ {
+ return $this->blackListedMethods;
+ }
+
+ public function getWhiteListedMethods()
+ {
+ return $this->whiteListedMethods;
+ }
+
+ public function isInstanceMock()
+ {
+ return $this->instanceMock;
+ }
+
+ public function getParameterOverrides()
+ {
+ return $this->parameterOverrides;
+ }
+
+ public function isMockOriginalDestructor()
+ {
+ return $this->mockOriginalDestructor;
+ }
+
+ protected function setTargetClassName($targetClassName)
+ {
+ $this->targetClassName = $targetClassName;
+ }
+
+ protected function getAllMethods()
+ {
+ if ($this->allMethods) {
+ return $this->allMethods;
+ }
+
+ $classes = $this->getTargetInterfaces();
+
+ if ($this->getTargetClass()) {
+ $classes[] = $this->getTargetClass();
+ }
+
+ $methods = array();
+ foreach ($classes as $class) {
+ $methods = array_merge($methods, $class->getMethods());
+ }
+
+ foreach ($this->getTargetTraits() as $trait) {
+ foreach ($trait->getMethods() as $method) {
+ if ($method->isAbstract()) {
+ $methods[] = $method;
+ }
+ }
+ }
+
+ $names = array();
+ $methods = array_filter($methods, function ($method) use (&$names) {
+ if (in_array($method->getName(), $names)) {
+ return false;
+ }
+
+ $names[] = $method->getName();
+ return true;
+ });
+
+ // In HHVM, class methods can be annotated with the built-in
+ // <<__Memoize>> attribute (similar to a Python decorator),
+ // which builds an LRU cache of method arguments and their
+ // return values.
+ // https://docs.hhvm.com/hack/attributes/special#__memoize
+ //
+ // HHVM implements this behavior by inserting a private helper
+ // method into the class at runtime which is named as the
+ // method to be memoized, suffixed by `$memoize_impl`.
+ // https://github.com/facebook/hhvm/blob/6aa46f1e8c2351b97d65e67b73e26f274a7c3f2e/hphp/runtime/vm/func.cpp#L364
+ //
+ // Ordinarily, PHP does not all allow the `$` token in method
+ // names, but since the memoization helper is inserted at
+ // runtime (and not in userland), HHVM allows it.
+ //
+ // We use code generation and eval() for some types of mocks,
+ // so to avoid syntax errors from these memoization helpers,
+ // we must filter them from our list of class methods.
+ //
+ // This effectively disables the memoization behavior in HHVM,
+ // but that's preferable to failing catastrophically when
+ // attempting to mock a class using the attribute.
+ if (defined('HHVM_VERSION')) {
+ $methods = array_filter($methods, function ($method) {
+ return strpos($method->getName(), '$memoize_impl') === false;
+ });
+ }
+
+ return $this->allMethods = $methods;
+ }
+
+ /**
+ * If we attempt to implement Traversable, we must ensure we are also
+ * implementing either Iterator or IteratorAggregate, and that whichever one
+ * it is comes before Traversable in the list of implements.
+ */
+ protected function addTargetInterfaceName($targetInterface)
+ {
+ $this->targetInterfaceNames[] = $targetInterface;
+ }
+
+ protected function addTargetTraitName($targetTraitName)
+ {
+ $this->targetTraitNames[] = $targetTraitName;
+ }
+
+ protected function setTargetObject($object)
+ {
+ $this->targetObject = $object;
+ }
+
+ public function getConstantsMap()
+ {
+ return $this->constantsMap;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/MockConfigurationBuilder.php b/vendor/mockery/mockery/library/Mockery/Generator/MockConfigurationBuilder.php
new file mode 100644
index 0000000..8170492
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/MockConfigurationBuilder.php
@@ -0,0 +1,176 @@
+= 0) {
+ $this->blackListedMethods = array_diff($this->blackListedMethods, $this->php7SemiReservedKeywords);
+ }
+ }
+
+ public function addTarget($target)
+ {
+ $this->targets[] = $target;
+
+ return $this;
+ }
+
+ public function addTargets($targets)
+ {
+ foreach ($targets as $target) {
+ $this->addTarget($target);
+ }
+
+ return $this;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function addBlackListedMethod($blackListedMethod)
+ {
+ $this->blackListedMethods[] = $blackListedMethod;
+ return $this;
+ }
+
+ public function addBlackListedMethods(array $blackListedMethods)
+ {
+ foreach ($blackListedMethods as $method) {
+ $this->addBlackListedMethod($method);
+ }
+ return $this;
+ }
+
+ public function setBlackListedMethods(array $blackListedMethods)
+ {
+ $this->blackListedMethods = $blackListedMethods;
+ return $this;
+ }
+
+ public function addWhiteListedMethod($whiteListedMethod)
+ {
+ $this->whiteListedMethods[] = $whiteListedMethod;
+ return $this;
+ }
+
+ public function addWhiteListedMethods(array $whiteListedMethods)
+ {
+ foreach ($whiteListedMethods as $method) {
+ $this->addWhiteListedMethod($method);
+ }
+ return $this;
+ }
+
+ public function setWhiteListedMethods(array $whiteListedMethods)
+ {
+ $this->whiteListedMethods = $whiteListedMethods;
+ return $this;
+ }
+
+ public function setInstanceMock($instanceMock)
+ {
+ $this->instanceMock = (bool) $instanceMock;
+ }
+
+ public function setParameterOverrides(array $overrides)
+ {
+ $this->parameterOverrides = $overrides;
+ }
+
+ public function setMockOriginalDestructor($mockDestructor)
+ {
+ $this->mockOriginalDestructor = $mockDestructor;
+ return $this;
+ }
+
+ public function setConstantsMap(array $map)
+ {
+ $this->constantsMap = $map;
+ }
+
+ public function getMockConfiguration()
+ {
+ return new MockConfiguration(
+ $this->targets,
+ $this->blackListedMethods,
+ $this->whiteListedMethods,
+ $this->name,
+ $this->instanceMock,
+ $this->parameterOverrides,
+ $this->mockOriginalDestructor,
+ $this->constantsMap
+ );
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/MockDefinition.php b/vendor/mockery/mockery/library/Mockery/Generator/MockDefinition.php
new file mode 100644
index 0000000..fd6a9fa
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/MockDefinition.php
@@ -0,0 +1,51 @@
+getName()) {
+ throw new \InvalidArgumentException("MockConfiguration must contain a name");
+ }
+ $this->config = $config;
+ $this->code = $code;
+ }
+
+ public function getConfig()
+ {
+ return $this->config;
+ }
+
+ public function getClassName()
+ {
+ return $this->config->getName();
+ }
+
+ public function getCode()
+ {
+ return $this->code;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/Parameter.php b/vendor/mockery/mockery/library/Mockery/Generator/Parameter.php
new file mode 100644
index 0000000..a5338c0
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/Parameter.php
@@ -0,0 +1,110 @@
+rfp = $rfp;
+ }
+
+ public function __call($method, array $args)
+ {
+ return call_user_func_array(array($this->rfp, $method), $args);
+ }
+
+ public function getClass()
+ {
+ return new DefinedTargetClass($this->rfp->getClass());
+ }
+
+ public function getTypeHintAsString()
+ {
+ if (method_exists($this->rfp, 'getTypehintText')) {
+ // Available in HHVM
+ $typehint = $this->rfp->getTypehintText();
+
+ // not exhaustive, but will do for now
+ if (in_array($typehint, array('int', 'integer', 'float', 'string', 'bool', 'boolean'))) {
+ return '';
+ }
+
+ return $typehint;
+ }
+
+ if ($this->rfp->isArray()) {
+ return 'array';
+ }
+
+ /*
+ * PHP < 5.4.1 has some strange behaviour with a typehint of self and
+ * subclass signatures, so we risk the regexp instead
+ */
+ if ((version_compare(PHP_VERSION, '5.4.1') >= 0)) {
+ try {
+ if ($this->rfp->getClass()) {
+ return $this->rfp->getClass()->getName();
+ }
+ } catch (\ReflectionException $re) {
+ // noop
+ }
+ }
+
+ if (version_compare(PHP_VERSION, '7.0.0-dev') >= 0 && $this->rfp->hasType()) {
+ return (string) $this->rfp->getType();
+ }
+
+ if (preg_match('/^Parameter #[0-9]+ \[ \<(required|optional)\> (?\S+ )?.*\$' . $this->rfp->getName() . ' .*\]$/', $this->rfp->__toString(), $typehintMatch)) {
+ if (!empty($typehintMatch['typehint'])) {
+ return $typehintMatch['typehint'];
+ }
+ }
+
+ return '';
+ }
+
+ /**
+ * Some internal classes have funny looking definitions...
+ */
+ public function getName()
+ {
+ $name = $this->rfp->getName();
+ if (!$name || $name == '...') {
+ $name = 'arg' . static::$parameterCounter++;
+ }
+
+ return $name;
+ }
+
+
+ /**
+ * Variadics only introduced in 5.6
+ */
+ public function isVariadic()
+ {
+ return $this->rfp->isVariadic();
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/CallTypeHintPass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/CallTypeHintPass.php
new file mode 100644
index 0000000..fd00264
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/CallTypeHintPass.php
@@ -0,0 +1,47 @@
+requiresCallTypeHintRemoval()) {
+ $code = str_replace(
+ 'public function __call($method, array $args)',
+ 'public function __call($method, $args)',
+ $code
+ );
+ }
+
+ if ($config->requiresCallStaticTypeHintRemoval()) {
+ $code = str_replace(
+ 'public static function __callStatic($method, array $args)',
+ 'public static function __callStatic($method, $args)',
+ $code
+ );
+ }
+
+ return $code;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/ClassNamePass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/ClassNamePass.php
new file mode 100644
index 0000000..b5a3109
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/ClassNamePass.php
@@ -0,0 +1,49 @@
+getNamespaceName();
+
+ $namespace = ltrim($namespace, "\\");
+
+ $className = $config->getShortName();
+
+ $code = str_replace(
+ 'namespace Mockery;',
+ $namespace ? 'namespace ' . $namespace . ';' : '',
+ $code
+ );
+
+ $code = str_replace(
+ 'class Mock',
+ 'class ' . $className,
+ $code
+ );
+
+ return $code;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/ClassPass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/ClassPass.php
new file mode 100644
index 0000000..91ccfab
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/ClassPass.php
@@ -0,0 +1,52 @@
+getTargetClass();
+
+ if (!$target) {
+ return $code;
+ }
+
+ if ($target->isFinal()) {
+ return $code;
+ }
+
+ $className = ltrim($target->getName(), "\\");
+ if (!class_exists($className)) {
+ \Mockery::declareClass($className);
+ }
+
+ $code = str_replace(
+ "implements MockInterface",
+ "extends \\" . $className . " implements MockInterface",
+ $code
+ );
+
+ return $code;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/ConstantsPass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/ConstantsPass.php
new file mode 100644
index 0000000..28f5cdf
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/ConstantsPass.php
@@ -0,0 +1,33 @@
+getConstantsMap();
+ if (empty($cm)) {
+ return $code;
+ }
+
+ if (!isset($cm[$config->getName()])) {
+ return $code;
+ }
+
+ $cm = $cm[$config->getName()];
+
+ $constantsCode = '';
+ foreach ($cm as $constant => $value) {
+ $constantsCode .= sprintf("\n const %s = '%s';\n", $constant, $value);
+ }
+
+ $i = strrpos($code, '}');
+ $code = substr_replace($code, $constantsCode, $i);
+ $code .= "}\n";
+
+ return $code;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/InstanceMockPass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/InstanceMockPass.php
new file mode 100644
index 0000000..6279147
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/InstanceMockPass.php
@@ -0,0 +1,83 @@
+_mockery_ignoreVerification = false;
+ \$associatedRealObject = \Mockery::fetchMock(__CLASS__);
+
+ foreach (get_object_vars(\$this) as \$attr => \$val) {
+ if (\$attr !== "_mockery_ignoreVerification" && \$attr !== "_mockery_expectations") {
+ \$this->\$attr = \$associatedRealObject->\$attr;
+ }
+ }
+
+ \$directors = \$associatedRealObject->mockery_getExpectations();
+ foreach (\$directors as \$method=>\$director) {
+ // get the director method needed
+ \$existingDirector = \$this->mockery_getExpectationsFor(\$method);
+ if (!\$existingDirector) {
+ \$existingDirector = new \Mockery\ExpectationDirector(\$method, \$this);
+ \$this->mockery_setExpectationsFor(\$method, \$existingDirector);
+ }
+ \$expectations = \$director->getExpectations();
+ foreach (\$expectations as \$expectation) {
+ \$clonedExpectation = clone \$expectation;
+ \$existingDirector->addExpectation(\$clonedExpectation);
+ }
+ \$defaultExpectations = \$director->getDefaultExpectations();
+ foreach (array_reverse(\$defaultExpectations) as \$expectation) {
+ \$clonedExpectation = clone \$expectation;
+ \$existingDirector->addExpectation(\$clonedExpectation);
+ \$existingDirector->makeExpectationDefault(\$clonedExpectation);
+ }
+ }
+ \Mockery::getContainer()->rememberMock(\$this);
+
+ \$this->_mockery_constructorCalled(func_get_args());
+ }
+MOCK;
+
+ public function apply($code, MockConfiguration $config)
+ {
+ if ($config->isInstanceMock()) {
+ $code = $this->appendToClass($code, static::INSTANCE_MOCK_CODE);
+ }
+
+ return $code;
+ }
+
+ protected function appendToClass($class, $code)
+ {
+ $lastBrace = strrpos($class, "}");
+ $class = substr($class, 0, $lastBrace) . $code . "\n }\n";
+ return $class;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/InterfacePass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/InterfacePass.php
new file mode 100644
index 0000000..982956e
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/InterfacePass.php
@@ -0,0 +1,48 @@
+getTargetInterfaces() as $i) {
+ $name = ltrim($i->getName(), "\\");
+ if (!interface_exists($name)) {
+ \Mockery::declareInterface($name);
+ }
+ }
+
+ $interfaces = array_reduce((array) $config->getTargetInterfaces(), function ($code, $i) {
+ return $code . ", \\" . ltrim($i->getName(), "\\");
+ }, "");
+
+ $code = str_replace(
+ "implements MockInterface",
+ "implements MockInterface" . $interfaces,
+ $code
+ );
+
+ return $code;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/MagicMethodTypeHintsPass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/MagicMethodTypeHintsPass.php
new file mode 100644
index 0000000..4a457b3
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/MagicMethodTypeHintsPass.php
@@ -0,0 +1,208 @@
+getMagicMethods($config->getTargetClass());
+ foreach ($config->getTargetInterfaces() as $interface) {
+ $magicMethods = array_merge($magicMethods, $this->getMagicMethods($interface));
+ }
+
+ foreach ($magicMethods as $method) {
+ $code = $this->applyMagicTypeHints($code, $method);
+ }
+
+ return $code;
+ }
+
+ /**
+ * Returns the magic methods within the
+ * passed DefinedTargetClass.
+ *
+ * @param TargetClassInterface $class
+ * @return array
+ */
+ public function getMagicMethods(
+ TargetClassInterface $class = null
+ ) {
+ if (is_null($class)) {
+ return array();
+ }
+ return array_filter($class->getMethods(), function (Method $method) {
+ return in_array($method->getName(), $this->mockMagicMethods);
+ });
+ }
+
+ /**
+ * Applies type hints of magic methods from
+ * class to the passed code.
+ *
+ * @param int $code
+ * @param Method $method
+ * @return string
+ */
+ private function applyMagicTypeHints($code, Method $method)
+ {
+ if ($this->isMethodWithinCode($code, $method)) {
+ $namedParameters = $this->getOriginalParameters(
+ $code,
+ $method
+ );
+ $code = preg_replace(
+ $this->getDeclarationRegex($method->getName()),
+ $this->getMethodDeclaration($method, $namedParameters),
+ $code
+ );
+ }
+ return $code;
+ }
+
+ /**
+ * Checks if the method is declared withing code.
+ *
+ * @param int $code
+ * @param Method $method
+ * @return boolean
+ */
+ private function isMethodWithinCode($code, Method $method)
+ {
+ return preg_match(
+ $this->getDeclarationRegex($method->getName()),
+ $code
+ ) == 1;
+ }
+
+ /**
+ * Returns the method original parameters, as they're
+ * described in the $code string.
+ *
+ * @param int $code
+ * @param Method $method
+ * @return array
+ */
+ private function getOriginalParameters($code, Method $method)
+ {
+ $matches = [];
+ $parameterMatches = [];
+
+ preg_match(
+ $this->getDeclarationRegex($method->getName()),
+ $code,
+ $matches
+ );
+
+ if (count($matches) > 0) {
+ preg_match_all(
+ '/(?<=\$)(\w+)+/i',
+ $matches[0],
+ $parameterMatches
+ );
+ }
+
+ $groupMatches = end($parameterMatches);
+ $parameterNames = is_array($groupMatches) ?
+ $groupMatches :
+ array($groupMatches);
+
+ return $parameterNames;
+ }
+
+ /**
+ * Gets the declaration code, as a string, for the passed method.
+ *
+ * @param Method $method
+ * @param array $namedParameters
+ * @return string
+ */
+ private function getMethodDeclaration(
+ Method $method,
+ array $namedParameters
+ ) {
+ $declaration = 'public';
+ $declaration .= $method->isStatic() ? ' static' : '';
+ $declaration .= ' function '.$method->getName().'(';
+
+ foreach ($method->getParameters() as $index => $parameter) {
+ $declaration .= $parameter->getTypeHintAsString().' ';
+ $name = isset($namedParameters[$index]) ?
+ $namedParameters[$index] :
+ $parameter->getName();
+ $declaration .= '$'.$name;
+ $declaration .= ',';
+ }
+ $declaration = rtrim($declaration, ',');
+ $declaration .= ') ';
+
+ $returnType = $method->getReturnType();
+ if (!empty($returnType)) {
+ $declaration .= ': '.$returnType;
+ }
+
+ return $declaration;
+ }
+
+ /**
+ * Returns a regex string used to match the
+ * declaration of some method.
+ *
+ * @param string $methodName
+ * @return string
+ */
+ private function getDeclarationRegex($methodName)
+ {
+ return "/public\s+(?:static\s+)?function\s+$methodName\s*\(.*\)\s*(?=\{)/i";
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/MethodDefinitionPass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/MethodDefinitionPass.php
new file mode 100644
index 0000000..c83ecf8
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/MethodDefinitionPass.php
@@ -0,0 +1,175 @@
+getMethodsToMock() as $method) {
+ if ($method->isPublic()) {
+ $methodDef = 'public';
+ } elseif ($method->isProtected()) {
+ $methodDef = 'protected';
+ } else {
+ $methodDef = 'private';
+ }
+
+ if ($method->isStatic()) {
+ $methodDef .= ' static';
+ }
+
+ $methodDef .= ' function ';
+ $methodDef .= $method->returnsReference() ? ' & ' : '';
+ $methodDef .= $method->getName();
+ $methodDef .= $this->renderParams($method, $config);
+ $methodDef .= $this->renderReturnType($method);
+ $methodDef .= $this->renderMethodBody($method, $config);
+
+ $code = $this->appendToClass($code, $methodDef);
+ }
+
+ return $code;
+ }
+
+ protected function renderParams(Method $method, $config)
+ {
+ $class = $method->getDeclaringClass();
+ if ($class->isInternal()) {
+ $overrides = $config->getParameterOverrides();
+
+ if (isset($overrides[strtolower($class->getName())][$method->getName()])) {
+ return '(' . implode(',', $overrides[strtolower($class->getName())][$method->getName()]) . ')';
+ }
+ }
+
+ $methodParams = array();
+ $params = $method->getParameters();
+ foreach ($params as $param) {
+ $paramDef = $this->renderTypeHint($param);
+ $paramDef .= $param->isPassedByReference() ? '&' : '';
+ $paramDef .= $param->isVariadic() ? '...' : '';
+ $paramDef .= '$' . $param->getName();
+
+ if (!$param->isVariadic()) {
+ if (false !== $param->isDefaultValueAvailable()) {
+ $paramDef .= ' = ' . var_export($param->getDefaultValue(), true);
+ } elseif ($param->isOptional()) {
+ $paramDef .= ' = null';
+ }
+ }
+
+ $methodParams[] = $paramDef;
+ }
+ return '(' . implode(', ', $methodParams) . ')';
+ }
+
+ protected function renderReturnType(Method $method)
+ {
+ $type = $method->getReturnType();
+ return $type ? sprintf(': %s', $type) : '';
+ }
+
+ protected function appendToClass($class, $code)
+ {
+ $lastBrace = strrpos($class, "}");
+ $class = substr($class, 0, $lastBrace) . $code . "\n }\n";
+ return $class;
+ }
+
+ protected function renderTypeHint(Parameter $param)
+ {
+ $typeHint = trim($param->getTypeHintAsString());
+
+ if (!empty($typeHint)) {
+ if (!\Mockery::isBuiltInType($typeHint)) {
+ $typeHint = '\\'.$typeHint;
+ }
+
+ if (version_compare(PHP_VERSION, '7.1.0-dev') >= 0 && $param->allowsNull()) {
+ $typeHint = "?".$typeHint;
+ }
+ }
+
+ return $typeHint .= ' ';
+ }
+
+ private function renderMethodBody($method, $config)
+ {
+ $invoke = $method->isStatic() ? 'static::_mockery_handleStaticMethodCall' : '$this->_mockery_handleMethodCall';
+ $body = <<getDeclaringClass();
+ $class_name = strtolower($class->getName());
+ $overrides = $config->getParameterOverrides();
+ if (isset($overrides[$class_name][$method->getName()])) {
+ $params = array_values($overrides[$class_name][$method->getName()]);
+ $paramCount = count($params);
+ for ($i = 0; $i < $paramCount; ++$i) {
+ $param = $params[$i];
+ if (strpos($param, '&') !== false) {
+ $body .= << $i) {
+ \$argv[$i] = {$param};
+}
+
+BODY;
+ }
+ }
+ } else {
+ $params = array_values($method->getParameters());
+ $paramCount = count($params);
+ for ($i = 0; $i < $paramCount; ++$i) {
+ $param = $params[$i];
+ if (!$param->isPassedByReference()) {
+ continue;
+ }
+ $body .= << $i) {
+ \$argv[$i] =& \${$param->getName()};
+}
+
+BODY;
+ }
+ }
+
+ $body .= "\$ret = {$invoke}(__FUNCTION__, \$argv);\n";
+
+ if ($method->getReturnType() !== "void") {
+ $body .= "return \$ret;\n";
+ }
+
+ $body .= "}\n";
+ return $body;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/Pass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/Pass.php
new file mode 100644
index 0000000..f7b72c9
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/Pass.php
@@ -0,0 +1,28 @@
+ '/public function __wakeup\(\)\s+\{.*?\}/sm',
+ );
+
+ public function apply($code, MockConfiguration $config)
+ {
+ $target = $config->getTargetClass();
+
+ if (!$target) {
+ return $code;
+ }
+
+ foreach ($target->getMethods() as $method) {
+ if ($method->isFinal() && isset($this->methods[$method->getName()])) {
+ $code = preg_replace($this->methods[$method->getName()], '', $code);
+ }
+ }
+
+ return $code;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/RemoveDestructorPass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/RemoveDestructorPass.php
new file mode 100644
index 0000000..ed5a420
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/RemoveDestructorPass.php
@@ -0,0 +1,45 @@
+
+ */
+
+namespace Mockery\Generator\StringManipulation\Pass;
+
+use Mockery\Generator\MockConfiguration;
+
+/**
+ * Remove mock's empty destructor if we tend to use original class destructor
+ */
+class RemoveDestructorPass
+{
+ public function apply($code, MockConfiguration $config)
+ {
+ $target = $config->getTargetClass();
+
+ if (!$target) {
+ return $code;
+ }
+
+ if (!$config->isMockOriginalDestructor()) {
+ $code = preg_replace('/public function __destruct\(\)\s+\{.*?\}/sm', '', $code);
+ }
+
+ return $code;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/RemoveUnserializeForInternalSerializableClassesPass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/RemoveUnserializeForInternalSerializableClassesPass.php
new file mode 100644
index 0000000..840fe99
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/RemoveUnserializeForInternalSerializableClassesPass.php
@@ -0,0 +1,58 @@
+getTargetClass();
+
+ if (!$target) {
+ return $code;
+ }
+
+ if (!$target->hasInternalAncestor() || !$target->implementsInterface("Serializable")) {
+ return $code;
+ }
+
+ $code = $this->appendToClass($code, self::DUMMY_METHOD_DEFINITION);
+
+ return $code;
+ }
+
+ protected function appendToClass($class, $code)
+ {
+ $lastBrace = strrpos($class, "}");
+ $class = substr($class, 0, $lastBrace) . $code . "\n }\n";
+ return $class;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/TraitPass.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/TraitPass.php
new file mode 100644
index 0000000..13343c3
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulation/Pass/TraitPass.php
@@ -0,0 +1,47 @@
+getTargetTraits();
+
+ if (empty($traits)) {
+ return $code;
+ }
+
+ $useStatements = array_map(function ($trait) {
+ return "use \\\\".ltrim($trait->getName(), "\\").";";
+ }, $traits);
+
+ $code = preg_replace(
+ '/^{$/m',
+ "{\n ".implode("\n ", $useStatements)."\n",
+ $code
+ );
+
+ return $code;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/StringManipulationGenerator.php b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulationGenerator.php
new file mode 100644
index 0000000..544bb88
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/StringManipulationGenerator.php
@@ -0,0 +1,87 @@
+passes = $passes;
+ }
+
+ public function generate(MockConfiguration $config)
+ {
+ $code = file_get_contents(__DIR__ . '/../Mock.php');
+ $className = $config->getName() ?: $config->generateName();
+
+ $namedConfig = $config->rename($className);
+
+ foreach ($this->passes as $pass) {
+ $code = $pass->apply($code, $namedConfig);
+ }
+
+ return new MockDefinition($namedConfig, $code);
+ }
+
+ public function addPass(Pass $pass)
+ {
+ $this->passes[] = $pass;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Generator/TargetClassInterface.php b/vendor/mockery/mockery/library/Mockery/Generator/TargetClassInterface.php
new file mode 100644
index 0000000..7724412
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Generator/TargetClassInterface.php
@@ -0,0 +1,107 @@
+name = $name;
+ }
+
+ public static function factory($name)
+ {
+ return new self($name);
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function isAbstract()
+ {
+ return false;
+ }
+
+ public function isFinal()
+ {
+ return false;
+ }
+
+ public function getMethods()
+ {
+ return array();
+ }
+
+ public function getInterfaces()
+ {
+ return array();
+ }
+
+ public function getNamespaceName()
+ {
+ $parts = explode("\\", ltrim($this->getName(), "\\"));
+ array_pop($parts);
+ return implode("\\", $parts);
+ }
+
+ public function inNamespace()
+ {
+ return $this->getNamespaceName() !== '';
+ }
+
+ public function getShortName()
+ {
+ $parts = explode("\\", $this->getName());
+ return array_pop($parts);
+ }
+
+ public function implementsInterface($interface)
+ {
+ return false;
+ }
+
+ public function hasInternalAncestor()
+ {
+ return false;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/HigherOrderMessage.php b/vendor/mockery/mockery/library/Mockery/HigherOrderMessage.php
new file mode 100644
index 0000000..1c13c89
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/HigherOrderMessage.php
@@ -0,0 +1,49 @@
+mock = $mock;
+ $this->method = $method;
+ }
+
+ /**
+ * @return \Mockery\Expectation
+ */
+ public function __call($method, $args)
+ {
+ if ($this->method === 'shouldNotHaveReceived') {
+ return $this->mock->{$this->method}($method, $args);
+ }
+
+ $expectation = $this->mock->{$this->method}($method);
+ return $expectation->withArgs($args);
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Instantiator.php b/vendor/mockery/mockery/library/Mockery/Instantiator.php
new file mode 100644
index 0000000..0e2c464
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Instantiator.php
@@ -0,0 +1,209 @@
+.
+ */
+
+namespace Mockery;
+
+use Closure;
+use ReflectionClass;
+use UnexpectedValueException;
+use InvalidArgumentException;
+
+/**
+ * This is a trimmed down version of https://github.com/doctrine/instantiator,
+ * basically without the caching
+ *
+ * @author Marco Pivetta
+ */
+final class Instantiator
+{
+ /**
+ * Markers used internally by PHP to define whether {@see \unserialize} should invoke
+ * the method {@see \Serializable::unserialize()} when dealing with classes implementing
+ * the {@see \Serializable} interface.
+ */
+ const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C';
+ const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O';
+
+ /**
+ * {@inheritDoc}
+ */
+ public function instantiate($className)
+ {
+ $factory = $this->buildFactory($className);
+ $instance = $factory();
+
+ return $instance;
+ }
+
+ /**
+ * @internal
+ * @private
+ *
+ * Builds a {@see \Closure} capable of instantiating the given $className without
+ * invoking its constructor.
+ * This method is only exposed as public because of PHP 5.3 compatibility. Do not
+ * use this method in your own code
+ *
+ * @param string $className
+ *
+ * @return Closure
+ */
+ public function buildFactory($className)
+ {
+ $reflectionClass = $this->getReflectionClass($className);
+
+ if ($this->isInstantiableViaReflection($reflectionClass)) {
+ return function () use ($reflectionClass) {
+ return $reflectionClass->newInstanceWithoutConstructor();
+ };
+ }
+
+ $serializedString = sprintf(
+ '%s:%d:"%s":0:{}',
+ $this->getSerializationFormat($reflectionClass),
+ strlen($className),
+ $className
+ );
+
+ $this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
+
+ return function () use ($serializedString) {
+ return unserialize($serializedString);
+ };
+ }
+
+ /**
+ * @param string $className
+ *
+ * @return ReflectionClass
+ *
+ * @throws InvalidArgumentException
+ */
+ private function getReflectionClass($className)
+ {
+ if (! class_exists($className)) {
+ throw new InvalidArgumentException("Class:$className does not exist");
+ }
+
+ $reflection = new ReflectionClass($className);
+
+ if ($reflection->isAbstract()) {
+ throw new InvalidArgumentException("Class:$className is an abstract class");
+ }
+
+ return $reflection;
+ }
+
+ /**
+ * @param ReflectionClass $reflectionClass
+ * @param string $serializedString
+ *
+ * @throws UnexpectedValueException
+ *
+ * @return void
+ */
+ private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString)
+ {
+ set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) {
+ $msg = sprintf(
+ 'Could not produce an instance of "%s" via un-serialization, since an error was triggered in file "%s" at line "%d"',
+ $reflectionClass->getName(),
+ $file,
+ $line
+ );
+
+ $error = new UnexpectedValueException($msg, 0, new \Exception($message, $code));
+ });
+
+ try {
+ unserialize($serializedString);
+ } catch (\Exception $exception) {
+ restore_error_handler();
+
+ throw new UnexpectedValueException("An exception was raised while trying to instantiate an instance of \"{$reflectionClass->getName()}\" via un-serialization", 0, $exception);
+ }
+
+ restore_error_handler();
+
+ if ($error) {
+ throw $error;
+ }
+ }
+
+ /**
+ * @param ReflectionClass $reflectionClass
+ *
+ * @return bool
+ */
+ private function isInstantiableViaReflection(ReflectionClass $reflectionClass)
+ {
+ return ! ($reflectionClass->isInternal() && $reflectionClass->isFinal());
+ }
+
+ /**
+ * Verifies whether the given class is to be considered internal
+ *
+ * @param ReflectionClass $reflectionClass
+ *
+ * @return bool
+ */
+ private function hasInternalAncestors(ReflectionClass $reflectionClass)
+ {
+ do {
+ if ($reflectionClass->isInternal()) {
+ return true;
+ }
+ } while ($reflectionClass = $reflectionClass->getParentClass());
+
+ return false;
+ }
+
+ /**
+ * Verifies if the given PHP version implements the `Serializable` interface serialization
+ * with an incompatible serialization format. If that's the case, use serialization marker
+ * "C" instead of "O".
+ *
+ * @link http://news.php.net/php.internals/74654
+ *
+ * @param ReflectionClass $reflectionClass
+ *
+ * @return string the serialization format marker, either self::SERIALIZATION_FORMAT_USE_UNSERIALIZER
+ * or self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER
+ */
+ private function getSerializationFormat(ReflectionClass $reflectionClass)
+ {
+ if ($this->isPhpVersionWithBrokenSerializationFormat()
+ && $reflectionClass->implementsInterface('Serializable')
+ ) {
+ return self::SERIALIZATION_FORMAT_USE_UNSERIALIZER;
+ }
+
+ return self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER;
+ }
+
+ /**
+ * Checks whether the current PHP runtime uses an incompatible serialization format
+ *
+ * @return bool
+ */
+ private function isPhpVersionWithBrokenSerializationFormat()
+ {
+ return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php b/vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php
new file mode 100644
index 0000000..e5f78a2
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php
@@ -0,0 +1,36 @@
+getClassName(), false)) {
+ return;
+ }
+
+ eval("?>" . $definition->getCode());
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Loader/Loader.php b/vendor/mockery/mockery/library/Mockery/Loader/Loader.php
new file mode 100644
index 0000000..170ffb6
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Loader/Loader.php
@@ -0,0 +1,28 @@
+path = realpath($path) ?: sys_get_temp_dir();
+ }
+
+ public function load(MockDefinition $definition)
+ {
+ if (class_exists($definition->getClassName(), false)) {
+ return;
+ }
+
+ $tmpfname = $this->path.DIRECTORY_SEPARATOR."Mockery_".uniqid().".php";
+ file_put_contents($tmpfname, $definition->getCode());
+
+ require $tmpfname;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/AndAnyOtherArgs.php b/vendor/mockery/mockery/library/Mockery/Matcher/AndAnyOtherArgs.php
new file mode 100644
index 0000000..e3c3b94
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/AndAnyOtherArgs.php
@@ -0,0 +1,45 @@
+';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/Any.php b/vendor/mockery/mockery/library/Mockery/Matcher/Any.php
new file mode 100644
index 0000000..1ff440b
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/Any.php
@@ -0,0 +1,45 @@
+';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/AnyArgs.php b/vendor/mockery/mockery/library/Mockery/Matcher/AnyArgs.php
new file mode 100644
index 0000000..9663a76
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/AnyArgs.php
@@ -0,0 +1,40 @@
+';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/AnyOf.php b/vendor/mockery/mockery/library/Mockery/Matcher/AnyOf.php
new file mode 100644
index 0000000..bcce4b7
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/AnyOf.php
@@ -0,0 +1,46 @@
+_expected, true);
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/ArgumentListMatcher.php b/vendor/mockery/mockery/library/Mockery/Matcher/ArgumentListMatcher.php
new file mode 100644
index 0000000..04408f5
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/ArgumentListMatcher.php
@@ -0,0 +1,25 @@
+_expected;
+ $result = $closure($actual);
+ return $result === true;
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/Contains.php b/vendor/mockery/mockery/library/Mockery/Matcher/Contains.php
new file mode 100644
index 0000000..79afb73
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/Contains.php
@@ -0,0 +1,64 @@
+_expected as $exp) {
+ $match = false;
+ foreach ($values as $val) {
+ if ($exp === $val || $exp == $val) {
+ $match = true;
+ break;
+ }
+ }
+ if ($match === false) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $return = '_expected as $v) {
+ $elements[] = (string) $v;
+ }
+ $return .= implode(', ', $elements) . ']>';
+ return $return;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/Ducktype.php b/vendor/mockery/mockery/library/Mockery/Matcher/Ducktype.php
new file mode 100644
index 0000000..291f422
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/Ducktype.php
@@ -0,0 +1,53 @@
+_expected as $method) {
+ if (!method_exists($actual, $method)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '_expected) . ']>';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/HasKey.php b/vendor/mockery/mockery/library/Mockery/Matcher/HasKey.php
new file mode 100644
index 0000000..fa983ea
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/HasKey.php
@@ -0,0 +1,45 @@
+_expected, $actual);
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "_expected]>";
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/HasValue.php b/vendor/mockery/mockery/library/Mockery/Matcher/HasValue.php
new file mode 100644
index 0000000..8ca6afd
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/HasValue.php
@@ -0,0 +1,46 @@
+_expected, $actual);
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $return = '_expected . ']>';
+ return $return;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/MatcherAbstract.php b/vendor/mockery/mockery/library/Mockery/Matcher/MatcherAbstract.php
new file mode 100644
index 0000000..3233079
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/MatcherAbstract.php
@@ -0,0 +1,58 @@
+_expected = $expected;
+ }
+
+ /**
+ * Check if the actual value matches the expected.
+ * Actual passed by reference to preserve reference trail (where applicable)
+ * back to the original method parameter.
+ *
+ * @param mixed $actual
+ * @return bool
+ */
+ abstract public function match(&$actual);
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ abstract public function __toString();
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/MultiArgumentClosure.php b/vendor/mockery/mockery/library/Mockery/Matcher/MultiArgumentClosure.php
new file mode 100644
index 0000000..8f00a89
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/MultiArgumentClosure.php
@@ -0,0 +1,49 @@
+_expected;
+ return true === call_user_func_array($closure, $actual);
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/MustBe.php b/vendor/mockery/mockery/library/Mockery/Matcher/MustBe.php
new file mode 100644
index 0000000..27b5ec5
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/MustBe.php
@@ -0,0 +1,52 @@
+_expected === $actual;
+ }
+
+ return $this->_expected == $actual;
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/NoArgs.php b/vendor/mockery/mockery/library/Mockery/Matcher/NoArgs.php
new file mode 100644
index 0000000..5e9e418
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/NoArgs.php
@@ -0,0 +1,40 @@
+';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/Not.php b/vendor/mockery/mockery/library/Mockery/Matcher/Not.php
new file mode 100644
index 0000000..756ccaa
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/Not.php
@@ -0,0 +1,46 @@
+_expected;
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/NotAnyOf.php b/vendor/mockery/mockery/library/Mockery/Matcher/NotAnyOf.php
new file mode 100644
index 0000000..cd82701
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/NotAnyOf.php
@@ -0,0 +1,51 @@
+_expected as $exp) {
+ if ($actual === $exp || $actual == $exp) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/PHPUnitConstraint.php b/vendor/mockery/mockery/library/Mockery/Matcher/PHPUnitConstraint.php
new file mode 100644
index 0000000..a9aaf4c
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/PHPUnitConstraint.php
@@ -0,0 +1,76 @@
+constraint = $constraint;
+ $this->rethrow = $rethrow;
+ }
+
+ /**
+ * @param mixed $actual
+ * @return bool
+ */
+ public function match(&$actual)
+ {
+ try {
+ $this->constraint->evaluate($actual);
+ return true;
+ } catch (\PHPUnit_Framework_AssertionFailedError $e) {
+ if ($this->rethrow) {
+ throw $e;
+ }
+ return false;
+ } catch (\PHPUnit\Framework\AssertionFailedError $e) {
+ if ($this->rethrow) {
+ throw $e;
+ }
+ return false;
+ }
+ }
+
+ /**
+ *
+ */
+ public function __toString()
+ {
+ return '';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/Pattern.php b/vendor/mockery/mockery/library/Mockery/Matcher/Pattern.php
new file mode 100644
index 0000000..362c366
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/Pattern.php
@@ -0,0 +1,45 @@
+_expected, (string) $actual) >= 1;
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/Subset.php b/vendor/mockery/mockery/library/Mockery/Matcher/Subset.php
new file mode 100644
index 0000000..5e706c8
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/Subset.php
@@ -0,0 +1,92 @@
+expected = $expected;
+ $this->strict = $strict;
+ }
+
+ /**
+ * @param array $expected Expected subset of data
+ *
+ * @return Subset
+ */
+ public static function strict(array $expected)
+ {
+ return new static($expected, true);
+ }
+
+ /**
+ * @param array $expected Expected subset of data
+ *
+ * @return Subset
+ */
+ public static function loose(array $expected)
+ {
+ return new static($expected, false);
+ }
+
+ /**
+ * Check if the actual value matches the expected.
+ *
+ * @param mixed $actual
+ * @return bool
+ */
+ public function match(&$actual)
+ {
+ if (!is_array($actual)) {
+ return false;
+ }
+
+ if ($this->strict) {
+ return $actual === array_replace_recursive($actual, $this->expected);
+ }
+
+ return $actual == array_replace_recursive($actual, $this->expected);
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $return = 'expected as $k=>$v) {
+ $elements[] = $k . '=' . (string) $v;
+ }
+ $return .= implode(', ', $elements) . ']>';
+ return $return;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Matcher/Type.php b/vendor/mockery/mockery/library/Mockery/Matcher/Type.php
new file mode 100644
index 0000000..dc189ab
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Matcher/Type.php
@@ -0,0 +1,52 @@
+_expected);
+ if (function_exists($function)) {
+ return $function($actual);
+ } elseif (is_string($this->_expected)
+ && (class_exists($this->_expected) || interface_exists($this->_expected))) {
+ return $actual instanceof $this->_expected;
+ }
+ return false;
+ }
+
+ /**
+ * Return a string representation of this Matcher
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '<' . ucfirst($this->_expected) . '>';
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/MethodCall.php b/vendor/mockery/mockery/library/Mockery/MethodCall.php
new file mode 100644
index 0000000..db68fd8
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/MethodCall.php
@@ -0,0 +1,43 @@
+method = $method;
+ $this->args = $args;
+ }
+
+ public function getMethod()
+ {
+ return $this->method;
+ }
+
+ public function getArgs()
+ {
+ return $this->args;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Mock.php b/vendor/mockery/mockery/library/Mockery/Mock.php
new file mode 100644
index 0000000..cf0aa13
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Mock.php
@@ -0,0 +1,935 @@
+_mockery_container = $container;
+ if (!is_null($partialObject)) {
+ $this->_mockery_partial = $partialObject;
+ }
+
+ if (!\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed()) {
+ foreach ($this->mockery_getMethods() as $method) {
+ if ($method->isPublic() && !$method->isStatic()) {
+ $this->_mockery_mockableMethods[] = $method->getName();
+ }
+ }
+ }
+ }
+
+ /**
+ * Set expected method calls
+ *
+ * @param array ...$methodNames one or many methods that are expected to be called in this mock
+ *
+ * @return \Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\HigherOrderMessage
+ */
+ public function shouldReceive(...$methodNames)
+ {
+ if (count($methodNames) === 0) {
+ return new HigherOrderMessage($this, "shouldReceive");
+ }
+
+ foreach ($methodNames as $method) {
+ if ("" == $method) {
+ throw new \InvalidArgumentException("Received empty method name");
+ }
+ }
+
+ $self = $this;
+ $allowMockingProtectedMethods = $this->_mockery_allowMockingProtectedMethods;
+
+ $lastExpectation = \Mockery::parseShouldReturnArgs(
+ $this, $methodNames, function ($method) use ($self, $allowMockingProtectedMethods) {
+ $rm = $self->mockery_getMethod($method);
+ if ($rm) {
+ if ($rm->isPrivate()) {
+ throw new \InvalidArgumentException("$method() cannot be mocked as it is a private method");
+ }
+ if (!$allowMockingProtectedMethods && $rm->isProtected()) {
+ throw new \InvalidArgumentException("$method() cannot be mocked as it is a protected method and mocking protected methods is not enabled for the currently used mock object. Use shouldAllowMockingProtectedMethods() to enable mocking of protected methods.");
+ }
+ }
+
+ $director = $self->mockery_getExpectationsFor($method);
+ if (!$director) {
+ $director = new \Mockery\ExpectationDirector($method, $self);
+ $self->mockery_setExpectationsFor($method, $director);
+ }
+ $expectation = new \Mockery\Expectation($self, $method);
+ $director->addExpectation($expectation);
+ return $expectation;
+ }
+ );
+ return $lastExpectation;
+ }
+
+ /**
+ * @param mixed $something String method name or map of method => return
+ * @return self|\Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\HigherOrderMessage
+ */
+ public function allows($something = [])
+ {
+ if (is_string($something)) {
+ return $this->shouldReceive($something);
+ }
+
+ if (empty($something)) {
+ return $this->shouldReceive();
+ }
+
+ foreach ($something as $method => $returnValue) {
+ $this->shouldReceive($method)->andReturn($returnValue);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param mixed $something String method name (optional)
+ * @return \Mockery\ExpectationInterface|\Mockery\Expectation|ExpectsHigherOrderMessage
+ */
+ public function expects($something = null)
+ {
+ if (is_string($something)) {
+ return $this->shouldReceive($something)->once();
+ }
+
+ return new ExpectsHigherOrderMessage($this);
+ }
+
+ /**
+ * Shortcut method for setting an expectation that a method should not be called.
+ *
+ * @param array ...$methodNames one or many methods that are expected not to be called in this mock
+ * @return \Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\HigherOrderMessage
+ */
+ public function shouldNotReceive(...$methodNames)
+ {
+ if (count($methodNames) === 0) {
+ return new HigherOrderMessage($this, "shouldNotReceive");
+ }
+
+ $expectation = call_user_func_array(array($this, 'shouldReceive'), $methodNames);
+ $expectation->never();
+ return $expectation;
+ }
+
+ /**
+ * Allows additional methods to be mocked that do not explicitly exist on mocked class
+ * @param String $method name of the method to be mocked
+ * @return Mock
+ */
+ public function shouldAllowMockingMethod($method)
+ {
+ $this->_mockery_mockableMethods[] = $method;
+ return $this;
+ }
+
+ /**
+ * Set mock to ignore unexpected methods and return Undefined class
+ * @param mixed $returnValue the default return value for calls to missing functions on this mock
+ * @return Mock
+ */
+ public function shouldIgnoreMissing($returnValue = null)
+ {
+ $this->_mockery_ignoreMissing = true;
+ $this->_mockery_defaultReturnValue = $returnValue;
+ return $this;
+ }
+
+ public function asUndefined()
+ {
+ $this->_mockery_ignoreMissing = true;
+ $this->_mockery_defaultReturnValue = new \Mockery\Undefined;
+ return $this;
+ }
+
+ /**
+ * @return Mock
+ */
+ public function shouldAllowMockingProtectedMethods()
+ {
+ $this->_mockery_allowMockingProtectedMethods = true;
+ return $this;
+ }
+
+
+ /**
+ * Set mock to defer unexpected methods to it's parent
+ *
+ * This is particularly useless for this class, as it doesn't have a parent,
+ * but included for completeness
+ *
+ * @deprecated 2.0.0 Please use makePartial() instead
+ *
+ * @return Mock
+ */
+ public function shouldDeferMissing()
+ {
+ return $this->makePartial();
+ }
+
+ /**
+ * Set mock to defer unexpected methods to it's parent
+ *
+ * It was an alias for shouldDeferMissing(), which will be removed
+ * in 2.0.0.
+ *
+ * @return Mock
+ */
+ public function makePartial()
+ {
+ $this->_mockery_deferMissing = true;
+ return $this;
+ }
+
+ /**
+ * In the event shouldReceive() accepting one or more methods/returns,
+ * this method will switch them from normal expectations to default
+ * expectations
+ *
+ * @return self
+ */
+ public function byDefault()
+ {
+ foreach ($this->_mockery_expectations as $director) {
+ $exps = $director->getExpectations();
+ foreach ($exps as $exp) {
+ $exp->byDefault();
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Capture calls to this mock
+ */
+ public function __call($method, array $args)
+ {
+ return $this->_mockery_handleMethodCall($method, $args);
+ }
+
+ public static function __callStatic($method, array $args)
+ {
+ return self::_mockery_handleStaticMethodCall($method, $args);
+ }
+
+ /**
+ * Forward calls to this magic method to the __call method
+ */
+ public function __toString()
+ {
+ return $this->__call('__toString', array());
+ }
+
+ /**
+ * Iterate across all expectation directors and validate each
+ *
+ * @throws \Mockery\CountValidator\Exception
+ * @return void
+ */
+ public function mockery_verify()
+ {
+ if ($this->_mockery_verified) {
+ return;
+ }
+ if (isset($this->_mockery_ignoreVerification)
+ && $this->_mockery_ignoreVerification == true) {
+ return;
+ }
+ $this->_mockery_verified = true;
+ foreach ($this->_mockery_expectations as $director) {
+ $director->verify();
+ }
+ }
+
+ /**
+ * Gets a list of exceptions thrown by this mock
+ *
+ * @return array
+ */
+ public function mockery_thrownExceptions()
+ {
+ return $this->_mockery_thrownExceptions;
+ }
+
+ /**
+ * Tear down tasks for this mock
+ *
+ * @return void
+ */
+ public function mockery_teardown()
+ {
+ }
+
+ /**
+ * Fetch the next available allocation order number
+ *
+ * @return int
+ */
+ public function mockery_allocateOrder()
+ {
+ $this->_mockery_allocatedOrder += 1;
+ return $this->_mockery_allocatedOrder;
+ }
+
+ /**
+ * Set ordering for a group
+ *
+ * @param mixed $group
+ * @param int $order
+ */
+ public function mockery_setGroup($group, $order)
+ {
+ $this->_mockery_groups[$group] = $order;
+ }
+
+ /**
+ * Fetch array of ordered groups
+ *
+ * @return array
+ */
+ public function mockery_getGroups()
+ {
+ return $this->_mockery_groups;
+ }
+
+ /**
+ * Set current ordered number
+ *
+ * @param int $order
+ */
+ public function mockery_setCurrentOrder($order)
+ {
+ $this->_mockery_currentOrder = $order;
+ return $this->_mockery_currentOrder;
+ }
+
+ /**
+ * Get current ordered number
+ *
+ * @return int
+ */
+ public function mockery_getCurrentOrder()
+ {
+ return $this->_mockery_currentOrder;
+ }
+
+ /**
+ * Validate the current mock's ordering
+ *
+ * @param string $method
+ * @param int $order
+ * @throws \Mockery\Exception
+ * @return void
+ */
+ public function mockery_validateOrder($method, $order)
+ {
+ if ($order < $this->_mockery_currentOrder) {
+ $exception = new \Mockery\Exception\InvalidOrderException(
+ 'Method ' . __CLASS__ . '::' . $method . '()'
+ . ' called out of order: expected order '
+ . $order . ', was ' . $this->_mockery_currentOrder
+ );
+ $exception->setMock($this)
+ ->setMethodName($method)
+ ->setExpectedOrder($order)
+ ->setActualOrder($this->_mockery_currentOrder);
+ throw $exception;
+ }
+ $this->mockery_setCurrentOrder($order);
+ }
+
+ /**
+ * Gets the count of expectations for this mock
+ *
+ * @return int
+ */
+ public function mockery_getExpectationCount()
+ {
+ $count = $this->_mockery_expectations_count;
+ foreach ($this->_mockery_expectations as $director) {
+ $count += $director->getExpectationCount();
+ }
+ return $count;
+ }
+
+ /**
+ * Return the expectations director for the given method
+ *
+ * @var string $method
+ * @return \Mockery\ExpectationDirector|null
+ */
+ public function mockery_setExpectationsFor($method, \Mockery\ExpectationDirector $director)
+ {
+ $this->_mockery_expectations[$method] = $director;
+ }
+
+ /**
+ * Return the expectations director for the given method
+ *
+ * @var string $method
+ * @return \Mockery\ExpectationDirector|null
+ */
+ public function mockery_getExpectationsFor($method)
+ {
+ if (isset($this->_mockery_expectations[$method])) {
+ return $this->_mockery_expectations[$method];
+ }
+ }
+
+ /**
+ * Find an expectation matching the given method and arguments
+ *
+ * @var string $method
+ * @var array $args
+ * @return \Mockery\Expectation|null
+ */
+ public function mockery_findExpectation($method, array $args)
+ {
+ if (!isset($this->_mockery_expectations[$method])) {
+ return null;
+ }
+ $director = $this->_mockery_expectations[$method];
+
+ return $director->findExpectation($args);
+ }
+
+ /**
+ * Return the container for this mock
+ *
+ * @return \Mockery\Container
+ */
+ public function mockery_getContainer()
+ {
+ return $this->_mockery_container;
+ }
+
+ /**
+ * Return the name for this mock
+ *
+ * @return string
+ */
+ public function mockery_getName()
+ {
+ return __CLASS__;
+ }
+
+ /**
+ * @return array
+ */
+ public function mockery_getMockableProperties()
+ {
+ return $this->_mockery_mockableProperties;
+ }
+
+ public function __isset($name)
+ {
+ if (false === stripos($name, '_mockery_') && method_exists(get_parent_class($this), '__isset')) {
+ return parent::__isset($name);
+ }
+
+ return false;
+ }
+
+ public function mockery_getExpectations()
+ {
+ return $this->_mockery_expectations;
+ }
+
+ /**
+ * Calls a parent class method and returns the result. Used in a passthru
+ * expectation where a real return value is required while still taking
+ * advantage of expectation matching and call count verification.
+ *
+ * @param string $name
+ * @param array $args
+ * @return mixed
+ */
+ public function mockery_callSubjectMethod($name, array $args)
+ {
+ return call_user_func_array('parent::' . $name, $args);
+ }
+
+ /**
+ * @return string[]
+ */
+ public function mockery_getMockableMethods()
+ {
+ return $this->_mockery_mockableMethods;
+ }
+
+ /**
+ * @return bool
+ */
+ public function mockery_isAnonymous()
+ {
+ $rfc = new \ReflectionClass($this);
+
+ // HHVM has a Stringish interface
+ $interfaces = array_filter($rfc->getInterfaces(), function ($i) {
+ return $i->getName() !== "Stringish";
+ });
+ $onlyImplementsMock = 1 == count($interfaces);
+
+ return (false === $rfc->getParentClass()) && $onlyImplementsMock;
+ }
+
+ public function __wakeup()
+ {
+ /**
+ * This does not add __wakeup method support. It's a blind method and any
+ * expected __wakeup work will NOT be performed. It merely cuts off
+ * annoying errors where a __wakeup exists but is not essential when
+ * mocking
+ */
+ }
+
+ public function __destruct()
+ {
+ /**
+ * Overrides real class destructor in case if class was created without original constructor
+ */
+ }
+
+ public function mockery_getMethod($name)
+ {
+ foreach ($this->mockery_getMethods() as $method) {
+ if ($method->getName() == $name) {
+ return $method;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param string $name Method name.
+ *
+ * @return mixed Generated return value based on the declared return value of the named method.
+ */
+ public function mockery_returnValueForMethod($name)
+ {
+ if (version_compare(PHP_VERSION, '7.0.0-dev') < 0) {
+ return;
+ }
+
+ $rm = $this->mockery_getMethod($name);
+ if (!$rm || !$rm->hasReturnType()) {
+ return;
+ }
+
+ $returnType = $rm->getReturnType();
+
+ // Default return value for methods with nullable type is null
+ if ($returnType->allowsNull()) {
+ return null;
+ }
+
+ $type = (string) $returnType;
+ switch ($type) {
+ case '': return;
+ case 'string': return '';
+ case 'int': return 0;
+ case 'float': return 0.0;
+ case 'bool': return false;
+ case 'array': return [];
+
+ case 'callable':
+ case 'Closure':
+ return function () {
+ };
+
+ case 'Traversable':
+ case 'Generator':
+ // Remove eval() when minimum version >=5.5
+ $generator = eval('return function () { yield; };');
+ return $generator();
+
+ case 'self':
+ return \Mockery::mock($rm->getDeclaringClass()->getName());
+
+ case 'void':
+ return null;
+
+ case 'object':
+ if (version_compare(PHP_VERSION, '7.2.0-dev') >= 0) {
+ return \Mockery::mock();
+ }
+
+ default:
+ return \Mockery::mock($type);
+ }
+ }
+
+ public function shouldHaveReceived($method = null, $args = null)
+ {
+ if ($method === null) {
+ return new HigherOrderMessage($this, "shouldHaveReceived");
+ }
+
+ $expectation = new \Mockery\VerificationExpectation($this, $method);
+ if (null !== $args) {
+ $expectation->withArgs($args);
+ }
+ $expectation->atLeast()->once();
+ $director = new \Mockery\VerificationDirector($this->_mockery_getReceivedMethodCalls(), $expectation);
+ $this->_mockery_expectations_count++;
+ $director->verify();
+ return $director;
+ }
+
+ public function shouldHaveBeenCalled()
+ {
+ return $this->shouldHaveReceived("__invoke");
+ }
+
+ public function shouldNotHaveReceived($method = null, $args = null)
+ {
+ if ($method === null) {
+ return new HigherOrderMessage($this, "shouldNotHaveReceived");
+ }
+
+ $expectation = new \Mockery\VerificationExpectation($this, $method);
+ if (null !== $args) {
+ $expectation->withArgs($args);
+ }
+ $expectation->never();
+ $director = new \Mockery\VerificationDirector($this->_mockery_getReceivedMethodCalls(), $expectation);
+ $this->_mockery_expectations_count++;
+ $director->verify();
+ return null;
+ }
+
+ public function shouldNotHaveBeenCalled(array $args = null)
+ {
+ return $this->shouldNotHaveReceived("__invoke", $args);
+ }
+
+ protected static function _mockery_handleStaticMethodCall($method, array $args)
+ {
+ $associatedRealObject = \Mockery::fetchMock(__CLASS__);
+ try {
+ return $associatedRealObject->__call($method, $args);
+ } catch (BadMethodCallException $e) {
+ throw new BadMethodCallException(
+ 'Static method ' . $associatedRealObject->mockery_getName() . '::' . $method
+ . '() does not exist on this mock object',
+ null,
+ $e
+ );
+ }
+ }
+
+ protected function _mockery_getReceivedMethodCalls()
+ {
+ return $this->_mockery_receivedMethodCalls ?: $this->_mockery_receivedMethodCalls = new \Mockery\ReceivedMethodCalls();
+ }
+
+ /**
+ * Called when an instance Mock was created and its constructor is getting called
+ *
+ * @see \Mockery\Generator\StringManipulation\Pass\InstanceMockPass
+ * @param array $args
+ */
+ protected function _mockery_constructorCalled(array $args)
+ {
+ if (!isset($this->_mockery_expectations['__construct']) /* _mockery_handleMethodCall runs the other checks */) {
+ return;
+ }
+ $this->_mockery_handleMethodCall('__construct', $args);
+ }
+
+ protected function _mockery_findExpectedMethodHandler($method)
+ {
+ if (isset($this->_mockery_expectations[$method])) {
+ return $this->_mockery_expectations[$method];
+ }
+
+ $lowerCasedMockeryExpectations = array_change_key_case($this->_mockery_expectations, CASE_LOWER);
+ $lowerCasedMethod = strtolower($method);
+
+ if (isset($lowerCasedMockeryExpectations[$lowerCasedMethod])) {
+ return $lowerCasedMockeryExpectations[$lowerCasedMethod];
+ }
+
+ return null;
+ }
+
+ protected function _mockery_handleMethodCall($method, array $args)
+ {
+ $this->_mockery_getReceivedMethodCalls()->push(new \Mockery\MethodCall($method, $args));
+
+ $rm = $this->mockery_getMethod($method);
+ if ($rm && $rm->isProtected() && !$this->_mockery_allowMockingProtectedMethods) {
+ if ($rm->isAbstract()) {
+ return;
+ }
+
+ try {
+ $prototype = $rm->getPrototype();
+ if ($prototype->isAbstract()) {
+ return;
+ }
+ } catch (\ReflectionException $re) {
+ // noop - there is no hasPrototype method
+ }
+
+ return call_user_func_array("parent::$method", $args);
+ }
+
+ $handler = $this->_mockery_findExpectedMethodHandler($method);
+
+ if ($handler !== null && !$this->_mockery_disableExpectationMatching) {
+ try {
+ return $handler->call($args);
+ } catch (\Mockery\Exception\NoMatchingExpectationException $e) {
+ if (!$this->_mockery_ignoreMissing && !$this->_mockery_deferMissing) {
+ throw $e;
+ }
+ }
+ }
+
+ if (!is_null($this->_mockery_partial) && method_exists($this->_mockery_partial, $method)) {
+ return call_user_func_array(array($this->_mockery_partial, $method), $args);
+ } elseif ($this->_mockery_deferMissing && is_callable("parent::$method")
+ && (!$this->hasMethodOverloadingInParentClass() || method_exists(get_parent_class($this), $method))) {
+ return call_user_func_array("parent::$method", $args);
+ } elseif ($method == '__toString') {
+ // __toString is special because we force its addition to the class API regardless of the
+ // original implementation. Thus, we should always return a string rather than honor
+ // _mockery_ignoreMissing and break the API with an error.
+ return sprintf("%s#%s", __CLASS__, spl_object_hash($this));
+ } elseif ($this->_mockery_ignoreMissing) {
+ if (\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed() || (method_exists($this->_mockery_partial, $method) || is_callable("parent::$method"))) {
+ if ($this->_mockery_defaultReturnValue instanceof \Mockery\Undefined) {
+ return call_user_func_array(array($this->_mockery_defaultReturnValue, $method), $args);
+ } elseif (null === $this->_mockery_defaultReturnValue) {
+ return $this->mockery_returnValueForMethod($method);
+ }
+
+ return $this->_mockery_defaultReturnValue;
+ }
+ }
+
+ $message = 'Method ' . __CLASS__ . '::' . $method .
+ '() does not exist on this mock object';
+
+ if (!is_null($rm)) {
+ $message = 'Received ' . __CLASS__ .
+ '::' . $method . '(), but no expectations were specified';
+ }
+
+ $bmce = new BadMethodCallException($message);
+ $this->_mockery_thrownExceptions[] = $bmce;
+ throw $bmce;
+ }
+
+ /**
+ * Uses reflection to get the list of all
+ * methods within the current mock object
+ *
+ * @return array
+ */
+ protected function mockery_getMethods()
+ {
+ if (static::$_mockery_methods && \Mockery::getConfiguration()->reflectionCacheEnabled()) {
+ return static::$_mockery_methods;
+ }
+
+ if (isset($this->_mockery_partial)) {
+ $reflected = new \ReflectionObject($this->_mockery_partial);
+ } else {
+ $reflected = new \ReflectionClass($this);
+ }
+
+ return static::$_mockery_methods = $reflected->getMethods();
+ }
+
+ private function hasMethodOverloadingInParentClass()
+ {
+ // if there's __call any name would be callable
+ return is_callable('parent::aFunctionNameThatNoOneWouldEverUseInRealLife12345');
+ }
+
+ /**
+ * @return array
+ */
+ private function getNonPublicMethods()
+ {
+ return array_map(
+ function ($method) {
+ return $method->getName();
+ },
+ array_filter($this->mockery_getMethods(), function ($method) {
+ return !$method->isPublic();
+ })
+ );
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/MockInterface.php b/vendor/mockery/mockery/library/Mockery/MockInterface.php
new file mode 100644
index 0000000..e7a2685
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/MockInterface.php
@@ -0,0 +1,252 @@
+ return
+ * @return self|\Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\HigherOrderMessage
+ */
+ public function allows($something = []);
+
+ /**
+ * @param mixed $something String method name (optional)
+ * @return \Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\ExpectsHigherOrderMessage
+ */
+ public function expects($something = null);
+
+ /**
+ * Alternative setup method to constructor
+ *
+ * @param \Mockery\Container $container
+ * @param object $partialObject
+ * @return void
+ */
+ public function mockery_init(\Mockery\Container $container = null, $partialObject = null);
+
+ /**
+ * Set expected method calls
+ *
+ * @param array ...$methodNames one or many methods that are expected to be called in this mock
+ *
+ * @return \Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\HigherOrderMessage
+ */
+ public function shouldReceive(...$methodNames);
+
+ /**
+ * Shortcut method for setting an expectation that a method should not be called.
+ *
+ * @param array ...$methodNames one or many methods that are expected not to be called in this mock
+ * @return \Mockery\ExpectationInterface|\Mockery\Expectation|\Mockery\HigherOrderMessage
+ */
+ public function shouldNotReceive(...$methodNames);
+
+ /**
+ * Allows additional methods to be mocked that do not explicitly exist on mocked class
+ * @param String $method name of the method to be mocked
+ */
+ public function shouldAllowMockingMethod($method);
+
+ /**
+ * Set mock to ignore unexpected methods and return Undefined class
+ * @param mixed $returnValue the default return value for calls to missing functions on this mock
+ * @return Mock
+ */
+ public function shouldIgnoreMissing($returnValue = null);
+
+ /**
+ * @return Mock
+ */
+ public function shouldAllowMockingProtectedMethods();
+
+ /**
+ * Set mock to defer unexpected methods to its parent if possible
+ *
+ * @deprecated 2.0.0 Please use makePartial() instead
+ *
+ * @return Mock
+ */
+ public function shouldDeferMissing();
+
+ /**
+ * Set mock to defer unexpected methods to its parent if possible
+ *
+ * @return Mock
+ */
+ public function makePartial();
+
+ /**
+ * @param null|string $method
+ * @param null $args
+ * @return mixed
+ */
+ public function shouldHaveReceived($method, $args = null);
+
+ /**
+ * @return mixed
+ */
+ public function shouldHaveBeenCalled();
+
+ /**
+ * @param null|string $method
+ * @param null $args
+ * @return mixed
+ */
+ public function shouldNotHaveReceived($method, $args = null);
+
+ /**
+ * @param array $args (optional)
+ * @return mixed
+ */
+ public function shouldNotHaveBeenCalled(array $args = null);
+
+ /**
+ * In the event shouldReceive() accepting an array of methods/returns
+ * this method will switch them from normal expectations to default
+ * expectations
+ *
+ * @return self
+ */
+ public function byDefault();
+
+ /**
+ * Iterate across all expectation directors and validate each
+ *
+ * @throws \Mockery\CountValidator\Exception
+ * @return void
+ */
+ public function mockery_verify();
+
+ /**
+ * Tear down tasks for this mock
+ *
+ * @return void
+ */
+ public function mockery_teardown();
+
+ /**
+ * Fetch the next available allocation order number
+ *
+ * @return int
+ */
+ public function mockery_allocateOrder();
+
+ /**
+ * Set ordering for a group
+ *
+ * @param mixed $group
+ * @param int $order
+ */
+ public function mockery_setGroup($group, $order);
+
+ /**
+ * Fetch array of ordered groups
+ *
+ * @return array
+ */
+ public function mockery_getGroups();
+
+ /**
+ * Set current ordered number
+ *
+ * @param int $order
+ */
+ public function mockery_setCurrentOrder($order);
+
+ /**
+ * Get current ordered number
+ *
+ * @return int
+ */
+ public function mockery_getCurrentOrder();
+
+ /**
+ * Validate the current mock's ordering
+ *
+ * @param string $method
+ * @param int $order
+ * @throws \Mockery\Exception
+ * @return void
+ */
+ public function mockery_validateOrder($method, $order);
+
+ /**
+ * Gets the count of expectations for this mock
+ *
+ * @return int
+ */
+ public function mockery_getExpectationCount();
+
+ /**
+ * Return the expectations director for the given method
+ *
+ * @var string $method
+ * @return \Mockery\ExpectationDirector|null
+ */
+ public function mockery_setExpectationsFor($method, \Mockery\ExpectationDirector $director);
+
+ /**
+ * Return the expectations director for the given method
+ *
+ * @var string $method
+ * @return \Mockery\ExpectationDirector|null
+ */
+ public function mockery_getExpectationsFor($method);
+
+ /**
+ * Find an expectation matching the given method and arguments
+ *
+ * @var string $method
+ * @var array $args
+ * @return \Mockery\Expectation|null
+ */
+ public function mockery_findExpectation($method, array $args);
+
+ /**
+ * Return the container for this mock
+ *
+ * @return \Mockery\Container
+ */
+ public function mockery_getContainer();
+
+ /**
+ * Return the name for this mock
+ *
+ * @return string
+ */
+ public function mockery_getName();
+
+ /**
+ * @return array
+ */
+ public function mockery_getMockableProperties();
+
+ /**
+ * @return string[]
+ */
+ public function mockery_getMockableMethods();
+
+ /**
+ * @return bool
+ */
+ public function mockery_isAnonymous();
+}
diff --git a/vendor/mockery/mockery/library/Mockery/ReceivedMethodCalls.php b/vendor/mockery/mockery/library/Mockery/ReceivedMethodCalls.php
new file mode 100644
index 0000000..da771c0
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/ReceivedMethodCalls.php
@@ -0,0 +1,48 @@
+methodCalls[] = $methodCall;
+ }
+
+ public function verify(Expectation $expectation)
+ {
+ foreach ($this->methodCalls as $methodCall) {
+ if ($methodCall->getMethod() !== $expectation->getName()) {
+ continue;
+ }
+
+ if (!$expectation->matchArgs($methodCall->getArgs())) {
+ continue;
+ }
+
+ $expectation->verifyCall($methodCall->getArgs());
+ }
+
+ $expectation->verify();
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/Undefined.php b/vendor/mockery/mockery/library/Mockery/Undefined.php
new file mode 100644
index 0000000..53b05e9
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/Undefined.php
@@ -0,0 +1,46 @@
+receivedMethodCalls = $receivedMethodCalls;
+ $this->expectation = $expectation;
+ }
+
+ public function verify()
+ {
+ return $this->receivedMethodCalls->verify($this->expectation);
+ }
+
+ public function with(...$args)
+ {
+ return $this->cloneApplyAndVerify("with", $args);
+ }
+
+ public function withArgs($args)
+ {
+ return $this->cloneApplyAndVerify("withArgs", array($args));
+ }
+
+ public function withNoArgs()
+ {
+ return $this->cloneApplyAndVerify("withNoArgs", array());
+ }
+
+ public function withAnyArgs()
+ {
+ return $this->cloneApplyAndVerify("withAnyArgs", array());
+ }
+
+ public function times($limit = null)
+ {
+ return $this->cloneWithoutCountValidatorsApplyAndVerify("times", array($limit));
+ }
+
+ public function once()
+ {
+ return $this->cloneWithoutCountValidatorsApplyAndVerify("once", array());
+ }
+
+ public function twice()
+ {
+ return $this->cloneWithoutCountValidatorsApplyAndVerify("twice", array());
+ }
+
+ public function atLeast()
+ {
+ return $this->cloneWithoutCountValidatorsApplyAndVerify("atLeast", array());
+ }
+
+ public function atMost()
+ {
+ return $this->cloneWithoutCountValidatorsApplyAndVerify("atMost", array());
+ }
+
+ public function between($minimum, $maximum)
+ {
+ return $this->cloneWithoutCountValidatorsApplyAndVerify("between", array($minimum, $maximum));
+ }
+
+ protected function cloneWithoutCountValidatorsApplyAndVerify($method, $args)
+ {
+ $expectation = clone $this->expectation;
+ $expectation->clearCountValidators();
+ call_user_func_array(array($expectation, $method), $args);
+ $director = new VerificationDirector($this->receivedMethodCalls, $expectation);
+ $director->verify();
+ return $director;
+ }
+
+ protected function cloneApplyAndVerify($method, $args)
+ {
+ $expectation = clone $this->expectation;
+ call_user_func_array(array($expectation, $method), $args);
+ $director = new VerificationDirector($this->receivedMethodCalls, $expectation);
+ $director->verify();
+ return $director;
+ }
+}
diff --git a/vendor/mockery/mockery/library/Mockery/VerificationExpectation.php b/vendor/mockery/mockery/library/Mockery/VerificationExpectation.php
new file mode 100644
index 0000000..3844a09
--- /dev/null
+++ b/vendor/mockery/mockery/library/Mockery/VerificationExpectation.php
@@ -0,0 +1,35 @@
+_countValidators = array();
+ }
+
+ public function __clone()
+ {
+ parent::__clone();
+ $this->_actualCount = 0;
+ }
+}
diff --git a/vendor/mockery/mockery/library/helpers.php b/vendor/mockery/mockery/library/helpers.php
new file mode 100644
index 0000000..72b7240
--- /dev/null
+++ b/vendor/mockery/mockery/library/helpers.php
@@ -0,0 +1,66 @@
+
+
+
+
+ ./tests
+ ./tests/PHP70
+ ./tests/PHP72
+
+ ./tests/PHP56
+ ./tests/Mockery/MockingVariadicArgumentsTest.php
+
+
+
+ ./tests
+ ./tests/PHP56
+
+ ./tests/PHP70
+ ./tests/PHP72
+ ./tests/Mockery/MockingVariadicArgumentsTest.php
+
+
+
+
+
+ ./library/
+
+ ./library/Mockery/Adapter/Phpunit/Legacy
+ ./library/Mockery/Adapter/Phpunit/TestListener.php
+
+
+
+
+
diff --git a/vendor/mockery/mockery/tests/Bootstrap.php b/vendor/mockery/mockery/tests/Bootstrap.php
new file mode 100644
index 0000000..5da2f67
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Bootstrap.php
@@ -0,0 +1,66 @@
+checkMockeryExceptions();
+ }
+
+ public function markAsRisky()
+ {
+ }
+};
+
+class MockeryPHPUnitIntegrationTest extends MockeryTestCase
+{
+ /**
+ * @test
+ * @requires PHPUnit 5.7.6
+ */
+ public function it_marks_a_passing_test_as_risky_if_we_threw_exceptions()
+ {
+ $mock = mock();
+ try {
+ $mock->foobar();
+ } catch (\Exception $e) {
+ // exception swallowed...
+ }
+
+ $test = spy(BaseClassStub::class)->makePartial();
+ $test->finish();
+
+ $test->shouldHaveReceived()->markAsRisky();
+ }
+
+ /**
+ * @test
+ * @requires PHPUnit 5.7.6
+ */
+ public function the_user_can_manually_dismiss_an_exception_to_avoid_the_risky_test()
+ {
+ $mock = mock();
+ try {
+ $mock->foobar();
+ } catch (BadMethodCallException $e) {
+ $e->dismiss();
+ }
+
+ $test = spy(BaseClassStub::class)->makePartial();
+ $test->finish();
+
+ $test->shouldNotHaveReceived()->markAsRisky();
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Adapter/Phpunit/TestListenerTest.php b/vendor/mockery/mockery/tests/Mockery/Adapter/Phpunit/TestListenerTest.php
new file mode 100644
index 0000000..9a73c81
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Adapter/Phpunit/TestListenerTest.php
@@ -0,0 +1,103 @@
+markTestSkipped('The TestListener is only supported with PHPUnit 6+.');
+ return;
+ }
+ // We intentionally test the static container here. That is what the
+ // listener will check.
+ $this->container = \Mockery::getContainer();
+ $this->listener = new TestListener();
+ $this->testResult = new TestResult();
+ $this->test = new EmptyTestCase();
+
+ $this->test->setTestResultObject($this->testResult);
+ $this->testResult->addListener($this->listener);
+
+ $this->assertTrue($this->testResult->wasSuccessful(), 'sanity check: empty test results should be considered successful');
+ }
+
+ public function testSuccessOnClose()
+ {
+ $mock = $this->container->mock();
+ $mock->shouldReceive('bar')->once();
+ $mock->bar();
+
+ // This is what MockeryPHPUnitIntegration and MockeryTestCase trait
+ // will do. We intentionally call the static close method.
+ $this->test->addToAssertionCount($this->container->mockery_getExpectationCount());
+ \Mockery::close();
+
+ $this->listener->endTest($this->test, 0);
+ $this->assertTrue($this->testResult->wasSuccessful(), 'expected test result to indicate success');
+ }
+
+ public function testFailureOnMissingClose()
+ {
+ $mock = $this->container->mock();
+ $mock->shouldReceive('bar')->once();
+
+ $this->listener->endTest($this->test, 0);
+ $this->assertFalse($this->testResult->wasSuccessful(), 'expected test result to indicate failure');
+
+ // Satisfy the expectation and close the global container now so we
+ // don't taint the environment.
+ $mock->bar();
+ \Mockery::close();
+ }
+
+ public function testMockeryIsAddedToBlacklist()
+ {
+ $suite = \Mockery::mock(\PHPUnit\Framework\TestSuite::class);
+
+ $this->assertArrayNotHasKey(\Mockery::class, \PHPUnit\Util\Blacklist::$blacklistedClassNames);
+ $this->listener->startTestSuite($suite);
+ $this->assertSame(1, \PHPUnit\Util\Blacklist::$blacklistedClassNames[\Mockery::class]);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/AdhocTest.php b/vendor/mockery/mockery/tests/Mockery/AdhocTest.php
new file mode 100644
index 0000000..b930c0a
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/AdhocTest.php
@@ -0,0 +1,119 @@
+container = new \Mockery\Container(\Mockery::getDefaultGenerator(), \Mockery::getDefaultLoader());
+ }
+
+ public function teardown()
+ {
+ $this->container->mockery_close();
+ }
+
+ public function testSimplestMockCreation()
+ {
+ $m = $this->container->mock('MockeryTest_NameOfExistingClass');
+ $this->assertInstanceOf(MockeryTest_NameOfExistingClass::class, $m);
+ }
+
+ public function testMockeryInterfaceForClass()
+ {
+ $m = $this->container->mock('SplFileInfo');
+ $this->assertInstanceOf(\Mockery\MockInterface::class, $m);
+ }
+
+ public function testMockeryInterfaceForNonExistingClass()
+ {
+ $m = $this->container->mock('ABC_IDontExist');
+ $this->assertInstanceOf(\Mockery\MockInterface::class, $m);
+ }
+
+ public function testMockeryInterfaceForInterface()
+ {
+ $m = $this->container->mock('MockeryTest_NameOfInterface');
+ $this->assertInstanceOf(\Mockery\MockInterface::class, $m);
+ }
+
+ public function testMockeryInterfaceForAbstract()
+ {
+ $m = $this->container->mock('MockeryTest_NameOfAbstract');
+ $this->assertInstanceOf(\Mockery\MockInterface::class, $m);
+ }
+
+ public function testInvalidCountExceptionThrowsRuntimeExceptionOnIllegalComparativeSymbol()
+ {
+ $this->expectException('Mockery\Exception\RuntimeException');
+ $e = new \Mockery\Exception\InvalidCountException;
+ $e->setExpectedCountComparative('X');
+ }
+
+ public function testMockeryConstructAndDestructIsNotCalled()
+ {
+ MockeryTest_NameOfExistingClassWithDestructor::$isDestructorWasCalled = false;
+ // We pass no arguments in constructor, so it's not being called. Then destructor shouldn't be called too.
+ $this->container->mock('MockeryTest_NameOfExistingClassWithDestructor');
+ // Clear references to trigger destructor
+ $this->container->mockery_close();
+ $this->assertFalse(MockeryTest_NameOfExistingClassWithDestructor::$isDestructorWasCalled);
+ }
+
+ public function testMockeryConstructAndDestructIsCalled()
+ {
+ MockeryTest_NameOfExistingClassWithDestructor::$isDestructorWasCalled = false;
+
+ $this->container->mock('MockeryTest_NameOfExistingClassWithDestructor', array());
+ // Clear references to trigger destructor
+ $this->container->mockery_close();
+ $this->assertTrue(MockeryTest_NameOfExistingClassWithDestructor::$isDestructorWasCalled);
+ }
+}
+
+class MockeryTest_NameOfExistingClass
+{
+}
+
+interface MockeryTest_NameOfInterface
+{
+ public function foo();
+}
+
+abstract class MockeryTest_NameOfAbstract
+{
+ abstract public function foo();
+}
+
+class MockeryTest_NameOfExistingClassWithDestructor
+{
+ public static $isDestructorWasCalled = false;
+
+ public function __destruct()
+ {
+ self::$isDestructorWasCalled = true;
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/AllowsExpectsSyntaxTest.php b/vendor/mockery/mockery/tests/Mockery/AllowsExpectsSyntaxTest.php
new file mode 100644
index 0000000..d7492f3
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/AllowsExpectsSyntaxTest.php
@@ -0,0 +1,111 @@
+allows()->foo(123)->andReturns(456);
+
+ $this->assertEquals(456, $stub->foo(123));
+ }
+
+ /** @test */
+ public function allowsCanTakeAnArrayOfCalls()
+ {
+ $stub = m::mock();
+ $stub->allows([
+ "foo" => "bar",
+ "bar" => "baz",
+ ]);
+
+ $this->assertEquals("bar", $stub->foo());
+ $this->assertEquals("baz", $stub->bar());
+ }
+
+ /** @test */
+ public function allowsCanTakeAString()
+ {
+ $stub = m::mock();
+ $stub->allows("foo")->andReturns("bar");
+ $this->assertEquals("bar", $stub->foo());
+ }
+
+ /** @test */
+ public function expects_can_optionally_match_on_any_arguments()
+ {
+ $mock = m::mock();
+ $mock->allows()->foo()->withAnyArgs()->andReturns(123);
+
+ $this->assertEquals(123, $mock->foo(456, 789));
+ }
+
+ /** @test */
+ public function expects_can_take_a_string()
+ {
+ $mock = m::mock();
+ $mock->expects("foo")->andReturns(123);
+
+ $this->assertEquals(123, $mock->foo(456, 789));
+ }
+
+ /** @test */
+ public function expectsSetsUpExpectationOfOneCall()
+ {
+ $mock = m::mock();
+ $mock->expects()->foo(123);
+
+ $this->expectException("Mockery\Exception\InvalidCountException");
+ m::close();
+ }
+
+ /** @test */
+ public function callVerificationCountCanBeOverridenAfterExpectsThrowsExceptionWhenIncorrectNumberOfCalls()
+ {
+ $mock = m::mock();
+ $mock->expects()->foo(123)->twice();
+
+ $mock->foo(123);
+ $this->expectException("Mockery\Exception\InvalidCountException");
+ m::close();
+ }
+
+ /** @test */
+ public function callVerificationCountCanBeOverridenAfterExpects()
+ {
+ $mock = m::mock();
+ $mock->expects()->foo(123)->twice();
+
+ $mock->foo(123);
+ $mock->foo(123);
+
+ m::close();
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/CallableSpyTest.php b/vendor/mockery/mockery/tests/Mockery/CallableSpyTest.php
new file mode 100644
index 0000000..013e5b1
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/CallableSpyTest.php
@@ -0,0 +1,199 @@
+shouldHaveBeenCalled();
+ }
+
+ /** @test */
+ public function it_throws_if_the_callable_was_not_called_at_all()
+ {
+ $spy = spy(function() {});
+
+ $this->expectException(InvalidCountException::class);
+ $spy->shouldHaveBeenCalled();
+ }
+
+ /** @test */
+ public function it_throws_if_there_were_no_arguments_but_we_expected_some()
+ {
+ $spy = spy(function() {});
+
+ $spy();
+
+ $this->expectException(InvalidCountException::class);
+ $spy->shouldHaveBeenCalled()->with(123, 546);
+ }
+
+ /** @test */
+ public function it_throws_if_the_arguments_do_not_match()
+ {
+ $spy = spy(function() {});
+
+ $spy(123);
+
+ $this->expectException(InvalidCountException::class);
+ $spy->shouldHaveBeenCalled()->with(123, 546);
+ }
+
+ /** @test */
+ public function it_verifies_the_closure_was_not_called()
+ {
+ $spy = spy(function () {});
+
+ $spy->shouldNotHaveBeenCalled();
+ }
+
+ /** @test */
+ public function it_throws_if_it_was_called_when_we_expected_it_to_not_have_been_called()
+ {
+ $spy = spy(function () {});
+
+ $spy();
+
+ $this->expectException(InvalidCountException::class);
+ $spy->shouldNotHaveBeenCalled();
+ }
+
+ /** @test */
+ public function it_verifies_it_was_not_called_with_some_particular_arguments_when_called_with_no_args()
+ {
+ $spy = spy(function () {});
+
+ $spy();
+
+ $spy->shouldNotHaveBeenCalled([123]);
+ }
+
+ /** @test */
+ public function it_verifies_it_was_not_called_with_some_particular_arguments_when_called_with_different_args()
+ {
+ $spy = spy(function () {});
+
+ $spy(456);
+
+ $spy->shouldNotHaveBeenCalled([123]);
+ }
+
+ /** @test */
+ public function it_throws_if_it_was_called_with_the_args_we_were_not_expecting()
+ {
+ $spy = spy(function () {});
+
+ $spy(123);
+
+ $this->expectException(InvalidCountException::class);
+ $spy->shouldNotHaveBeenCalled([123]);
+ }
+
+ /** @test */
+ public function it_can_verify_it_was_called_a_number_of_times()
+ {
+ $spy = spy(function () {});
+
+ $spy();
+ $spy();
+
+ $spy->shouldHaveBeenCalled()->twice();
+ }
+
+ /** @test */
+ public function it_can_verify_it_was_called_a_number_of_times_with_particular_arguments()
+ {
+ $spy = spy(function () {});
+
+ $spy(123);
+ $spy(123);
+
+ $spy->shouldHaveBeenCalled()->with(123)->twice();
+ }
+
+ /** @test */
+ public function it_throws_if_it_was_called_less_than_the_number_of_times_we_expected()
+ {
+ $spy = spy(function () {});
+
+ $spy();
+
+ $this->expectException(InvalidCountException::class);
+ $spy->shouldHaveBeenCalled()->twice();
+ }
+
+ /** @test */
+ public function it_throws_if_it_was_called_less_than_the_number_of_times_we_expected_with_particular_arguments()
+ {
+ $spy = spy(function () {});
+
+ $spy();
+ $spy(123);
+
+ $this->expectException(InvalidCountException::class);
+ $spy->shouldHaveBeenCalled()->with(123)->twice();
+ }
+
+ /** @test */
+ public function it_throws_if_it_was_called_more_than_the_number_of_times_we_expected()
+ {
+ $spy = spy(function () {});
+
+ $spy();
+ $spy();
+ $spy();
+
+ $this->expectException(InvalidCountException::class);
+ $spy->shouldHaveBeenCalled()->twice();
+ }
+
+ /** @test */
+ public function it_throws_if_it_was_called_more_than_the_number_of_times_we_expected_with_particular_arguments()
+ {
+ $spy = spy(function () {});
+
+ $spy(123);
+ $spy(123);
+ $spy(123);
+
+ $this->expectException(InvalidCountException::class);
+ $spy->shouldHaveBeenCalled()->with(123)->twice();
+ }
+
+ /** @test */
+ public function it_acts_as_partial()
+ {
+ $spy = spy(function ($number) { return $number + 1;});
+
+ $this->assertEquals(124, $spy(123));
+ $spy->shouldHaveBeenCalled();
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/ContainerTest.php b/vendor/mockery/mockery/tests/Mockery/ContainerTest.php
new file mode 100644
index 0000000..446d9e3
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/ContainerTest.php
@@ -0,0 +1,1825 @@
+shouldReceive('foo')->andReturn('bar');
+ $this->assertEquals('bar', $m->foo());
+ }
+
+ public function testGetKeyOfDemeterMockShouldReturnKeyWhenMatchingMock()
+ {
+ $m = mock();
+ $m->shouldReceive('foo->bar');
+ $this->assertRegExp(
+ '/Mockery_(\d+)__demeter_([0-9a-f]+)_foo/',
+ Mockery::getContainer()->getKeyOfDemeterMockFor('foo', get_class($m))
+ );
+ }
+ public function testGetKeyOfDemeterMockShouldReturnNullWhenNoMatchingMock()
+ {
+ $method = 'unknownMethod';
+ $this->assertNull(Mockery::getContainer()->getKeyOfDemeterMockFor($method, 'any'));
+
+ $m = mock();
+ $m->shouldReceive('method');
+ $this->assertNull(Mockery::getContainer()->getKeyOfDemeterMockFor($method, get_class($m)));
+
+ $m->shouldReceive('foo->bar');
+ $this->assertNull(Mockery::getContainer()->getKeyOfDemeterMockFor($method, get_class($m)));
+ }
+
+
+ public function testNamedMocksAddNameToExceptions()
+ {
+ $m = mock('Foo');
+ $m->shouldReceive('foo')->with(1)->andReturn('bar');
+ try {
+ $m->foo();
+ } catch (\Mockery\Exception $e) {
+ $this->assertTrue((bool) preg_match("/Foo/", $e->getMessage()));
+ }
+ }
+
+ public function testSimpleMockWithArrayDefs()
+ {
+ $m = mock(array('foo'=>1, 'bar'=>2));
+ $this->assertEquals(1, $m->foo());
+ $this->assertEquals(2, $m->bar());
+ }
+
+ public function testSimpleMockWithArrayDefsCanBeOverridden()
+ {
+ // eg. In shared test setup
+ $m = mock(array('foo' => 1, 'bar' => 2));
+
+ // and then overridden in one test
+ $m->shouldReceive('foo')->with('baz')->once()->andReturn(2);
+ $m->shouldReceive('bar')->with('baz')->once()->andReturn(42);
+
+ $this->assertEquals(2, $m->foo('baz'));
+ $this->assertEquals(42, $m->bar('baz'));
+ }
+
+ public function testNamedMockWithArrayDefs()
+ {
+ $m = mock('Foo', array('foo'=>1, 'bar'=>2));
+ $this->assertEquals(1, $m->foo());
+ $this->assertEquals(2, $m->bar());
+ try {
+ $m->f();
+ } catch (BadMethodCallException $e) {
+ $this->assertTrue((bool) preg_match("/Foo/", $e->getMessage()));
+ }
+ }
+
+ public function testNamedMockWithArrayDefsCanBeOverridden()
+ {
+ // eg. In shared test setup
+ $m = mock('Foo', array('foo' => 1));
+
+ // and then overridden in one test
+ $m->shouldReceive('foo')->with('bar')->once()->andReturn(2);
+
+ $this->assertEquals(2, $m->foo('bar'));
+
+ try {
+ $m->f();
+ } catch (BadMethodCallException $e) {
+ $this->assertTrue((bool) preg_match("/Foo/", $e->getMessage()));
+ }
+ }
+
+ public function testNamedMockMultipleInterfaces()
+ {
+ $m = mock('stdClass, ArrayAccess, Countable', array('foo'=>1, 'bar'=>2));
+ $this->assertEquals(1, $m->foo());
+ $this->assertEquals(2, $m->bar());
+ try {
+ $m->f();
+ } catch (BadMethodCallException $e) {
+ $this->assertTrue((bool) preg_match("/stdClass/", $e->getMessage()));
+ $this->assertTrue((bool) preg_match("/ArrayAccess/", $e->getMessage()));
+ $this->assertTrue((bool) preg_match("/Countable/", $e->getMessage()));
+ }
+ }
+
+ public function testNamedMockWithConstructorArgs()
+ {
+ $m = mock("MockeryTest_ClassConstructor2[foo]", array($param1 = new stdClass()));
+ $m->shouldReceive("foo")->andReturn(123);
+ $this->assertEquals(123, $m->foo());
+ $this->assertEquals($param1, $m->getParam1());
+ }
+
+ public function testNamedMockWithConstructorArgsAndArrayDefs()
+ {
+ $m = mock(
+ "MockeryTest_ClassConstructor2[foo]",
+ array($param1 = new stdClass()),
+ array("foo" => 123)
+ );
+ $this->assertEquals(123, $m->foo());
+ $this->assertEquals($param1, $m->getParam1());
+ }
+
+ public function testNamedMockWithConstructorArgsWithInternalCallToMockedMethod()
+ {
+ $m = mock("MockeryTest_ClassConstructor2[foo]", array($param1 = new stdClass()));
+ $m->shouldReceive("foo")->andReturn(123);
+ $this->assertEquals(123, $m->bar());
+ }
+
+ public function testNamedMockWithConstructorArgsButNoQuickDefsShouldLeaveConstructorIntact()
+ {
+ $m = mock("MockeryTest_ClassConstructor2", array($param1 = new stdClass()));
+ $m->makePartial();
+ $this->assertEquals($param1, $m->getParam1());
+ }
+
+ public function testNamedMockWithMakePartial()
+ {
+ $m = mock("MockeryTest_ClassConstructor2", array($param1 = new stdClass()));
+ $m->makePartial();
+ $this->assertEquals('foo', $m->bar());
+ $m->shouldReceive("bar")->andReturn(123);
+ $this->assertEquals(123, $m->bar());
+ }
+
+ /**
+ * @expectedException BadMethodCallException
+ */
+ public function testNamedMockWithMakePartialThrowsIfNotAvailable()
+ {
+ $m = mock("MockeryTest_ClassConstructor2", array($param1 = new stdClass()));
+ $m->makePartial();
+ $m->foorbar123();
+ $m->mockery_verify();
+ }
+
+ public function testMockingAKnownConcreteClassSoMockInheritsClassType()
+ {
+ $m = mock('stdClass');
+ $m->shouldReceive('foo')->andReturn('bar');
+ $this->assertEquals('bar', $m->foo());
+ $this->assertInstanceOf(stdClass::class, $m);
+ }
+
+ public function testMockingAKnownUserClassSoMockInheritsClassType()
+ {
+ $m = mock('MockeryTest_TestInheritedType');
+ $this->assertInstanceOf(MockeryTest_TestInheritedType::class, $m);
+ }
+
+ public function testMockingAConcreteObjectCreatesAPartialWithoutError()
+ {
+ $m = mock(new stdClass);
+ $m->shouldReceive('foo')->andReturn('bar');
+ $this->assertEquals('bar', $m->foo());
+ $this->assertInstanceOf(stdClass::class, $m);
+ }
+
+ public function testCreatingAPartialAllowsDynamicExpectationsAndPassesThroughUnexpectedMethods()
+ {
+ $m = mock(new MockeryTestFoo);
+ $m->shouldReceive('bar')->andReturn('bar');
+ $this->assertEquals('bar', $m->bar());
+ $this->assertEquals('foo', $m->foo());
+ $this->assertInstanceOf(MockeryTestFoo::class, $m);
+ }
+
+ public function testCreatingAPartialAllowsExpectationsToInterceptCallsToImplementedMethods()
+ {
+ $m = mock(new MockeryTestFoo2);
+ $m->shouldReceive('bar')->andReturn('baz');
+ $this->assertEquals('baz', $m->bar());
+ $this->assertEquals('foo', $m->foo());
+ $this->assertInstanceOf(MockeryTestFoo2::class, $m);
+ }
+
+ public function testBlockForwardingToPartialObject()
+ {
+ $m = mock(new MockeryTestBar1, array('foo'=>1, Mockery\Container::BLOCKS => array('method1')));
+ $this->assertSame($m, $m->method1());
+ }
+
+ public function testPartialWithArrayDefs()
+ {
+ $m = mock(new MockeryTestBar1, array('foo'=>1, Mockery\Container::BLOCKS => array('method1')));
+ $this->assertEquals(1, $m->foo());
+ }
+
+ public function testPassingClosureAsFinalParameterUsedToDefineExpectations()
+ {
+ $m = mock('foo', function ($m) {
+ $m->shouldReceive('foo')->once()->andReturn('bar');
+ });
+ $this->assertEquals('bar', $m->foo());
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testMockingAKnownConcreteFinalClassThrowsErrors_OnlyPartialMocksCanMockFinalElements()
+ {
+ $m = mock('MockeryFoo3');
+ }
+
+ public function testMockingAKnownConcreteClassWithFinalMethodsThrowsNoException()
+ {
+ $this->assertInstanceOf(MockInterface::class, mock('MockeryFoo4'));
+ }
+
+ /**
+ * @group finalclass
+ */
+ public function testFinalClassesCanBePartialMocks()
+ {
+ $m = mock(new MockeryFoo3);
+ $m->shouldReceive('foo')->andReturn('baz');
+ $this->assertEquals('baz', $m->foo());
+ $this->assertNotInstanceOf(MockeryFoo3::class, $m);
+ }
+
+ public function testSplClassWithFinalMethodsCanBeMocked()
+ {
+ $m = mock('SplFileInfo');
+ $m->shouldReceive('foo')->andReturn('baz');
+ $this->assertEquals('baz', $m->foo());
+ $this->assertInstanceOf(SplFileInfo::class, $m);
+ }
+
+ public function testSplClassWithFinalMethodsCanBeMockedMultipleTimes()
+ {
+ mock('SplFileInfo');
+ $m = mock('SplFileInfo');
+ $m->shouldReceive('foo')->andReturn('baz');
+ $this->assertEquals('baz', $m->foo());
+ $this->assertInstanceOf(SplFileInfo::class, $m);
+ }
+
+ public function testClassesWithFinalMethodsCanBeProxyPartialMocks()
+ {
+ $m = mock(new MockeryFoo4);
+ $m->shouldReceive('foo')->andReturn('baz');
+ $this->assertEquals('baz', $m->foo());
+ $this->assertEquals('bar', $m->bar());
+ $this->assertInstanceOf(MockeryFoo4::class, $m);
+ }
+
+ public function testClassesWithFinalMethodsCanBeProperPartialMocks()
+ {
+ $m = mock('MockeryFoo4[bar]');
+ $m->shouldReceive('bar')->andReturn('baz');
+ $this->assertEquals('baz', $m->foo());
+ $this->assertEquals('baz', $m->bar());
+ $this->assertInstanceOf(MockeryFoo4::class, $m);
+ }
+
+ public function testClassesWithFinalMethodsCanBeProperPartialMocksButFinalMethodsNotPartialed()
+ {
+ $m = mock('MockeryFoo4[foo]');
+ $m->shouldReceive('foo')->andReturn('foo');
+ $this->assertEquals('baz', $m->foo()); // partial expectation ignored - will fail callcount assertion
+ $this->assertInstanceOf(MockeryFoo4::class, $m);
+ }
+
+ public function testSplfileinfoClassMockPassesUserExpectations()
+ {
+ $file = mock('SplFileInfo[getFilename,getPathname,getExtension,getMTime]', array(__FILE__));
+ $file->shouldReceive('getFilename')->once()->andReturn('foo');
+ $file->shouldReceive('getPathname')->once()->andReturn('path/to/foo');
+ $file->shouldReceive('getExtension')->once()->andReturn('css');
+ $file->shouldReceive('getMTime')->once()->andReturn(time());
+
+ // not sure what this test is for, maybe something special about
+ // SplFileInfo
+ $this->assertEquals('foo', $file->getFilename());
+ $this->assertEquals('path/to/foo', $file->getPathname());
+ $this->assertEquals('css', $file->getExtension());
+ $this->assertInternalType('int', $file->getMTime());
+ }
+
+ public function testCanMockInterface()
+ {
+ $m = mock('MockeryTest_Interface');
+ $this->assertInstanceOf(MockeryTest_Interface::class, $m);
+ }
+
+ public function testCanMockSpl()
+ {
+ $m = mock('\\SplFixedArray');
+ $this->assertInstanceOf(SplFixedArray::class, $m);
+ }
+
+ public function testCanMockInterfaceWithAbstractMethod()
+ {
+ $m = mock('MockeryTest_InterfaceWithAbstractMethod');
+ $this->assertInstanceOf(MockeryTest_InterfaceWithAbstractMethod::class, $m);
+ $m->shouldReceive('foo')->andReturn(1);
+ $this->assertEquals(1, $m->foo());
+ }
+
+ public function testCanMockAbstractWithAbstractProtectedMethod()
+ {
+ $m = mock('MockeryTest_AbstractWithAbstractMethod');
+ $this->assertInstanceOf(MockeryTest_AbstractWithAbstractMethod::class, $m);
+ }
+
+ public function testCanMockInterfaceWithPublicStaticMethod()
+ {
+ $m = mock('MockeryTest_InterfaceWithPublicStaticMethod');
+ $this->assertInstanceOf(MockeryTest_InterfaceWithPublicStaticMethod::class, $m);
+ }
+
+ public function testCanMockClassWithConstructor()
+ {
+ $m = mock('MockeryTest_ClassConstructor');
+ $this->assertInstanceOf(MockeryTest_ClassConstructor::class, $m);
+ }
+
+ public function testCanMockClassWithConstructorNeedingClassArgs()
+ {
+ $m = mock('MockeryTest_ClassConstructor2');
+ $this->assertInstanceOf(MockeryTest_ClassConstructor2::class, $m);
+ }
+
+ /**
+ * @group partial
+ */
+ public function testCanPartiallyMockANormalClass()
+ {
+ $m = mock('MockeryTest_PartialNormalClass[foo]');
+ $this->assertInstanceOf(MockeryTest_PartialNormalClass::class, $m);
+ $m->shouldReceive('foo')->andReturn('cba');
+ $this->assertEquals('abc', $m->bar());
+ $this->assertEquals('cba', $m->foo());
+ }
+
+ /**
+ * @group partial
+ */
+ public function testCanPartiallyMockAnAbstractClass()
+ {
+ $m = mock('MockeryTest_PartialAbstractClass[foo]');
+ $this->assertInstanceOf(MockeryTest_PartialAbstractClass::class, $m);
+ $m->shouldReceive('foo')->andReturn('cba');
+ $this->assertEquals('abc', $m->bar());
+ $this->assertEquals('cba', $m->foo());
+ }
+
+ /**
+ * @group partial
+ */
+ public function testCanPartiallyMockANormalClassWith2Methods()
+ {
+ $m = mock('MockeryTest_PartialNormalClass2[foo, baz]');
+ $this->assertInstanceOf(MockeryTest_PartialNormalClass2::class, $m);
+ $m->shouldReceive('foo')->andReturn('cba');
+ $m->shouldReceive('baz')->andReturn('cba');
+ $this->assertEquals('abc', $m->bar());
+ $this->assertEquals('cba', $m->foo());
+ $this->assertEquals('cba', $m->baz());
+ }
+
+ /**
+ * @group partial
+ */
+ public function testCanPartiallyMockAnAbstractClassWith2Methods()
+ {
+ $m = mock('MockeryTest_PartialAbstractClass2[foo,baz]');
+ $this->assertInstanceOf(MockeryTest_PartialAbstractClass2::class, $m);
+ $m->shouldReceive('foo')->andReturn('cba');
+ $m->shouldReceive('baz')->andReturn('cba');
+ $this->assertEquals('abc', $m->bar());
+ $this->assertEquals('cba', $m->foo());
+ $this->assertEquals('cba', $m->baz());
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ * @group partial
+ */
+ public function testThrowsExceptionIfSettingExpectationForNonMockedMethodOfPartialMock()
+ {
+ $this->markTestSkipped('For now...');
+ $m = mock('MockeryTest_PartialNormalClass[foo]');
+ $this->assertInstanceOf(MockeryTest_PartialNormalClass::class, $m);
+ $m->shouldReceive('bar')->andReturn('cba');
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ * @group partial
+ */
+ public function testThrowsExceptionIfClassOrInterfaceForPartialMockDoesNotExist()
+ {
+ $m = mock('MockeryTest_PartialNormalClassXYZ[foo]');
+ }
+
+ /**
+ * @group issue/4
+ */
+ public function testCanMockClassContainingMagicCallMethod()
+ {
+ $m = mock('MockeryTest_Call1');
+ $this->assertInstanceOf(MockeryTest_Call1::class, $m);
+ }
+
+ /**
+ * @group issue/4
+ */
+ public function testCanMockClassContainingMagicCallMethodWithoutTypeHinting()
+ {
+ $m = mock('MockeryTest_Call2');
+ $this->assertInstanceOf(MockeryTest_Call2::class, $m);
+ }
+
+ /**
+ * @group issue/14
+ */
+ public function testCanMockClassContainingAPublicWakeupMethod()
+ {
+ $m = mock('MockeryTest_Wakeup1');
+ $this->assertInstanceOf(MockeryTest_Wakeup1::class, $m);
+ }
+
+ /**
+ * @group issue/18
+ */
+ public function testCanMockClassUsingMagicCallMethodsInPlaceOfNormalMethods()
+ {
+ $m = Mockery::mock('Gateway');
+ $m->shouldReceive('iDoSomethingReallyCoolHere');
+ $m->iDoSomethingReallyCoolHere();
+ }
+
+ /**
+ * @group issue/18
+ */
+ public function testCanPartialMockObjectUsingMagicCallMethodsInPlaceOfNormalMethods()
+ {
+ $m = Mockery::mock(new Gateway);
+ $m->shouldReceive('iDoSomethingReallyCoolHere');
+ $m->iDoSomethingReallyCoolHere();
+ }
+
+ /**
+ * @group issue/13
+ */
+ public function testCanMockClassWhereMethodHasReferencedParameter()
+ {
+ $this->assertInstanceOf(MockInterface::class, Mockery::mock(new MockeryTest_MethodParamRef));
+ }
+
+ /**
+ * @group issue/13
+ */
+ public function testCanPartiallyMockObjectWhereMethodHasReferencedParameter()
+ {
+ $this->assertInstanceOf(MockInterface::class, Mockery::mock(new MockeryTest_MethodParamRef2));
+ }
+
+ /**
+ * @group issue/11
+ */
+ public function testMockingAKnownConcreteClassCanBeGrantedAnArbitraryClassType()
+ {
+ $m = mock('alias:MyNamespace\MyClass');
+ $m->shouldReceive('foo')->andReturn('bar');
+ $this->assertEquals('bar', $m->foo());
+ $this->assertInstanceOf(MyNamespace\MyClass::class, $m);
+ }
+
+ /**
+ * @group issue/15
+ */
+ public function testCanMockMultipleInterfaces()
+ {
+ $m = mock('MockeryTest_Interface1, MockeryTest_Interface2');
+ $this->assertInstanceOf(MockeryTest_Interface1::class, $m);
+ $this->assertInstanceOf(MockeryTest_Interface2::class, $m);
+ }
+
+ /**
+ */
+ public function testCanMockMultipleInterfacesThatMayNotExist()
+ {
+ $m = mock('NonExistingClass, MockeryTest_Interface1, MockeryTest_Interface2, \Some\Thing\That\Doesnt\Exist');
+ $this->assertInstanceOf(MockeryTest_Interface1::class, $m);
+ $this->assertInstanceOf(MockeryTest_Interface2::class, $m);
+ $this->assertInstanceOf(\Some\Thing\That\Doesnt\Exist::class, $m);
+ }
+
+ /**
+ * @group issue/15
+ */
+ public function testCanMockClassAndApplyMultipleInterfaces()
+ {
+ $m = mock('MockeryTestFoo, MockeryTest_Interface1, MockeryTest_Interface2');
+ $this->assertInstanceOf(MockeryTestFoo::class, $m);
+ $this->assertInstanceOf(MockeryTest_Interface1::class, $m);
+ $this->assertInstanceOf(MockeryTest_Interface2::class, $m);
+ }
+
+ /**
+ * @group issue/7
+ *
+ * Noted: We could complicate internally, but a blind class is better built
+ * with a real class noted up front (stdClass is a perfect choice it is
+ * behaviourless). Fine, it's a muddle - but we need to draw a line somewhere.
+ */
+ public function testCanMockStaticMethods()
+ {
+ $m = mock('alias:MyNamespace\MyClass2');
+ $m->shouldReceive('staticFoo')->andReturn('bar');
+ $this->assertEquals('bar', \MyNameSpace\MyClass2::staticFoo());
+ }
+
+ /**
+ * @group issue/7
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testMockedStaticMethodsObeyMethodCounting()
+ {
+ $m = mock('alias:MyNamespace\MyClass3');
+ $m->shouldReceive('staticFoo')->once()->andReturn('bar');
+ Mockery::close();
+ }
+
+ /**
+ */
+ public function testMockedStaticThrowsExceptionWhenMethodDoesNotExist()
+ {
+ $m = mock('alias:MyNamespace\StaticNoMethod');
+ try {
+ MyNameSpace\StaticNoMethod::staticFoo();
+ } catch (BadMethodCallException $e) {
+ // Mockery + PHPUnit has a fail safe for tests swallowing our
+ // exceptions
+ $e->dismiss();
+ return;
+ }
+
+ $this->fail('Exception was not thrown');
+ }
+
+ /**
+ * @group issue/17
+ */
+ public function testMockingAllowsPublicPropertyStubbingOnRealClass()
+ {
+ $m = mock('MockeryTestFoo');
+ $m->foo = 'bar';
+ $this->assertEquals('bar', $m->foo);
+ //$this->assertArrayHasKey('foo', $m->mockery_getMockableProperties());
+ }
+
+ /**
+ * @group issue/17
+ */
+ public function testMockingAllowsPublicPropertyStubbingOnNamedMock()
+ {
+ $m = mock('Foo');
+ $m->foo = 'bar';
+ $this->assertEquals('bar', $m->foo);
+ //$this->assertArrayHasKey('foo', $m->mockery_getMockableProperties());
+ }
+
+ /**
+ * @group issue/17
+ */
+ public function testMockingAllowsPublicPropertyStubbingOnPartials()
+ {
+ $m = mock(new stdClass);
+ $m->foo = 'bar';
+ $this->assertEquals('bar', $m->foo);
+ //$this->assertArrayHasKey('foo', $m->mockery_getMockableProperties());
+ }
+
+ /**
+ * @group issue/17
+ */
+ public function testMockingDoesNotStubNonStubbedPropertiesOnPartials()
+ {
+ $m = mock(new MockeryTest_ExistingProperty);
+ $this->assertEquals('bar', $m->foo);
+ $this->assertArrayNotHasKey('foo', $m->mockery_getMockableProperties());
+ }
+
+ public function testCreationOfInstanceMock()
+ {
+ $m = mock('overload:MyNamespace\MyClass4');
+ $this->assertInstanceOf(MyNamespace\MyClass4::class, $m);
+ }
+
+ public function testInstantiationOfInstanceMock()
+ {
+ $m = mock('overload:MyNamespace\MyClass5');
+ $instance = new MyNamespace\MyClass5;
+ $this->assertInstanceOf(MyNamespace\MyClass5::class, $instance);
+ }
+
+ public function testInstantiationOfInstanceMockImportsExpectations()
+ {
+ $m = mock('overload:MyNamespace\MyClass6');
+ $m->shouldReceive('foo')->andReturn('bar');
+ $instance = new MyNamespace\MyClass6;
+ $this->assertEquals('bar', $instance->foo());
+ }
+
+ public function testInstantiationOfInstanceMockImportsDefaultExpectations()
+ {
+ $m = mock('overload:MyNamespace\MyClass6');
+ $m->shouldReceive('foo')->andReturn('bar')->byDefault();
+ $instance = new MyNamespace\MyClass6;
+
+ $this->assertEquals('bar', $instance->foo());
+ }
+
+ public function testInstantiationOfInstanceMockImportsDefaultExpectationsInTheCorrectOrder()
+ {
+ $m = mock('overload:MyNamespace\MyClass6');
+ $m->shouldReceive('foo')->andReturn(1)->byDefault();
+ $m->shouldReceive('foo')->andReturn(2)->byDefault();
+ $m->shouldReceive('foo')->andReturn(3)->byDefault();
+ $instance = new MyNamespace\MyClass6;
+
+ $this->assertEquals(3, $instance->foo());
+ }
+
+ public function testInstantiationOfInstanceMocksIgnoresVerificationOfOriginMock()
+ {
+ $m = mock('overload:MyNamespace\MyClass7');
+ $m->shouldReceive('foo')->once()->andReturn('bar');
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testInstantiationOfInstanceMocksAddsThemToContainerForVerification()
+ {
+ $m = mock('overload:MyNamespace\MyClass8');
+ $m->shouldReceive('foo')->once();
+ $instance = new MyNamespace\MyClass8;
+ Mockery::close();
+ }
+
+ public function testInstantiationOfInstanceMocksDoesNotHaveCountValidatorCrossover()
+ {
+ $m = mock('overload:MyNamespace\MyClass9');
+ $m->shouldReceive('foo')->once();
+ $instance1 = new MyNamespace\MyClass9;
+ $instance2 = new MyNamespace\MyClass9;
+ $instance1->foo();
+ $instance2->foo();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testInstantiationOfInstanceMocksDoesNotHaveCountValidatorCrossover2()
+ {
+ $m = mock('overload:MyNamespace\MyClass10');
+ $m->shouldReceive('foo')->once();
+ $instance1 = new MyNamespace\MyClass10;
+ $instance2 = new MyNamespace\MyClass10;
+ $instance1->foo();
+ Mockery::close();
+ }
+
+ public function testCreationOfInstanceMockWithFullyQualifiedName()
+ {
+ $m = mock('overload:\MyNamespace\MyClass11');
+ $this->assertInstanceOf(MyNamespace\MyClass11::class, $m);
+ }
+
+ public function testInstanceMocksShouldIgnoreMissing()
+ {
+ $m = mock('overload:MyNamespace\MyClass12');
+ $m->shouldIgnoreMissing();
+
+ $instance = new MyNamespace\MyClass12();
+ $this->assertNull($instance->foo());
+ }
+
+ /**
+ * @group issue/451
+ */
+ public function testSettingPropertyOnInstanceMockWillSetItOnActualInstance()
+ {
+ $m = mock('overload:MyNamespace\MyClass13');
+ $m->shouldReceive('foo')->andSet('bar', 'baz');
+ $instance = new MyNamespace\MyClass13;
+ $instance->foo();
+ $this->assertEquals('baz', $m->bar);
+ $this->assertEquals('baz', $instance->bar);
+ }
+
+ public function testInstantiationOfInstanceMockWithConstructorParameterValidation()
+ {
+ $m = mock('overload:MyNamespace\MyClass14');
+ $params = [
+ 'value1' => uniqid('test_')
+ ];
+ $m->shouldReceive('__construct')->with($params);
+
+ new MyNamespace\MyClass14($params);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception\NoMatchingExpectationException
+ */
+ public function testInstantiationOfInstanceMockWithConstructorParameterValidationNegative()
+ {
+ $m = mock('overload:MyNamespace\MyClass15');
+ $params = [
+ 'value1' => uniqid('test_')
+ ];
+ $m->shouldReceive('__construct')->with($params);
+
+ new MyNamespace\MyClass15([]);
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessageRegExp /^instanceMock \d{3}$/
+ */
+ public function testInstantiationOfInstanceMockWithConstructorParameterValidationException()
+ {
+ $m = mock('overload:MyNamespace\MyClass16');
+ $m->shouldReceive('__construct')
+ ->andThrow(new \Exception('instanceMock '.rand(100, 999)));
+
+ new MyNamespace\MyClass16();
+ }
+
+ public function testMethodParamsPassedByReferenceHaveReferencePreserved()
+ {
+ $m = mock('MockeryTestRef1');
+ $m->shouldReceive('foo')->with(
+ Mockery::on(function (&$a) {
+ $a += 1;
+ return true;
+ }),
+ Mockery::any()
+ );
+ $a = 1;
+ $b = 1;
+ $m->foo($a, $b);
+ $this->assertEquals(2, $a);
+ $this->assertEquals(1, $b);
+ }
+
+ public function testMethodParamsPassedByReferenceThroughWithArgsHaveReferencePreserved()
+ {
+ $m = mock('MockeryTestRef1');
+ $m->shouldReceive('foo')->withArgs(function (&$a, $b) {
+ $a += 1;
+ $b += 1;
+ return true;
+ });
+ $a = 1;
+ $b = 1;
+ $m->foo($a, $b);
+ $this->assertEquals(2, $a);
+ $this->assertEquals(1, $b);
+ }
+
+ /**
+ * Meant to test the same logic as
+ * testCanOverrideExpectedParametersOfExtensionPHPClassesToPreserveRefs,
+ * but:
+ * - doesn't require an extension
+ * - isn't actually known to be used
+ */
+ public function testCanOverrideExpectedParametersOfInternalPHPClassesToPreserveRefs()
+ {
+ Mockery::getConfiguration()->setInternalClassMethodParamMap(
+ 'DateTime', 'modify', array('&$string')
+ );
+ // @ used to avoid E_STRICT for incompatible signature
+ @$m = mock('DateTime');
+ $this->assertInstanceOf("Mockery\MockInterface", $m, "Mocking failed, remove @ error suppresion to debug");
+ $m->shouldReceive('modify')->with(
+ Mockery::on(function (&$string) {
+ $string = 'foo';
+ return true;
+ })
+ );
+ $data ='bar';
+ $m->modify($data);
+ $this->assertEquals('foo', $data);
+ Mockery::getConfiguration()->resetInternalClassMethodParamMaps();
+ }
+
+ /**
+ * Real world version of
+ * testCanOverrideExpectedParametersOfInternalPHPClassesToPreserveRefs
+ */
+ public function testCanOverrideExpectedParametersOfExtensionPHPClassesToPreserveRefs()
+ {
+ if (!class_exists('MongoCollection', false)) {
+ $this->markTestSkipped('ext/mongo not installed');
+ }
+ Mockery::getConfiguration()->setInternalClassMethodParamMap(
+ 'MongoCollection', 'insert', array('&$data', '$options')
+ );
+ // @ used to avoid E_STRICT for incompatible signature
+ @$m = mock('MongoCollection');
+ $this->assertInstanceOf("Mockery\MockInterface", $m, "Mocking failed, remove @ error suppresion to debug");
+ $m->shouldReceive('insert')->with(
+ Mockery::on(function (&$data) {
+ $data['_id'] = 123;
+ return true;
+ }),
+ Mockery::type('array')
+ );
+ $data = array('a'=>1,'b'=>2);
+ $m->insert($data, array());
+ $this->assertArrayHasKey('_id', $data);
+ $this->assertEquals(123, $data['_id']);
+ Mockery::getConfiguration()->resetInternalClassMethodParamMaps();
+ }
+
+ public function testCanCreateNonOverridenInstanceOfPreviouslyOverridenInternalClasses()
+ {
+ Mockery::getConfiguration()->setInternalClassMethodParamMap(
+ 'DateTime', 'modify', array('&$string')
+ );
+ // @ used to avoid E_STRICT for incompatible signature
+ @$m = mock('DateTime');
+ $this->assertInstanceOf("Mockery\MockInterface", $m, "Mocking failed, remove @ error suppresion to debug");
+ $rc = new ReflectionClass($m);
+ $rm = $rc->getMethod('modify');
+ $params = $rm->getParameters();
+ $this->assertTrue($params[0]->isPassedByReference());
+
+ Mockery::getConfiguration()->resetInternalClassMethodParamMaps();
+
+ $m = mock('DateTime');
+ $this->assertInstanceOf("Mockery\MockInterface", $m, "Mocking failed");
+ $rc = new ReflectionClass($m);
+ $rm = $rc->getMethod('modify');
+ $params = $rm->getParameters();
+ $this->assertFalse($params[0]->isPassedByReference());
+
+ Mockery::getConfiguration()->resetInternalClassMethodParamMaps();
+ }
+
+ /**
+ * @group abstract
+ */
+ public function testCanMockAbstractClassWithAbstractPublicMethod()
+ {
+ $m = mock('MockeryTest_AbstractWithAbstractPublicMethod');
+ $this->assertInstanceOf(MockeryTest_AbstractWithAbstractPublicMethod::class, $m);
+ }
+
+ /**
+ * @issue issue/21
+ */
+ public function testClassDeclaringIssetDoesNotThrowException()
+ {
+ $this->assertInstanceOf(MockInterface::class, mock('MockeryTest_IssetMethod'));
+ }
+
+ /**
+ * @issue issue/21
+ */
+ public function testClassDeclaringUnsetDoesNotThrowException()
+ {
+ $this->assertInstanceOf(MockInterface::class, mock('MockeryTest_UnsetMethod'));
+ }
+
+ /**
+ * @issue issue/35
+ */
+ public function testCallingSelfOnlyReturnsLastMockCreatedOrCurrentMockBeingProgrammedSinceTheyAreOneAndTheSame()
+ {
+ $m = mock('MockeryTestFoo');
+ $this->assertNotInstanceOf(MockeryTestFoo2::class, Mockery::self());
+ //$m = mock('MockeryTestFoo2');
+ //$this->assertInstanceOf(MockeryTestFoo2::class, self());
+ //$m = mock('MockeryTestFoo');
+ //$this->assertNotInstanceOf(MockeryTestFoo2::class, Mockery::self());
+ //$this->assertInstanceOf(MockeryTestFoo::class, Mockery::self());
+ }
+
+ /**
+ * @issue issue/89
+ */
+ public function testCreatingMockOfClassWithExistingToStringMethodDoesntCreateClassWithTwoToStringMethods()
+ {
+ $m = mock('MockeryTest_WithToString'); // this would fatal
+ $m->shouldReceive("__toString")->andReturn('dave');
+ $this->assertEquals("dave", "$m");
+ }
+
+ public function testGetExpectationCount_freshContainer()
+ {
+ $this->assertEquals(0, Mockery::getContainer()->mockery_getExpectationCount());
+ }
+
+ public function testGetExpectationCount_simplestMock()
+ {
+ $m = mock();
+ $m->shouldReceive('foo')->andReturn('bar');
+ $this->assertEquals(1, Mockery::getContainer()->mockery_getExpectationCount());
+ }
+
+ public function testMethodsReturningParamsByReferenceDoesNotErrorOut()
+ {
+ mock('MockeryTest_ReturnByRef');
+ $mock = mock('MockeryTest_ReturnByRef');
+ $mock->shouldReceive("get")->andReturn($var = 123);
+ $this->assertSame($var, $mock->get());
+ }
+
+
+ public function testMockCallableTypeHint()
+ {
+ $this->assertInstanceOf(MockInterface::class, mock('MockeryTest_MockCallableTypeHint'));
+ }
+
+ public function testCanMockClassWithReservedWordMethod()
+ {
+ if (!extension_loaded("redis")) {
+ $this->markTestSkipped("phpredis not installed");
+ }
+
+ mock("Redis");
+ }
+
+ public function testUndeclaredClassIsDeclared()
+ {
+ $this->assertFalse(class_exists("BlahBlah"));
+ $mock = mock("BlahBlah");
+ $this->assertInstanceOf("BlahBlah", $mock);
+ }
+
+ public function testUndeclaredClassWithNamespaceIsDeclared()
+ {
+ $this->assertFalse(class_exists("MyClasses\Blah\BlahBlah"));
+ $mock = mock("MyClasses\Blah\BlahBlah");
+ $this->assertInstanceOf("MyClasses\Blah\BlahBlah", $mock);
+ }
+
+ public function testUndeclaredClassWithNamespaceIncludingLeadingOperatorIsDeclared()
+ {
+ $this->assertFalse(class_exists("\MyClasses\DaveBlah\BlahBlah"));
+ $mock = mock("\MyClasses\DaveBlah\BlahBlah");
+ $this->assertInstanceOf("\MyClasses\DaveBlah\BlahBlah", $mock);
+ }
+
+ public function testMockingPhpredisExtensionClassWorks()
+ {
+ if (!class_exists('Redis')) {
+ $this->markTestSkipped('PHPRedis extension required for this test');
+ }
+ $m = mock('Redis');
+ }
+
+ public function testIssetMappingUsingProxiedPartials_CheckNoExceptionThrown()
+ {
+ $var = mock(new MockeryTestIsset_Bar());
+ $mock = mock(new MockeryTestIsset_Foo($var));
+ $mock->shouldReceive('bar')->once();
+ $mock->bar();
+ Mockery::close();
+
+ $this->assertTrue(true);
+ }
+
+ /**
+ * @group traversable1
+ */
+ public function testCanMockInterfacesExtendingTraversable()
+ {
+ $mock = mock('MockeryTest_InterfaceWithTraversable');
+ $this->assertInstanceOf('MockeryTest_InterfaceWithTraversable', $mock);
+ $this->assertInstanceOf('ArrayAccess', $mock);
+ $this->assertInstanceOf('Countable', $mock);
+ $this->assertInstanceOf('Traversable', $mock);
+ }
+
+ /**
+ * @group traversable2
+ */
+ public function testCanMockInterfacesAlongsideTraversable()
+ {
+ $mock = mock('stdClass, ArrayAccess, Countable, Traversable');
+ $this->assertInstanceOf('stdClass', $mock);
+ $this->assertInstanceOf('ArrayAccess', $mock);
+ $this->assertInstanceOf('Countable', $mock);
+ $this->assertInstanceOf('Traversable', $mock);
+ }
+
+ public function testInterfacesCanHaveAssertions()
+ {
+ $m = mock('stdClass, ArrayAccess, Countable, Traversable');
+ $m->shouldReceive('foo')->once();
+ $m->foo();
+ }
+
+ public function testMockingIteratorAggregateDoesNotImplementIterator()
+ {
+ $mock = mock('MockeryTest_ImplementsIteratorAggregate');
+ $this->assertInstanceOf('IteratorAggregate', $mock);
+ $this->assertInstanceOf('Traversable', $mock);
+ $this->assertNotInstanceOf('Iterator', $mock);
+ }
+
+ public function testMockingInterfaceThatExtendsIteratorDoesNotImplementIterator()
+ {
+ $mock = mock('MockeryTest_InterfaceThatExtendsIterator');
+ $this->assertInstanceOf('Iterator', $mock);
+ $this->assertInstanceOf('Traversable', $mock);
+ }
+
+ public function testMockingInterfaceThatExtendsIteratorAggregateDoesNotImplementIterator()
+ {
+ $mock = mock('MockeryTest_InterfaceThatExtendsIteratorAggregate');
+ $this->assertInstanceOf('IteratorAggregate', $mock);
+ $this->assertInstanceOf('Traversable', $mock);
+ $this->assertNotInstanceOf('Iterator', $mock);
+ }
+
+ public function testMockingIteratorAggregateDoesNotImplementIteratorAlongside()
+ {
+ $mock = mock('IteratorAggregate');
+ $this->assertInstanceOf('IteratorAggregate', $mock);
+ $this->assertInstanceOf('Traversable', $mock);
+ $this->assertNotInstanceOf('Iterator', $mock);
+ }
+
+ public function testMockingIteratorDoesNotImplementIteratorAlongside()
+ {
+ $mock = mock('Iterator');
+ $this->assertInstanceOf('Iterator', $mock);
+ $this->assertInstanceOf('Traversable', $mock);
+ }
+
+ public function testMockingIteratorDoesNotImplementIterator()
+ {
+ $mock = mock('MockeryTest_ImplementsIterator');
+ $this->assertInstanceOf('Iterator', $mock);
+ $this->assertInstanceOf('Traversable', $mock);
+ }
+
+ public function testMockeryCloseForIllegalIssetFileInclude()
+ {
+ $m = Mockery::mock('StdClass')
+ ->shouldReceive('get')
+ ->andReturn(false)
+ ->getMock();
+ $m->get();
+ Mockery::close();
+
+ // no idea what this test does, adding this as an assertion...
+ $this->assertTrue(true);
+ }
+
+ public function testMockeryShouldDistinguishBetweenConstructorParamsAndClosures()
+ {
+ $obj = new MockeryTestFoo();
+ $this->assertInstanceOf(MockInterface::class, mock('MockeryTest_ClassMultipleConstructorParams[dave]', [
+ &$obj, 'foo'
+ ]));
+ }
+
+ /** @group nette */
+ public function testMockeryShouldNotMockCallstaticMagicMethod()
+ {
+ $this->assertInstanceOf(MockInterface::class, mock('MockeryTest_CallStatic'));
+ }
+
+ /** @group issue/144 */
+ public function testMockeryShouldInterpretEmptyArrayAsConstructorArgs()
+ {
+ $mock = mock("EmptyConstructorTest", array());
+ $this->assertSame(0, $mock->numberOfConstructorArgs);
+ }
+
+ /** @group issue/144 */
+ public function testMockeryShouldCallConstructorByDefaultWhenRequestingPartials()
+ {
+ $mock = mock("EmptyConstructorTest[foo]");
+ $this->assertSame(0, $mock->numberOfConstructorArgs);
+ }
+
+ /** @group issue/158 */
+ public function testMockeryShouldRespectInterfaceWithMethodParamSelf()
+ {
+ $this->assertInstanceOf(MockInterface::class, mock('MockeryTest_InterfaceWithMethodParamSelf'));
+ }
+
+ /** @group issue/162 */
+ public function testMockeryDoesntTryAndMockLowercaseToString()
+ {
+ $this->assertInstanceOf(MockInterface::class, mock('MockeryTest_Lowercase_ToString'));
+ }
+
+ /** @group issue/175 */
+ public function testExistingStaticMethodMocking()
+ {
+ $mock = mock('MockeryTest_PartialStatic[mockMe]');
+
+ $mock->shouldReceive('mockMe')->with(5)->andReturn(10);
+
+ $this->assertEquals(10, $mock::mockMe(5));
+ $this->assertEquals(3, $mock::keepMe(3));
+ }
+
+ /**
+ * @group issue/154
+ * @expectedException InvalidArgumentException
+ * @expectedExceptionMessage protectedMethod() cannot be mocked as it is a protected method and mocking protected methods is not enabled for the currently used mock object.
+ */
+ public function testShouldThrowIfAttemptingToStubProtectedMethod()
+ {
+ $mock = mock('MockeryTest_WithProtectedAndPrivate');
+ $mock->shouldReceive("protectedMethod");
+ }
+
+ /**
+ * @group issue/154
+ * @expectedException InvalidArgumentException
+ * @expectedExceptionMessage privateMethod() cannot be mocked as it is a private method
+ */
+ public function testShouldThrowIfAttemptingToStubPrivateMethod()
+ {
+ $mock = mock('MockeryTest_WithProtectedAndPrivate');
+ $mock->shouldReceive("privateMethod");
+ }
+
+ public function testWakeupMagicIsNotMockedToAllowSerialisationInstanceHack()
+ {
+ $this->assertInstanceOf(\DateTime::class, mock('DateTime'));
+ }
+
+ /**
+ * @group issue/154
+ */
+ public function testCanMockMethodsWithRequiredParamsThatHaveDefaultValues()
+ {
+ $mock = mock('MockeryTest_MethodWithRequiredParamWithDefaultValue');
+ $mock->shouldIgnoreMissing();
+ $this->assertNull($mock->foo(null, 123));
+ }
+
+ /**
+ * @test
+ * @group issue/294
+ * @expectedException Mockery\Exception\RuntimeException
+ * @expectedExceptionMessage Could not load mock DateTime, class already exists
+ */
+ public function testThrowsWhenNamedMockClassExistsAndIsNotMockery()
+ {
+ $builder = new MockConfigurationBuilder();
+ $builder->setName("DateTime");
+ $mock = mock($builder);
+ }
+
+ /**
+ * @expectedException Mockery\Exception\NoMatchingExpectationException
+ * @expectedExceptionMessage MyTestClass::foo(resource(...))
+ */
+ public function testHandlesMethodWithArgumentExpectationWhenCalledWithResource()
+ {
+ $mock = mock('MyTestClass');
+ $mock->shouldReceive('foo')->with(array('yourself' => 21));
+
+ $mock->foo(fopen('php://memory', 'r'));
+ }
+
+ /**
+ * @expectedException Mockery\Exception\NoMatchingExpectationException
+ * @expectedExceptionMessage MyTestClass::foo(['myself' => [...]])
+ */
+ public function testHandlesMethodWithArgumentExpectationWhenCalledWithCircularArray()
+ {
+ $testArray = array();
+ $testArray['myself'] =& $testArray;
+
+ $mock = mock('MyTestClass');
+ $mock->shouldReceive('foo')->with(array('yourself' => 21));
+
+ $mock->foo($testArray);
+ }
+
+ /**
+ * @expectedException Mockery\Exception\NoMatchingExpectationException
+ * @expectedExceptionMessage MyTestClass::foo(['a_scalar' => 2, 'an_array' => [...]])
+ */
+ public function testHandlesMethodWithArgumentExpectationWhenCalledWithNestedArray()
+ {
+ $testArray = array();
+ $testArray['a_scalar'] = 2;
+ $testArray['an_array'] = array(1, 2, 3);
+
+ $mock = mock('MyTestClass');
+ $mock->shouldReceive('foo')->with(array('yourself' => 21));
+
+ $mock->foo($testArray);
+ }
+
+ /**
+ * @expectedException Mockery\Exception\NoMatchingExpectationException
+ * @expectedExceptionMessage MyTestClass::foo(['a_scalar' => 2, 'an_object' => object(stdClass)])
+ */
+ public function testHandlesMethodWithArgumentExpectationWhenCalledWithNestedObject()
+ {
+ $testArray = array();
+ $testArray['a_scalar'] = 2;
+ $testArray['an_object'] = new stdClass();
+
+ $mock = mock('MyTestClass');
+ $mock->shouldReceive('foo')->with(array('yourself' => 21));
+
+ $mock->foo($testArray);
+ }
+
+ /**
+ * @expectedException Mockery\Exception\NoMatchingExpectationException
+ * @expectedExceptionMessage MyTestClass::foo(['a_scalar' => 2, 'a_closure' => object(Closure
+ */
+ public function testHandlesMethodWithArgumentExpectationWhenCalledWithNestedClosure()
+ {
+ $testArray = array();
+ $testArray['a_scalar'] = 2;
+ $testArray['a_closure'] = function () {
+ };
+
+ $mock = mock('MyTestClass');
+ $mock->shouldReceive('foo')->with(array('yourself' => 21));
+
+ $mock->foo($testArray);
+ }
+
+ /**
+ * @expectedException Mockery\Exception\NoMatchingExpectationException
+ * @expectedExceptionMessage MyTestClass::foo(['a_scalar' => 2, 'a_resource' => resource(...)])
+ */
+ public function testHandlesMethodWithArgumentExpectationWhenCalledWithNestedResource()
+ {
+ $testArray = array();
+ $testArray['a_scalar'] = 2;
+ $testArray['a_resource'] = fopen('php://memory', 'r');
+
+ $mock = mock('MyTestClass');
+ $mock->shouldReceive('foo')->with(array('yourself' => 21));
+
+ $mock->foo($testArray);
+ }
+
+ public function testExceptionOutputMakesBooleansLookLikeBooleans()
+ {
+ $mock = mock('MyTestClass');
+ $mock->shouldReceive("foo")->with(123);
+
+ $this->expectException(
+ "Mockery\Exception\NoMatchingExpectationException",
+ "MyTestClass::foo(true, false, [0 => true, 1 => false])"
+ );
+
+ $mock->foo(true, false, [true, false]);
+ }
+
+ /**
+ * @test
+ * @group issue/339
+ */
+ public function canMockClassesThatDescendFromInternalClasses()
+ {
+ $mock = mock("MockeryTest_ClassThatDescendsFromInternalClass");
+ $this->assertInstanceOf("DateTime", $mock);
+ }
+
+ /**
+ * @test
+ * @group issue/339
+ */
+ public function canMockClassesThatImplementSerializable()
+ {
+ $mock = mock("MockeryTest_ClassThatImplementsSerializable");
+ $this->assertInstanceOf("Serializable", $mock);
+ }
+
+ /**
+ * @test
+ * @group issue/346
+ */
+ public function canMockInternalClassesThatImplementSerializable()
+ {
+ $mock = mock("ArrayObject");
+ $this->assertInstanceOf("Serializable", $mock);
+ }
+
+ /**
+ * @dataProvider classNameProvider
+ */
+ public function testIsValidClassName($expected, $className)
+ {
+ $container = new \Mockery\Container;
+ $this->assertSame($expected, $container->isValidClassName($className));
+ }
+
+ public function classNameProvider()
+ {
+ return array(
+ array(false, ' '), // just a space
+ array(false, 'ClassName.WithDot'),
+ array(false, '\\\\TooManyBackSlashes'),
+ array(true, 'Foo'),
+ array(true, '\\Foo\\Bar'),
+ );
+ }
+}
+
+class MockeryTest_CallStatic
+{
+ public static function __callStatic($method, $args)
+ {
+ }
+}
+
+class MockeryTest_ClassMultipleConstructorParams
+{
+ public function __construct($a, $b)
+ {
+ }
+
+ public function dave()
+ {
+ }
+}
+
+interface MockeryTest_InterfaceWithTraversable extends ArrayAccess, Traversable, Countable
+{
+ public function self();
+}
+
+class MockeryTestIsset_Bar
+{
+ public function doSomething()
+ {
+ }
+}
+
+class MockeryTestIsset_Foo
+{
+ private $var;
+
+ public function __construct($var)
+ {
+ $this->var = $var;
+ }
+
+ public function __get($name)
+ {
+ $this->var->doSomething();
+ }
+
+ public function __isset($name)
+ {
+ return (bool) strlen($this->__get($name));
+ }
+}
+
+class MockeryTest_IssetMethod
+{
+ protected $_properties = array();
+
+ public function __construct()
+ {
+ }
+
+ public function __isset($property)
+ {
+ return isset($this->_properties[$property]);
+ }
+}
+
+class MockeryTest_UnsetMethod
+{
+ protected $_properties = array();
+
+ public function __construct()
+ {
+ }
+
+ public function __unset($property)
+ {
+ unset($this->_properties[$property]);
+ }
+}
+
+class MockeryTestFoo
+{
+ public function foo()
+ {
+ return 'foo';
+ }
+}
+
+class MockeryTestFoo2
+{
+ public function foo()
+ {
+ return 'foo';
+ }
+
+ public function bar()
+ {
+ return 'bar';
+ }
+}
+
+final class MockeryFoo3
+{
+ public function foo()
+ {
+ return 'baz';
+ }
+}
+
+class MockeryFoo4
+{
+ final public function foo()
+ {
+ return 'baz';
+ }
+
+ public function bar()
+ {
+ return 'bar';
+ }
+}
+
+interface MockeryTest_Interface
+{
+}
+interface MockeryTest_Interface1
+{
+}
+interface MockeryTest_Interface2
+{
+}
+
+interface MockeryTest_InterfaceWithAbstractMethod
+{
+ public function set();
+}
+
+interface MockeryTest_InterfaceWithPublicStaticMethod
+{
+ public static function self();
+}
+
+abstract class MockeryTest_AbstractWithAbstractMethod
+{
+ abstract protected function set();
+}
+
+class MockeryTest_WithProtectedAndPrivate
+{
+ protected function protectedMethod()
+ {
+ }
+
+ private function privateMethod()
+ {
+ }
+}
+
+class MockeryTest_ClassConstructor
+{
+ public function __construct($param1)
+ {
+ }
+}
+
+class MockeryTest_ClassConstructor2
+{
+ protected $param1;
+
+ public function __construct(stdClass $param1)
+ {
+ $this->param1 = $param1;
+ }
+
+ public function getParam1()
+ {
+ return $this->param1;
+ }
+
+ public function foo()
+ {
+ return 'foo';
+ }
+
+ public function bar()
+ {
+ return $this->foo();
+ }
+}
+
+class MockeryTest_Call1
+{
+ public function __call($method, array $params)
+ {
+ }
+}
+
+class MockeryTest_Call2
+{
+ public function __call($method, $params)
+ {
+ }
+}
+
+class MockeryTest_Wakeup1
+{
+ public function __construct()
+ {
+ }
+
+ public function __wakeup()
+ {
+ }
+}
+
+class MockeryTest_ExistingProperty
+{
+ public $foo = 'bar';
+}
+
+abstract class MockeryTest_AbstractWithAbstractPublicMethod
+{
+ abstract public function foo($a, $b);
+}
+
+// issue/18
+class SoCool
+{
+ public function iDoSomethingReallyCoolHere()
+ {
+ return 3;
+ }
+}
+
+class Gateway
+{
+ public function __call($method, $args)
+ {
+ $m = new SoCool();
+ return call_user_func_array(array($m, $method), $args);
+ }
+}
+
+class MockeryTestBar1
+{
+ public function method1()
+ {
+ return $this;
+ }
+}
+
+class MockeryTest_ReturnByRef
+{
+ public $i = 0;
+
+ public function &get()
+ {
+ return $this->$i;
+ }
+}
+
+class MockeryTest_MethodParamRef
+{
+ public function method1(&$foo)
+ {
+ return true;
+ }
+}
+class MockeryTest_MethodParamRef2
+{
+ public function method1(&$foo)
+ {
+ return true;
+ }
+}
+class MockeryTestRef1
+{
+ public function foo(&$a, $b)
+ {
+ }
+}
+
+class MockeryTest_PartialNormalClass
+{
+ public function foo()
+ {
+ return 'abc';
+ }
+
+ public function bar()
+ {
+ return 'abc';
+ }
+}
+
+abstract class MockeryTest_PartialAbstractClass
+{
+ abstract public function foo();
+
+ public function bar()
+ {
+ return 'abc';
+ }
+}
+
+class MockeryTest_PartialNormalClass2
+{
+ public function foo()
+ {
+ return 'abc';
+ }
+
+ public function bar()
+ {
+ return 'abc';
+ }
+
+ public function baz()
+ {
+ return 'abc';
+ }
+}
+
+abstract class MockeryTest_PartialAbstractClass2
+{
+ abstract public function foo();
+
+ public function bar()
+ {
+ return 'abc';
+ }
+
+ abstract public function baz();
+}
+
+class MockeryTest_TestInheritedType
+{
+}
+
+if (PHP_VERSION_ID >= 50400) {
+ class MockeryTest_MockCallableTypeHint
+ {
+ public function foo(callable $baz)
+ {
+ $baz();
+ }
+
+ public function bar(callable $callback = null)
+ {
+ $callback();
+ }
+ }
+}
+
+class MockeryTest_WithToString
+{
+ public function __toString()
+ {
+ }
+}
+
+class MockeryTest_ImplementsIteratorAggregate implements IteratorAggregate
+{
+ public function getIterator()
+ {
+ return new ArrayIterator(array());
+ }
+}
+
+class MockeryTest_ImplementsIterator implements Iterator
+{
+ public function rewind()
+ {
+ }
+
+ public function current()
+ {
+ }
+
+ public function key()
+ {
+ }
+
+ public function next()
+ {
+ }
+
+ public function valid()
+ {
+ }
+}
+
+class EmptyConstructorTest
+{
+ public $numberOfConstructorArgs;
+
+ public function __construct(...$args)
+ {
+ $this->numberOfConstructorArgs = count($args);
+ }
+
+ public function foo()
+ {
+ }
+}
+
+interface MockeryTest_InterfaceWithMethodParamSelf
+{
+ public function foo(self $bar);
+}
+
+class MockeryTest_Lowercase_ToString
+{
+ public function __tostring()
+ {
+ }
+}
+
+class MockeryTest_PartialStatic
+{
+ public static function mockMe($a)
+ {
+ return $a;
+ }
+
+ public static function keepMe($b)
+ {
+ return $b;
+ }
+}
+
+class MockeryTest_MethodWithRequiredParamWithDefaultValue
+{
+ public function foo(DateTime $bar = null, $baz)
+ {
+ }
+}
+
+interface MockeryTest_InterfaceThatExtendsIterator extends Iterator
+{
+ public function foo();
+}
+
+interface MockeryTest_InterfaceThatExtendsIteratorAggregate extends IteratorAggregate
+{
+ public function foo();
+}
+
+class MockeryTest_ClassThatDescendsFromInternalClass extends DateTime
+{
+}
+
+class MockeryTest_ClassThatImplementsSerializable implements Serializable
+{
+ public function serialize()
+ {
+ }
+
+ public function unserialize($serialized)
+ {
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/DemeterChainTest.php b/vendor/mockery/mockery/tests/Mockery/DemeterChainTest.php
new file mode 100644
index 0000000..9528d16
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/DemeterChainTest.php
@@ -0,0 +1,204 @@
+= 0) {
+ require_once __DIR__.'/DummyClasses/DemeterChain.php';
+}
+
+use Mockery\Adapter\Phpunit\MockeryTestCase;
+
+class DemeterChainTest extends MockeryTestCase
+{
+ /** @var Mockery\Mock $this->mock */
+ private $mock;
+
+ public function setUp()
+ {
+ $this->mock = $this->mock = Mockery::mock()->shouldIgnoreMissing();
+ }
+
+ public function tearDown()
+ {
+ $this->mock->mockery_getContainer()->mockery_close();
+ }
+
+ public function testTwoChains()
+ {
+ $this->mock->shouldReceive('getElement->getFirst')
+ ->once()
+ ->andReturn('something');
+
+ $this->mock->shouldReceive('getElement->getSecond')
+ ->once()
+ ->andReturn('somethingElse');
+
+ $this->assertEquals(
+ 'something',
+ $this->mock->getElement()->getFirst()
+ );
+ $this->assertEquals(
+ 'somethingElse',
+ $this->mock->getElement()->getSecond()
+ );
+ $this->mock->mockery_getContainer()->mockery_close();
+ }
+
+ public function testTwoChainsWithExpectedParameters()
+ {
+ $this->mock->shouldReceive('getElement->getFirst')
+ ->once()
+ ->with('parameter')
+ ->andReturn('something');
+
+ $this->mock->shouldReceive('getElement->getSecond')
+ ->once()
+ ->with('secondParameter')
+ ->andReturn('somethingElse');
+
+ $this->assertEquals(
+ 'something',
+ $this->mock->getElement()->getFirst('parameter')
+ );
+ $this->assertEquals(
+ 'somethingElse',
+ $this->mock->getElement()->getSecond('secondParameter')
+ );
+ $this->mock->mockery_getContainer()->mockery_close();
+ }
+
+ public function testThreeChains()
+ {
+ $this->mock->shouldReceive('getElement->getFirst')
+ ->once()
+ ->andReturn('something');
+
+ $this->mock->shouldReceive('getElement->getSecond')
+ ->once()
+ ->andReturn('somethingElse');
+
+ $this->assertEquals(
+ 'something',
+ $this->mock->getElement()->getFirst()
+ );
+ $this->assertEquals(
+ 'somethingElse',
+ $this->mock->getElement()->getSecond()
+ );
+ $this->mock->shouldReceive('getElement->getFirst')
+ ->once()
+ ->andReturn('somethingNew');
+ $this->assertEquals(
+ 'somethingNew',
+ $this->mock->getElement()->getFirst()
+ );
+ }
+
+ public function testManyChains()
+ {
+ $this->mock->shouldReceive('getElements->getFirst')
+ ->once()
+ ->andReturn('something');
+
+ $this->mock->shouldReceive('getElements->getSecond')
+ ->once()
+ ->andReturn('somethingElse');
+
+ $this->mock->getElements()->getFirst();
+ $this->mock->getElements()->getSecond();
+ }
+
+ public function testTwoNotRelatedChains()
+ {
+ $this->mock->shouldReceive('getElement->getFirst')
+ ->once()
+ ->andReturn('something');
+
+ $this->mock->shouldReceive('getOtherElement->getSecond')
+ ->once()
+ ->andReturn('somethingElse');
+
+ $this->assertEquals(
+ 'somethingElse',
+ $this->mock->getOtherElement()->getSecond()
+ );
+ $this->assertEquals(
+ 'something',
+ $this->mock->getElement()->getFirst()
+ );
+ }
+
+ public function testDemeterChain()
+ {
+ $this->mock->shouldReceive('getElement->getFirst')
+ ->once()
+ ->andReturn('somethingElse');
+
+ $this->assertEquals('somethingElse', $this->mock->getElement()->getFirst());
+ }
+
+ public function testMultiLevelDemeterChain()
+ {
+ $this->mock->shouldReceive('levelOne->levelTwo->getFirst')
+ ->andReturn('first');
+
+ $this->mock->shouldReceive('levelOne->levelTwo->getSecond')
+ ->andReturn('second');
+
+ $this->assertEquals(
+ 'second',
+ $this->mock->levelOne()->levelTwo()->getSecond()
+ );
+ $this->assertEquals(
+ 'first',
+ $this->mock->levelOne()->levelTwo()->getFirst()
+ );
+ }
+
+ public function testSimilarDemeterChainsOnDifferentClasses()
+ {
+ $mock1 = Mockery::mock('overload:mock1');
+ $mock1->shouldReceive('select->some->data')->andReturn(1);
+ $mock1->shouldReceive('select->some->other->data')->andReturn(2);
+
+ $mock2 = Mockery::mock('overload:mock2');
+ $mock2->shouldReceive('select->some->data')->andReturn(3);
+ $mock2->shouldReceive('select->some->other->data')->andReturn(4);
+
+ $this->assertEquals(1, mock1::select()->some()->data());
+ $this->assertEquals(2, mock1::select()->some()->other()->data());
+ $this->assertEquals(3, mock2::select()->some()->data());
+ $this->assertEquals(4, mock2::select()->some()->other()->data());
+ }
+
+ /**
+ * @requires PHP 7.0.0
+ */
+ public function testDemeterChainsWithClassReturnTypeHints()
+ {
+ $a = \Mockery::mock(\DemeterChain\A::class);
+ $a->shouldReceive('foo->bar->baz')->andReturn(new stdClass);
+
+ $m = new \DemeterChain\Main();
+ $result = $m->callDemeter($a);
+
+ $this->assertInstanceOf(stdClass::class, $result);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/DummyClasses/DemeterChain.php b/vendor/mockery/mockery/tests/Mockery/DummyClasses/DemeterChain.php
new file mode 100644
index 0000000..b778cd4
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/DummyClasses/DemeterChain.php
@@ -0,0 +1,54 @@
+foo()->bar()->baz();
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/DummyClasses/Namespaced.php b/vendor/mockery/mockery/tests/Mockery/DummyClasses/Namespaced.php
new file mode 100644
index 0000000..615eb71
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/DummyClasses/Namespaced.php
@@ -0,0 +1,35 @@
+mock = mock();
+ }
+
+ public function teardown()
+ {
+ parent::tearDown();
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(true);
+ }
+
+ public function testReturnsNullWhenNoArgs()
+ {
+ $this->mock->shouldReceive('foo');
+ $this->assertNull($this->mock->foo());
+ }
+
+ public function testReturnsNullWhenSingleArg()
+ {
+ $this->mock->shouldReceive('foo');
+ $this->assertNull($this->mock->foo(1));
+ }
+
+ public function testReturnsNullWhenManyArgs()
+ {
+ $this->mock->shouldReceive('foo');
+ $this->assertNull($this->mock->foo('foo', array(), new stdClass));
+ }
+
+ public function testReturnsNullIfNullIsReturnValue()
+ {
+ $this->mock->shouldReceive('foo')->andReturn(null);
+ $this->assertNull($this->mock->foo());
+ }
+
+ public function testReturnsNullForMockedExistingClassIfAndreturnnullCalled()
+ {
+ $mock = mock('MockeryTest_Foo');
+ $mock->shouldReceive('foo')->andReturn(null);
+ $this->assertNull($mock->foo());
+ }
+
+ public function testReturnsNullForMockedExistingClassIfNullIsReturnValue()
+ {
+ $mock = mock('MockeryTest_Foo');
+ $mock->shouldReceive('foo')->andReturnNull();
+ $this->assertNull($mock->foo());
+ }
+
+ public function testReturnsSameValueForAllIfNoArgsExpectationAndNoneGiven()
+ {
+ $this->mock->shouldReceive('foo')->andReturn(1);
+ $this->assertEquals(1, $this->mock->foo());
+ }
+
+ public function testSetsPublicPropertyWhenRequested()
+ {
+ $this->mock->bar = null;
+ $this->mock->shouldReceive('foo')->andSet('bar', 'baz');
+ $this->assertNull($this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('baz', $this->mock->bar);
+ }
+
+ public function testSetsPublicPropertyWhenRequestedUsingAlias()
+ {
+ $this->mock->bar = null;
+ $this->mock->shouldReceive('foo')->set('bar', 'baz');
+ $this->assertNull($this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('baz', $this->mock->bar);
+ }
+
+ public function testSetsPublicPropertiesWhenRequested()
+ {
+ $this->mock->bar = null;
+ $this->mock->shouldReceive('foo')->andSet('bar', 'baz', 'bazz', 'bazzz');
+ $this->assertNull($this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('baz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazzz', $this->mock->bar);
+ }
+
+ public function testSetsPublicPropertiesWhenRequestedUsingAlias()
+ {
+ $this->mock->bar = null;
+ $this->mock->shouldReceive('foo')->set('bar', 'baz', 'bazz', 'bazzz');
+ $this->assertAttributeEmpty('bar', $this->mock);
+ $this->mock->foo();
+ $this->assertEquals('baz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazzz', $this->mock->bar);
+ }
+
+ public function testSetsPublicPropertiesWhenRequestedMoreTimesThanSetValues()
+ {
+ $this->mock->bar = null;
+ $this->mock->shouldReceive('foo')->andSet('bar', 'baz', 'bazz');
+ $this->assertNull($this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('baz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazz', $this->mock->bar);
+ }
+
+ public function testSetsPublicPropertiesWhenRequestedMoreTimesThanSetValuesUsingAlias()
+ {
+ $this->mock->bar = null;
+ $this->mock->shouldReceive('foo')->andSet('bar', 'baz', 'bazz');
+ $this->assertNull($this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('baz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazz', $this->mock->bar);
+ }
+
+ public function testSetsPublicPropertiesWhenRequestedMoreTimesThanSetValuesWithDirectSet()
+ {
+ $this->mock->bar = null;
+ $this->mock->shouldReceive('foo')->andSet('bar', 'baz', 'bazz');
+ $this->assertNull($this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('baz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazz', $this->mock->bar);
+ $this->mock->bar = null;
+ $this->mock->foo();
+ $this->assertNull($this->mock->bar);
+ }
+
+ public function testSetsPublicPropertiesWhenRequestedMoreTimesThanSetValuesWithDirectSetUsingAlias()
+ {
+ $this->mock->bar = null;
+ $this->mock->shouldReceive('foo')->set('bar', 'baz', 'bazz');
+ $this->assertNull($this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('baz', $this->mock->bar);
+ $this->mock->foo();
+ $this->assertEquals('bazz', $this->mock->bar);
+ $this->mock->bar = null;
+ $this->mock->foo();
+ $this->assertNull($this->mock->bar);
+ }
+
+ public function testReturnsSameValueForAllIfNoArgsExpectationAndSomeGiven()
+ {
+ $this->mock->shouldReceive('foo')->andReturn(1);
+ $this->assertEquals(1, $this->mock->foo('foo'));
+ }
+
+ public function testReturnsValueFromSequenceSequentially()
+ {
+ $this->mock->shouldReceive('foo')->andReturn(1, 2, 3);
+ $this->mock->foo('foo');
+ $this->assertEquals(2, $this->mock->foo('foo'));
+ }
+
+ public function testReturnsValueFromSequenceSequentiallyAndRepeatedlyReturnsFinalValueOnExtraCalls()
+ {
+ $this->mock->shouldReceive('foo')->andReturn(1, 2, 3);
+ $this->mock->foo('foo');
+ $this->mock->foo('foo');
+ $this->assertEquals(3, $this->mock->foo('foo'));
+ $this->assertEquals(3, $this->mock->foo('foo'));
+ }
+
+ public function testReturnsValueFromSequenceSequentiallyAndRepeatedlyReturnsFinalValueOnExtraCallsWithManyAndReturnCalls()
+ {
+ $this->mock->shouldReceive('foo')->andReturn(1)->andReturn(2, 3);
+ $this->mock->foo('foo');
+ $this->mock->foo('foo');
+ $this->assertEquals(3, $this->mock->foo('foo'));
+ $this->assertEquals(3, $this->mock->foo('foo'));
+ }
+
+ public function testReturnsValueOfClosure()
+ {
+ $this->mock->shouldReceive('foo')->with(5)->andReturnUsing(function ($v) {
+ return $v+1;
+ });
+ $this->assertEquals(6, $this->mock->foo(5));
+ }
+
+ public function testReturnsUndefined()
+ {
+ $this->mock->shouldReceive('foo')->andReturnUndefined();
+ $this->assertInstanceOf(\Mockery\Undefined::class, $this->mock->foo());
+ }
+
+ public function testReturnsValuesSetAsArray()
+ {
+ $this->mock->shouldReceive('foo')->andReturnValues(array(1, 2, 3));
+ $this->assertEquals(1, $this->mock->foo());
+ $this->assertEquals(2, $this->mock->foo());
+ $this->assertEquals(3, $this->mock->foo());
+ }
+
+ /**
+ * @expectedException OutOfBoundsException
+ */
+ public function testThrowsException()
+ {
+ $this->mock->shouldReceive('foo')->andThrow(new OutOfBoundsException);
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ /** @test */
+ public function and_throws_is_an_alias_to_and_throw()
+ {
+ $this->mock->shouldReceive('foo')->andThrows(new OutOfBoundsException);
+
+ $this->expectException(OutOfBoundsException::class);
+ $this->mock->foo();
+ }
+
+ /**
+ * @test
+ * @requires PHP 7.0.0
+ */
+ public function it_can_throw_a_throwable()
+ {
+ $this->expectException(\Error::class);
+ $this->mock->shouldReceive('foo')->andThrow(new \Error());
+ $this->mock->foo();
+ }
+
+ /**
+ * @expectedException OutOfBoundsException
+ */
+ public function testThrowsExceptionBasedOnArgs()
+ {
+ $this->mock->shouldReceive('foo')->andThrow('OutOfBoundsException');
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testThrowsExceptionBasedOnArgsWithMessage()
+ {
+ $this->mock->shouldReceive('foo')->andThrow('OutOfBoundsException', 'foo');
+ try {
+ $this->mock->foo();
+ } catch (OutOfBoundsException $e) {
+ $this->assertEquals('foo', $e->getMessage());
+ }
+ }
+
+ /**
+ * @expectedException OutOfBoundsException
+ */
+ public function testThrowsExceptionSequentially()
+ {
+ $this->mock->shouldReceive('foo')->andThrow(new Exception)->andThrow(new OutOfBoundsException);
+ try {
+ $this->mock->foo();
+ } catch (Exception $e) {
+ }
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testAndThrowExceptions()
+ {
+ $this->mock->shouldReceive('foo')->andThrowExceptions(array(
+ new OutOfBoundsException,
+ new InvalidArgumentException,
+ ));
+
+ try {
+ $this->mock->foo();
+ throw new Exception("Expected OutOfBoundsException, non thrown");
+ } catch (\Exception $e) {
+ $this->assertInstanceOf("OutOfBoundsException", $e, "Wrong or no exception thrown: {$e->getMessage()}");
+ }
+
+ try {
+ $this->mock->foo();
+ throw new Exception("Expected InvalidArgumentException, non thrown");
+ } catch (\Exception $e) {
+ $this->assertInstanceOf("InvalidArgumentException", $e, "Wrong or no exception thrown: {$e->getMessage()}");
+ }
+ }
+
+ /**
+ * @expectedException Mockery\Exception
+ * @expectedExceptionMessage You must pass an array of exception objects to andThrowExceptions
+ */
+ public function testAndThrowExceptionsCatchNonExceptionArgument()
+ {
+ $this->mock
+ ->shouldReceive('foo')
+ ->andThrowExceptions(array('NotAnException'));
+ Mockery::close();
+ }
+
+ public function testMultipleExpectationsWithReturns()
+ {
+ $this->mock->shouldReceive('foo')->with(1)->andReturn(10);
+ $this->mock->shouldReceive('bar')->with(2)->andReturn(20);
+ $this->assertEquals(10, $this->mock->foo(1));
+ $this->assertEquals(20, $this->mock->bar(2));
+ }
+
+ public function testExpectsNoArguments()
+ {
+ $this->mock->shouldReceive('foo')->withNoArgs();
+ $this->mock->foo();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testExpectsNoArgumentsThrowsExceptionIfAnyPassed()
+ {
+ $this->mock->shouldReceive('foo')->withNoArgs();
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ public function testExpectsArgumentsArray()
+ {
+ $this->mock->shouldReceive('foo')->withArgs(array(1, 2));
+ $this->mock->foo(1, 2);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testExpectsArgumentsArrayThrowsExceptionIfPassedEmptyArray()
+ {
+ $this->mock->shouldReceive('foo')->withArgs(array());
+ $this->mock->foo(1, 2);
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testExpectsArgumentsArrayThrowsExceptionIfNoArgumentsPassed()
+ {
+ $this->mock->shouldReceive('foo')->with();
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testExpectsArgumentsArrayThrowsExceptionIfPassedWrongArguments()
+ {
+ $this->mock->shouldReceive('foo')->withArgs(array(1, 2));
+ $this->mock->foo(3, 4);
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ * @expectedExceptionMessageRegExp /foo\(NULL\)/
+ */
+ public function testExpectsStringArgumentExceptionMessageDifferentiatesBetweenNullAndEmptyString()
+ {
+ $this->mock->shouldReceive('foo')->withArgs(array('a string'));
+ $this->mock->foo(null);
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessageRegExp /invalid argument (.+), only array and closure are allowed/
+ */
+ public function testExpectsArgumentsArrayThrowsExceptionIfPassedWrongArgumentType()
+ {
+ $this->mock->shouldReceive('foo')->withArgs(5);
+ Mockery::close();
+ }
+
+ public function testExpectsArgumentsArrayAcceptAClosureThatValidatesPassedArguments()
+ {
+ $closure = function ($odd, $even) {
+ return ($odd % 2 != 0) && ($even % 2 == 0);
+ };
+ $this->mock->shouldReceive('foo')->withArgs($closure);
+ $this->mock->foo(1, 2);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testExpectsArgumentsArrayThrowsExceptionWhenClosureEvaluatesToFalse()
+ {
+ $closure = function ($odd, $even) {
+ return ($odd % 2 != 0) && ($even % 2 == 0);
+ };
+ $this->mock->shouldReceive('foo')->withArgs($closure);
+ $this->mock->foo(4, 2);
+ Mockery::close();
+ }
+
+ public function testExpectsArgumentsArrayClosureDoesNotThrowExceptionIfOptionalArgumentsAreMissing()
+ {
+ $closure = function ($odd, $even, $sum = null) {
+ $result = ($odd % 2 != 0) && ($even % 2 == 0);
+ if (!is_null($sum)) {
+ return $result && ($odd + $even == $sum);
+ }
+ return $result;
+ };
+ $this->mock->shouldReceive('foo')->withArgs($closure);
+ $this->mock->foo(1, 4);
+ }
+
+ public function testExpectsArgumentsArrayClosureDoesNotThrowExceptionIfOptionalArgumentsMathTheExpectation()
+ {
+ $closure = function ($odd, $even, $sum = null) {
+ $result = ($odd % 2 != 0) && ($even % 2 == 0);
+ if (!is_null($sum)) {
+ return $result && ($odd + $even == $sum);
+ }
+ return $result;
+ };
+ $this->mock->shouldReceive('foo')->withArgs($closure);
+ $this->mock->foo(1, 4, 5);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testExpectsArgumentsArrayClosureThrowsExceptionIfOptionalArgumentsDontMatchTheExpectation()
+ {
+ $closure = function ($odd, $even, $sum = null) {
+ $result = ($odd % 2 != 0) && ($even % 2 == 0);
+ if (!is_null($sum)) {
+ return $result && ($odd + $even == $sum);
+ }
+ return $result;
+ };
+ $this->mock->shouldReceive('foo')->withArgs($closure);
+ $this->mock->foo(1, 4, 2);
+ Mockery::close();
+ }
+
+ public function testExpectsAnyArguments()
+ {
+ $this->mock->shouldReceive('foo')->withAnyArgs();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 'k', new stdClass);
+ }
+
+ public function testExpectsArgumentMatchingObjectType()
+ {
+ $this->mock->shouldReceive('foo')->with('\stdClass');
+ $this->mock->foo(new stdClass);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testThrowsExceptionOnNoArgumentMatch()
+ {
+ $this->mock->shouldReceive('foo')->with(1);
+ $this->mock->foo(2);
+ Mockery::close();
+ }
+
+ public function testNeverCalled()
+ {
+ $this->mock->shouldReceive('foo')->never();
+ }
+
+ public function testShouldNotReceive()
+ {
+ $this->mock->shouldNotReceive('foo');
+ }
+
+ /**
+ * @expectedException \Mockery\Exception\InvalidCountException
+ */
+ public function testShouldNotReceiveThrowsExceptionIfMethodCalled()
+ {
+ $this->mock->shouldNotReceive('foo');
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception\InvalidCountException
+ */
+ public function testShouldNotReceiveWithArgumentThrowsExceptionIfMethodCalled()
+ {
+ $this->mock->shouldNotReceive('foo')->with(2);
+ $this->mock->foo(2);
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testNeverCalledThrowsExceptionOnCall()
+ {
+ $this->mock->shouldReceive('foo')->never();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testCalledOnce()
+ {
+ $this->mock->shouldReceive('foo')->once();
+ $this->mock->foo();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testCalledOnceThrowsExceptionIfNotCalled()
+ {
+ $this->mock->shouldReceive('foo')->once();
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testCalledOnceThrowsExceptionIfCalledTwice()
+ {
+ $this->mock->shouldReceive('foo')->once();
+ $this->mock->foo();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testCalledTwice()
+ {
+ $this->mock->shouldReceive('foo')->twice();
+ $this->mock->foo();
+ $this->mock->foo();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testCalledTwiceThrowsExceptionIfNotCalled()
+ {
+ $this->mock->shouldReceive('foo')->twice();
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testCalledOnceThrowsExceptionIfCalledThreeTimes()
+ {
+ $this->mock->shouldReceive('foo')->twice();
+ $this->mock->foo();
+ $this->mock->foo();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testCalledZeroOrMoreTimesAtZeroCalls()
+ {
+ $this->mock->shouldReceive('foo')->zeroOrMoreTimes();
+ }
+
+ public function testCalledZeroOrMoreTimesAtThreeCalls()
+ {
+ $this->mock->shouldReceive('foo')->zeroOrMoreTimes();
+ $this->mock->foo();
+ $this->mock->foo();
+ $this->mock->foo();
+ }
+
+ public function testTimesCountCalls()
+ {
+ $this->mock->shouldReceive('foo')->times(4);
+ $this->mock->foo();
+ $this->mock->foo();
+ $this->mock->foo();
+ $this->mock->foo();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testTimesCountCallThrowsExceptionOnTooFewCalls()
+ {
+ $this->mock->shouldReceive('foo')->times(2);
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testTimesCountCallThrowsExceptionOnTooManyCalls()
+ {
+ $this->mock->shouldReceive('foo')->times(2);
+ $this->mock->foo();
+ $this->mock->foo();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testCalledAtLeastOnceAtExactlyOneCall()
+ {
+ $this->mock->shouldReceive('foo')->atLeast()->once();
+ $this->mock->foo();
+ }
+
+ public function testCalledAtLeastOnceAtExactlyThreeCalls()
+ {
+ $this->mock->shouldReceive('foo')->atLeast()->times(3);
+ $this->mock->foo();
+ $this->mock->foo();
+ $this->mock->foo();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testCalledAtLeastThrowsExceptionOnTooFewCalls()
+ {
+ $this->mock->shouldReceive('foo')->atLeast()->twice();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testCalledAtMostOnceAtExactlyOneCall()
+ {
+ $this->mock->shouldReceive('foo')->atMost()->once();
+ $this->mock->foo();
+ }
+
+ public function testCalledAtMostAtExactlyThreeCalls()
+ {
+ $this->mock->shouldReceive('foo')->atMost()->times(3);
+ $this->mock->foo();
+ $this->mock->foo();
+ $this->mock->foo();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testCalledAtLeastThrowsExceptionOnTooManyCalls()
+ {
+ $this->mock->shouldReceive('foo')->atMost()->twice();
+ $this->mock->foo();
+ $this->mock->foo();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testExactCountersOverrideAnyPriorSetNonExactCounters()
+ {
+ $this->mock->shouldReceive('foo')->atLeast()->once()->once();
+ $this->mock->foo();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testComboOfLeastAndMostCallsWithOneCall()
+ {
+ $this->mock->shouldReceive('foo')->atleast()->once()->atMost()->twice();
+ $this->mock->foo();
+ }
+
+ public function testComboOfLeastAndMostCallsWithTwoCalls()
+ {
+ $this->mock->shouldReceive('foo')->atleast()->once()->atMost()->twice();
+ $this->mock->foo();
+ $this->mock->foo();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testComboOfLeastAndMostCallsThrowsExceptionAtTooFewCalls()
+ {
+ $this->mock->shouldReceive('foo')->atleast()->once()->atMost()->twice();
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testComboOfLeastAndMostCallsThrowsExceptionAtTooManyCalls()
+ {
+ $this->mock->shouldReceive('foo')->atleast()->once()->atMost()->twice();
+ $this->mock->foo();
+ $this->mock->foo();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testCallCountingOnlyAppliesToMatchedExpectations()
+ {
+ $this->mock->shouldReceive('foo')->with(1)->once();
+ $this->mock->shouldReceive('foo')->with(2)->twice();
+ $this->mock->shouldReceive('foo')->with(3);
+ $this->mock->foo(1);
+ $this->mock->foo(2);
+ $this->mock->foo(2);
+ $this->mock->foo(3);
+ }
+
+ /**
+ * @expectedException \Mockery\CountValidator\Exception
+ */
+ public function testCallCountingThrowsExceptionOnAnyMismatch()
+ {
+ $this->mock->shouldReceive('foo')->with(1)->once();
+ $this->mock->shouldReceive('foo')->with(2)->twice();
+ $this->mock->shouldReceive('foo')->with(3);
+ $this->mock->shouldReceive('bar');
+ $this->mock->foo(1);
+ $this->mock->foo(2);
+ $this->mock->foo(3);
+ $this->mock->bar();
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception\InvalidCountException
+ */
+ public function testCallCountingThrowsExceptionFirst()
+ {
+ $number_of_calls = 0;
+ $this->mock->shouldReceive('foo')
+ ->times(2)
+ ->with(\Mockery::on(function ($argument) use (&$number_of_calls) {
+ $number_of_calls++;
+ return $number_of_calls <= 3;
+ }));
+
+ $this->mock->foo(1);
+ $this->mock->foo(1);
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ public function testOrderedCallsWithoutError()
+ {
+ $this->mock->shouldReceive('foo')->ordered();
+ $this->mock->shouldReceive('bar')->ordered();
+ $this->mock->foo();
+ $this->mock->bar();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testOrderedCallsWithOutOfOrderError()
+ {
+ $this->mock->shouldReceive('foo')->ordered();
+ $this->mock->shouldReceive('bar')->ordered();
+ $this->mock->bar();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testDifferentArgumentsAndOrderingsPassWithoutException()
+ {
+ $this->mock->shouldReceive('foo')->with(1)->ordered();
+ $this->mock->shouldReceive('foo')->with(2)->ordered();
+ $this->mock->foo(1);
+ $this->mock->foo(2);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testDifferentArgumentsAndOrderingsThrowExceptionWhenInWrongOrder()
+ {
+ $this->mock->shouldReceive('foo')->with(1)->ordered();
+ $this->mock->shouldReceive('foo')->with(2)->ordered();
+ $this->mock->foo(2);
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ public function testUnorderedCallsIgnoredForOrdering()
+ {
+ $this->mock->shouldReceive('foo')->with(1)->ordered();
+ $this->mock->shouldReceive('foo')->with(2);
+ $this->mock->shouldReceive('foo')->with(3)->ordered();
+ $this->mock->foo(2);
+ $this->mock->foo(1);
+ $this->mock->foo(2);
+ $this->mock->foo(3);
+ $this->mock->foo(2);
+ }
+
+ public function testOrderingOfDefaultGrouping()
+ {
+ $this->mock->shouldReceive('foo')->ordered();
+ $this->mock->shouldReceive('bar')->ordered();
+ $this->mock->foo();
+ $this->mock->bar();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testOrderingOfDefaultGroupingThrowsExceptionOnWrongOrder()
+ {
+ $this->mock->shouldReceive('foo')->ordered();
+ $this->mock->shouldReceive('bar')->ordered();
+ $this->mock->bar();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testOrderingUsingNumberedGroups()
+ {
+ $this->mock->shouldReceive('start')->ordered(1);
+ $this->mock->shouldReceive('foo')->ordered(2);
+ $this->mock->shouldReceive('bar')->ordered(2);
+ $this->mock->shouldReceive('final')->ordered();
+ $this->mock->start();
+ $this->mock->bar();
+ $this->mock->foo();
+ $this->mock->bar();
+ $this->mock->final();
+ }
+
+ public function testOrderingUsingNamedGroups()
+ {
+ $this->mock->shouldReceive('start')->ordered('start');
+ $this->mock->shouldReceive('foo')->ordered('foobar');
+ $this->mock->shouldReceive('bar')->ordered('foobar');
+ $this->mock->shouldReceive('final')->ordered();
+ $this->mock->start();
+ $this->mock->bar();
+ $this->mock->foo();
+ $this->mock->bar();
+ $this->mock->final();
+ }
+
+ /**
+ * @group 2A
+ */
+ public function testGroupedUngroupedOrderingDoNotOverlap()
+ {
+ $s = $this->mock->shouldReceive('start')->ordered();
+ $m = $this->mock->shouldReceive('mid')->ordered('foobar');
+ $e = $this->mock->shouldReceive('end')->ordered();
+ $this->assertLessThan($m->getOrderNumber(), $s->getOrderNumber());
+ $this->assertLessThan($e->getOrderNumber(), $m->getOrderNumber());
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testGroupedOrderingThrowsExceptionWhenCallsDisordered()
+ {
+ $this->mock->shouldReceive('foo')->ordered('first');
+ $this->mock->shouldReceive('bar')->ordered('second');
+ $this->mock->bar();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testExpectationMatchingWithNoArgsOrderings()
+ {
+ $this->mock->shouldReceive('foo')->withNoArgs()->once()->ordered();
+ $this->mock->shouldReceive('bar')->withNoArgs()->once()->ordered();
+ $this->mock->shouldReceive('foo')->withNoArgs()->once()->ordered();
+ $this->mock->foo();
+ $this->mock->bar();
+ $this->mock->foo();
+ }
+
+ public function testExpectationMatchingWithAnyArgsOrderings()
+ {
+ $this->mock->shouldReceive('foo')->withAnyArgs()->once()->ordered();
+ $this->mock->shouldReceive('bar')->withAnyArgs()->once()->ordered();
+ $this->mock->shouldReceive('foo')->withAnyArgs()->once()->ordered();
+ $this->mock->foo();
+ $this->mock->bar();
+ $this->mock->foo();
+ }
+
+ public function testEnsuresOrderingIsNotCrossMockByDefault()
+ {
+ $this->mock->shouldReceive('foo')->ordered();
+ $mock2 = mock('bar');
+ $mock2->shouldReceive('bar')->ordered();
+ $mock2->bar();
+ $this->mock->foo();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testEnsuresOrderingIsCrossMockWhenGloballyFlagSet()
+ {
+ $this->mock->shouldReceive('foo')->globally()->ordered();
+ $mock2 = mock('bar');
+ $mock2->shouldReceive('bar')->globally()->ordered();
+ $mock2->bar();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testExpectationCastToStringFormatting()
+ {
+ $exp = $this->mock->shouldReceive('foo')->with(1, 'bar', new stdClass, array('Spam' => 'Ham', 'Bar' => 'Baz'));
+ $this->assertEquals("[foo(1, 'bar', object(stdClass), ['Spam' => 'Ham', 'Bar' => 'Baz'])]", (string) $exp);
+ }
+
+ public function testLongExpectationCastToStringFormatting()
+ {
+ $exp = $this->mock->shouldReceive('foo')->with(array('Spam' => 'Ham', 'Bar' => 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'Bar', 'Baz', 'End'));
+ $this->assertEquals("[foo(['Spam' => 'Ham', 'Bar' => 'Baz', 0 => 'Bar', 1 => 'Baz', 2 => 'Bar', 3 => 'Baz', 4 => 'Bar', 5 => 'Baz', 6 => 'Bar', 7 => 'Baz', 8 => 'Bar', 9 => 'Baz', 10 => 'Bar', 11 => 'Baz', 12 => 'Bar', 13 => 'Baz', 14 => 'Bar', 15 => 'Baz', 16 => 'Bar', 17 => 'Baz', 18 => 'Bar', 19 => 'Baz', 20 => 'Bar', 21 => 'Baz', 22 => 'Bar', 23 => 'Baz', 24 => 'Bar', 25 => 'Baz', 26 => 'Bar', 27 => 'Baz', 28 => 'Bar', 29 => 'Baz', 30 => 'Bar', 31 => 'Baz', 32 => 'Bar', 33 => 'Baz', 34 => 'Bar', 35 => 'Baz', 36 => 'Bar', 37 => 'Baz', 38 => 'Bar', 39 => 'Baz', 40 => 'Bar', 41 => 'Baz', 42 => 'Bar', 43 => 'Baz', 44 => 'Bar', 45 => 'Baz', 46 => 'Baz', 47 => 'Bar', 48 => 'Baz', 49 => 'Bar', 50 => 'Baz', 51 => 'Bar', 52 => 'Baz', 53 => 'Bar', 54 => 'Baz', 55 => 'Bar', 56 => 'Baz', 57 => 'Baz', 58 => 'Bar', 59 => 'Baz', 60 => 'Bar', 61 => 'Baz', 62 => 'Bar', 63 => 'Baz', 64 => 'Bar', 65 => 'Baz', 66 => 'Bar', 67 => 'Baz', 68 => 'Baz', 69 => 'Bar', 70 => 'Baz', 71 => 'Bar', 72 => 'Baz', 73 => 'Bar', 74 => 'Baz', 7...])]", (string) $exp);
+ }
+
+ public function testMultipleExpectationCastToStringFormatting()
+ {
+ $exp = $this->mock->shouldReceive('foo', 'bar')->with(1);
+ $this->assertEquals('[foo(1), bar(1)]', (string) $exp);
+ }
+
+ public function testGroupedOrderingWithLimitsAllowsMultipleReturnValues()
+ {
+ $this->mock->shouldReceive('foo')->with(2)->once()->andReturn('first');
+ $this->mock->shouldReceive('foo')->with(2)->twice()->andReturn('second/third');
+ $this->mock->shouldReceive('foo')->with(2)->andReturn('infinity');
+ $this->assertEquals('first', $this->mock->foo(2));
+ $this->assertEquals('second/third', $this->mock->foo(2));
+ $this->assertEquals('second/third', $this->mock->foo(2));
+ $this->assertEquals('infinity', $this->mock->foo(2));
+ $this->assertEquals('infinity', $this->mock->foo(2));
+ $this->assertEquals('infinity', $this->mock->foo(2));
+ }
+
+ public function testExpectationsCanBeMarkedAsDefaults()
+ {
+ $this->mock->shouldReceive('foo')->andReturn('bar')->byDefault();
+ $this->assertEquals('bar', $this->mock->foo());
+ }
+
+ public function testDefaultExpectationsValidatedInCorrectOrder()
+ {
+ $this->mock->shouldReceive('foo')->with(1)->once()->andReturn('first')->byDefault();
+ $this->mock->shouldReceive('foo')->with(2)->once()->andReturn('second')->byDefault();
+ $this->assertEquals('first', $this->mock->foo(1));
+ $this->assertEquals('second', $this->mock->foo(2));
+ }
+
+ public function testDefaultExpectationsAreReplacedByLaterConcreteExpectations()
+ {
+ $this->mock->shouldReceive('foo')->andReturn('bar')->once()->byDefault();
+ $this->mock->shouldReceive('foo')->andReturn('baz')->twice();
+ $this->assertEquals('baz', $this->mock->foo());
+ $this->assertEquals('baz', $this->mock->foo());
+ }
+
+ public function testExpectationFallsBackToDefaultExpectationWhenConcreteExpectationsAreUsedUp()
+ {
+ $this->mock->shouldReceive('foo')->with(1)->andReturn('bar')->once()->byDefault();
+ $this->mock->shouldReceive('foo')->with(2)->andReturn('baz')->once();
+ $this->assertEquals('baz', $this->mock->foo(2));
+ $this->assertEquals('bar', $this->mock->foo(1));
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testDefaultExpectationsCanBeOrdered()
+ {
+ $this->mock->shouldReceive('foo')->ordered()->byDefault();
+ $this->mock->shouldReceive('bar')->ordered()->byDefault();
+ $this->mock->bar();
+ $this->mock->foo();
+ Mockery::close();
+ }
+
+ public function testDefaultExpectationsCanBeOrderedAndReplaced()
+ {
+ $this->mock->shouldReceive('foo')->ordered()->byDefault();
+ $this->mock->shouldReceive('bar')->ordered()->byDefault();
+ $this->mock->shouldReceive('bar')->ordered();
+ $this->mock->shouldReceive('foo')->ordered();
+ $this->mock->bar();
+ $this->mock->foo();
+ }
+
+ public function testByDefaultOperatesFromMockConstruction()
+ {
+ $container = new \Mockery\Container(\Mockery::getDefaultGenerator(), \Mockery::getDefaultLoader());
+ $mock = $container->mock('f', array('foo'=>'rfoo', 'bar'=>'rbar', 'baz'=>'rbaz'))->byDefault();
+ $mock->shouldReceive('foo')->andReturn('foobar');
+ $this->assertEquals('foobar', $mock->foo());
+ $this->assertEquals('rbar', $mock->bar());
+ $this->assertEquals('rbaz', $mock->baz());
+ }
+
+ public function testByDefaultOnAMockDoesSquatWithoutExpectations()
+ {
+ $this->assertInstanceOf(MockInterface::class, mock('f')->byDefault());
+ }
+
+ public function testDefaultExpectationsCanBeOverridden()
+ {
+ $this->mock->shouldReceive('foo')->with('test')->andReturn('bar')->byDefault();
+ $this->mock->shouldReceive('foo')->with('test')->andReturn('newbar')->byDefault();
+ $this->mock->foo('test');
+ $this->assertEquals('newbar', $this->mock->foo('test'));
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testByDefaultPreventedFromSettingDefaultWhenDefaultingExpectationWasReplaced()
+ {
+ $exp = $this->mock->shouldReceive('foo')->andReturn(1);
+ $this->mock->shouldReceive('foo')->andReturn(2);
+ $exp->byDefault();
+ Mockery::close();
+ }
+
+ /**
+ * Argument Constraint Tests
+ */
+
+ public function testAnyConstraintMatchesAnyArg()
+ {
+ $this->mock->shouldReceive('foo')->with(1, Mockery::any())->twice();
+ $this->mock->foo(1, 2);
+ $this->mock->foo(1, 'str');
+ }
+
+ public function testAnyConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::any())->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ public function testAndAnyOtherConstraintMatchesTheRestOfTheArguments()
+ {
+ $this->mock->shouldReceive('foo')->with(1, 2, Mockery::andAnyOthers())->twice();
+ $this->mock->foo(1, 2, 3, 4, 5);
+ $this->mock->foo(1, 'str', 3, 4);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testAndAnyOtherConstraintDoesNotPreventMatchingOfRegularArguments()
+ {
+ $this->mock->shouldReceive('foo')->with(1, 2, Mockery::andAnyOthers());
+ $this->mock->foo(10, 2, 3, 4, 5);
+ Mockery::close();
+ }
+
+ public function testArrayConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('array'))->once();
+ $this->mock->foo(array());
+ }
+
+ public function testArrayConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('array'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testArrayConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('array'));
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ public function testBoolConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('bool'))->once();
+ $this->mock->foo(true);
+ }
+
+ public function testBoolConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('bool'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testBoolConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('bool'));
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ public function testCallableConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('callable'))->once();
+ $this->mock->foo(function () {
+ return 'f';
+ });
+ }
+
+ public function testCallableConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('callable'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testCallableConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('callable'));
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ public function testDoubleConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('double'))->once();
+ $this->mock->foo(2.25);
+ }
+
+ public function testDoubleConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('double'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testDoubleConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('double'));
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ public function testFloatConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('float'))->once();
+ $this->mock->foo(2.25);
+ }
+
+ public function testFloatConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('float'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testFloatConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('float'));
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ public function testIntConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('int'))->once();
+ $this->mock->foo(2);
+ }
+
+ public function testIntConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('int'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testIntConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('int'));
+ $this->mock->foo('f');
+ Mockery::close();
+ }
+
+ public function testLongConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('long'))->once();
+ $this->mock->foo(2);
+ }
+
+ public function testLongConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('long'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testLongConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('long'));
+ $this->mock->foo('f');
+ Mockery::close();
+ }
+
+ public function testNullConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('null'))->once();
+ $this->mock->foo(null);
+ }
+
+ public function testNullConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('null'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testNullConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('null'));
+ $this->mock->foo('f');
+ Mockery::close();
+ }
+
+ public function testNumericConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('numeric'))->once();
+ $this->mock->foo('2');
+ }
+
+ public function testNumericConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('numeric'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testNumericConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('numeric'));
+ $this->mock->foo('f');
+ Mockery::close();
+ }
+
+ public function testObjectConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('object'))->once();
+ $this->mock->foo(new stdClass);
+ }
+
+ public function testObjectConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('object`'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testObjectConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('object'));
+ $this->mock->foo('f');
+ Mockery::close();
+ }
+
+ public function testRealConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('real'))->once();
+ $this->mock->foo(2.25);
+ }
+
+ public function testRealConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('real'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testRealConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('real'));
+ $this->mock->foo('f');
+ Mockery::close();
+ }
+
+ public function testResourceConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('resource'))->once();
+ $r = fopen(dirname(__FILE__) . '/_files/file.txt', 'r');
+ $this->mock->foo($r);
+ }
+
+ public function testResourceConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('resource'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testResourceConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('resource'));
+ $this->mock->foo('f');
+ Mockery::close();
+ }
+
+ public function testScalarConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('scalar'))->once();
+ $this->mock->foo(2);
+ }
+
+ public function testScalarConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('scalar'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testScalarConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('scalar'));
+ $this->mock->foo(array());
+ Mockery::close();
+ }
+
+ public function testStringConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('string'))->once();
+ $this->mock->foo('2');
+ }
+
+ public function testStringConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('string'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testStringConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('string'));
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+
+ public function testClassConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('stdClass'))->once();
+ $this->mock->foo(new stdClass);
+ }
+
+ public function testClassConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::type('stdClass'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testClassConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::type('stdClass'));
+ $this->mock->foo(new Exception);
+ Mockery::close();
+ }
+
+ public function testDucktypeConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::ducktype('quack', 'swim'))->once();
+ $this->mock->foo(new Mockery_Duck);
+ }
+
+ public function testDucktypeConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::ducktype('quack', 'swim'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testDucktypeConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::ducktype('quack', 'swim'));
+ $this->mock->foo(new Mockery_Duck_Nonswimmer);
+ Mockery::close();
+ }
+
+ public function testArrayContentConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::subset(array('a'=>1, 'b'=>2)))->once();
+ $this->mock->foo(array('a'=>1, 'b'=>2, 'c'=>3));
+ }
+
+ public function testArrayContentConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::subset(array('a'=>1, 'b'=>2)))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testArrayContentConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::subset(array('a'=>1, 'b'=>2)));
+ $this->mock->foo(array('a'=>1, 'c'=>3));
+ Mockery::close();
+ }
+
+ public function testContainsConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::contains(1, 2))->once();
+ $this->mock->foo(array('a'=>1, 'b'=>2, 'c'=>3));
+ }
+
+ public function testContainsConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::contains(1, 2))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testContainsConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::contains(1, 2));
+ $this->mock->foo(array('a'=>1, 'c'=>3));
+ Mockery::close();
+ }
+
+ public function testHasKeyConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::hasKey('c'))->once();
+ $this->mock->foo(array('a'=>1, 'b'=>2, 'c'=>3));
+ }
+
+ public function testHasKeyConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::hasKey('a'))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, array('a'=>1), 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testHasKeyConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::hasKey('c'));
+ $this->mock->foo(array('a'=>1, 'b'=>3));
+ Mockery::close();
+ }
+
+ public function testHasValueConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::hasValue(1))->once();
+ $this->mock->foo(array('a'=>1, 'b'=>2, 'c'=>3));
+ }
+
+ public function testHasValueConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::hasValue(1))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, array('a'=>1), 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testHasValueConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::hasValue(2));
+ $this->mock->foo(array('a'=>1, 'b'=>3));
+ Mockery::close();
+ }
+
+ public function testOnConstraintMatchesArgument_ClosureEvaluatesToTrue()
+ {
+ $function = function ($arg) {
+ return $arg % 2 == 0;
+ };
+ $this->mock->shouldReceive('foo')->with(Mockery::on($function))->once();
+ $this->mock->foo(4);
+ }
+
+ public function testOnConstraintMatchesArgumentOfTypeArray_ClosureEvaluatesToTrue()
+ {
+ $function = function ($arg) {
+ return is_array($arg);
+ };
+ $this->mock->shouldReceive('foo')->with(Mockery::on($function))->once();
+ $this->mock->foo([4, 5]);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testOnConstraintThrowsExceptionWhenConstraintUnmatched_ClosureEvaluatesToFalse()
+ {
+ $function = function ($arg) {
+ return $arg % 2 == 0;
+ };
+ $this->mock->shouldReceive('foo')->with(Mockery::on($function));
+ $this->mock->foo(5);
+ Mockery::close();
+ }
+
+ public function testMustBeConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::mustBe(2))->once();
+ $this->mock->foo(2);
+ }
+
+ public function testMustBeConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::mustBe(2))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testMustBeConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::mustBe(2));
+ $this->mock->foo('2');
+ Mockery::close();
+ }
+
+ public function testMustBeConstraintMatchesObjectArgumentWithEqualsComparisonNotIdentical()
+ {
+ $a = new stdClass;
+ $a->foo = 1;
+ $b = new stdClass;
+ $b->foo = 1;
+ $this->mock->shouldReceive('foo')->with(Mockery::mustBe($a))->once();
+ $this->mock->foo($b);
+ }
+
+ public function testMustBeConstraintNonMatchingCaseWithObject()
+ {
+ $a = new stdClass;
+ $a->foo = 1;
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::mustBe($a))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, $a, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testMustBeConstraintThrowsExceptionWhenConstraintUnmatchedWithObject()
+ {
+ $a = new stdClass;
+ $a->foo = 1;
+ $b = new stdClass;
+ $b->foo = 2;
+ $this->mock->shouldReceive('foo')->with(Mockery::mustBe($a));
+ $this->mock->foo($b);
+ Mockery::close();
+ }
+
+ public function testMatchPrecedenceBasedOnExpectedCallsFavouringExplicitMatch()
+ {
+ $this->mock->shouldReceive('foo')->with(1)->once();
+ $this->mock->shouldReceive('foo')->with(Mockery::any())->never();
+ $this->mock->foo(1);
+ }
+
+ public function testMatchPrecedenceBasedOnExpectedCallsFavouringAnyMatch()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::any())->once();
+ $this->mock->shouldReceive('foo')->with(1)->never();
+ $this->mock->foo(1);
+ }
+
+ public function testReturnNullIfIgnoreMissingMethodsSet()
+ {
+ $this->mock->shouldIgnoreMissing();
+ $this->assertNull($this->mock->g(1, 2));
+ }
+
+ public function testReturnUndefinedIfIgnoreMissingMethodsSet()
+ {
+ $this->mock->shouldIgnoreMissing()->asUndefined();
+ $this->assertInstanceOf(\Mockery\Undefined::class, $this->mock->g(1, 2));
+ }
+
+ public function testReturnAsUndefinedAllowsForInfiniteSelfReturningChain()
+ {
+ $this->mock->shouldIgnoreMissing()->asUndefined();
+ $this->assertInstanceOf(\Mockery\Undefined::class, $this->mock->g(1, 2)->a()->b()->c());
+ }
+
+ public function testShouldIgnoreMissingFluentInterface()
+ {
+ $this->assertInstanceOf(\Mockery\MockInterface::class, $this->mock->shouldIgnoreMissing());
+ }
+
+ public function testShouldIgnoreMissingAsUndefinedFluentInterface()
+ {
+ $this->assertInstanceOf(\Mockery\MockInterface::class, $this->mock->shouldIgnoreMissing()->asUndefined());
+ }
+
+ public function testShouldIgnoreMissingAsDefinedProxiesToUndefinedAllowingToString()
+ {
+ $this->mock->shouldIgnoreMissing()->asUndefined();
+ $this->assertInternalType('string', "{$this->mock->g()}");
+ $this->assertInternalType('string', "{$this->mock}");
+ }
+
+ public function testShouldIgnoreMissingDefaultReturnValue()
+ {
+ $this->mock->shouldIgnoreMissing(1);
+ $this->assertEquals(1, $this->mock->a());
+ }
+
+ /** @issue #253 */
+ public function testShouldIgnoreMissingDefaultSelfAndReturnsSelf()
+ {
+ $this->mock->shouldIgnoreMissing(\Mockery::self());
+ $this->assertSame($this->mock, $this->mock->a()->b());
+ }
+
+ public function testToStringMagicMethodCanBeMocked()
+ {
+ $this->mock->shouldReceive("__toString")->andReturn('dave');
+ $this->assertEquals("{$this->mock}", "dave");
+ }
+
+ public function testOptionalMockRetrieval()
+ {
+ $m = mock('f')->shouldReceive('foo')->with(1)->andReturn(3)->mock();
+ $this->assertInstanceOf(\Mockery\MockInterface::class, $m);
+ }
+
+ public function testNotConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::not(1))->once();
+ $this->mock->foo(2);
+ }
+
+ public function testNotConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::not(2))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testNotConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::not(2));
+ $this->mock->foo(2);
+ Mockery::close();
+ }
+
+ public function testAnyOfConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::anyOf(1, 2))->twice();
+ $this->mock->foo(2);
+ $this->mock->foo(1);
+ }
+
+ public function testAnyOfConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::anyOf(1, 2))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 2, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testAnyOfConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::anyOf(1, 2));
+ $this->mock->foo(3);
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testAnyOfConstraintThrowsExceptionWhenTrueIsNotAnExpectedArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::anyOf(1, 2));
+ $this->mock->foo(true);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testAnyOfConstraintThrowsExceptionWhenFalseIsNotAnExpectedArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::anyOf(0, 1, 2));
+ $this->mock->foo(false);
+ }
+
+ public function testNotAnyOfConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::notAnyOf(1, 2))->once();
+ $this->mock->foo(3);
+ }
+
+ public function testNotAnyOfConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->times(3);
+ $this->mock->shouldReceive('foo')->with(1, Mockery::notAnyOf(1, 2))->never();
+ $this->mock->foo();
+ $this->mock->foo(1);
+ $this->mock->foo(1, 4, 3);
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testNotAnyOfConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::notAnyOf(1, 2));
+ $this->mock->foo(2);
+ Mockery::close();
+ }
+
+ public function testPatternConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::pattern('/foo.*/'))->once();
+ $this->mock->foo('foobar');
+ }
+
+ public function testPatternConstraintNonMatchingCase()
+ {
+ $this->mock->shouldReceive('foo')->once();
+ $this->mock->shouldReceive('foo')->with(Mockery::pattern('/foo.*/'))->never();
+ $this->mock->foo('bar');
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testPatternConstraintThrowsExceptionWhenConstraintUnmatched()
+ {
+ $this->mock->shouldReceive('foo')->with(Mockery::pattern('/foo.*/'));
+ $this->mock->foo('bar');
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testGlobalConfigMayForbidMockingNonExistentMethodsOnClasses()
+ {
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
+ $mock = mock('stdClass');
+ $mock->shouldReceive('foo');
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ * @expectedExceptionMessage Mockery can't find 'SomeMadeUpClass' so can't mock it
+ */
+ public function testGlobalConfigMayForbidMockingNonExistentMethodsOnAutoDeclaredClasses()
+ {
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
+ $mock = mock('SomeMadeUpClass');
+ $mock->shouldReceive('foo');
+ Mockery::close();
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testGlobalConfigMayForbidMockingNonExistentMethodsOnObjects()
+ {
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
+ $mock = mock(new stdClass);
+ $mock->shouldReceive('foo');
+ Mockery::close();
+ }
+
+ public function testAnExampleWithSomeExpectationAmends()
+ {
+ $service = mock('MyService');
+ $service->shouldReceive('login')->with('user', 'pass')->once()->andReturn(true);
+ $service->shouldReceive('hasBookmarksTagged')->with('php')->once()->andReturn(false);
+ $service->shouldReceive('addBookmark')->with(Mockery::pattern('/^http:/'), \Mockery::type('string'))->times(3)->andReturn(true);
+ $service->shouldReceive('hasBookmarksTagged')->with('php')->once()->andReturn(true);
+
+ $this->assertTrue($service->login('user', 'pass'));
+ $this->assertFalse($service->hasBookmarksTagged('php'));
+ $this->assertTrue($service->addBookmark('http://example.com/1', 'some_tag1'));
+ $this->assertTrue($service->addBookmark('http://example.com/2', 'some_tag2'));
+ $this->assertTrue($service->addBookmark('http://example.com/3', 'some_tag3'));
+ $this->assertTrue($service->hasBookmarksTagged('php'));
+ }
+
+ public function testAnExampleWithSomeExpectationAmendsOnCallCounts()
+ {
+ $service = mock('MyService');
+ $service->shouldReceive('login')->with('user', 'pass')->once()->andReturn(true);
+ $service->shouldReceive('hasBookmarksTagged')->with('php')->once()->andReturn(false);
+ $service->shouldReceive('addBookmark')->with(Mockery::pattern('/^http:/'), \Mockery::type('string'))->times(3)->andReturn(true);
+ $service->shouldReceive('hasBookmarksTagged')->with('php')->twice()->andReturn(true);
+
+ $this->assertTrue($service->login('user', 'pass'));
+ $this->assertFalse($service->hasBookmarksTagged('php'));
+ $this->assertTrue($service->addBookmark('http://example.com/1', 'some_tag1'));
+ $this->assertTrue($service->addBookmark('http://example.com/2', 'some_tag2'));
+ $this->assertTrue($service->addBookmark('http://example.com/3', 'some_tag3'));
+ $this->assertTrue($service->hasBookmarksTagged('php'));
+ $this->assertTrue($service->hasBookmarksTagged('php'));
+ }
+
+ public function testAnExampleWithSomeExpectationAmendsOnCallCounts_PHPUnitTest()
+ {
+ $service = $this->createMock('MyService2');
+ $service->expects($this->once())->method('login')->with('user', 'pass')->will($this->returnValue(true));
+ $service->expects($this->exactly(3))->method('hasBookmarksTagged')->with('php')
+ ->will($this->onConsecutiveCalls(false, true, true));
+ $service->expects($this->exactly(3))->method('addBookmark')
+ ->with($this->matchesRegularExpression('/^http:/'), $this->isType('string'))
+ ->will($this->returnValue(true));
+
+ $this->assertTrue($service->login('user', 'pass'));
+ $this->assertFalse($service->hasBookmarksTagged('php'));
+ $this->assertTrue($service->addBookmark('http://example.com/1', 'some_tag1'));
+ $this->assertTrue($service->addBookmark('http://example.com/2', 'some_tag2'));
+ $this->assertTrue($service->addBookmark('http://example.com/3', 'some_tag3'));
+ $this->assertTrue($service->hasBookmarksTagged('php'));
+ $this->assertTrue($service->hasBookmarksTagged('php'));
+ }
+
+ public function testMockedMethodsCallableFromWithinOriginalClass()
+ {
+ $mock = mock('MockeryTest_InterMethod1[doThird]');
+ $mock->shouldReceive('doThird')->andReturn(true);
+ $this->assertTrue($mock->doFirst());
+ }
+
+ /**
+ * @group issue #20
+ */
+ public function testMockingDemeterChainsPassesMockeryExpectationToCompositeExpectation()
+ {
+ $mock = mock('Mockery_Demeterowski');
+ $mock->shouldReceive('foo->bar->baz')->andReturn('Spam!');
+ $demeter = new Mockery_UseDemeter($mock);
+ $this->assertSame('Spam!', $demeter->doit());
+ }
+
+ /**
+ * @group issue #20 - with args in demeter chain
+ */
+ public function testMockingDemeterChainsPassesMockeryExpectationToCompositeExpectationWithArgs()
+ {
+ $mock = mock('Mockery_Demeterowski');
+ $mock->shouldReceive('foo->bar->baz')->andReturn('Spam!');
+ $demeter = new Mockery_UseDemeter($mock);
+ $this->assertSame('Spam!', $demeter->doitWithArgs());
+ }
+
+ public function testShouldNotReceiveCanBeAddedToCompositeExpectation()
+ {
+ $mock = mock('Foo');
+ $mock->shouldReceive('a')->once()->andReturn('Spam!')
+ ->shouldNotReceive('b');
+ $mock->a();
+ }
+
+ public function testPassthruEnsuresRealMethodCalledForReturnValues()
+ {
+ $mock = mock('MockeryTest_SubjectCall1');
+ $mock->shouldReceive('foo')->once()->passthru();
+ $this->assertEquals('bar', $mock->foo());
+ }
+
+ public function testShouldIgnoreMissingExpectationBasedOnArgs()
+ {
+ $mock = mock("MyService2")->shouldIgnoreMissing();
+ $mock->shouldReceive("hasBookmarksTagged")->with("dave")->once();
+ $mock->hasBookmarksTagged("dave");
+ $mock->hasBookmarksTagged("padraic");
+ }
+
+ public function testMakePartialExpectationBasedOnArgs()
+ {
+ $mock = mock("MockeryTest_SubjectCall1")->makePartial();
+
+ $this->assertEquals('bar', $mock->foo());
+ $this->assertEquals('bar', $mock->foo("baz"));
+ $this->assertEquals('bar', $mock->foo("qux"));
+
+ $mock->shouldReceive("foo")->with("baz")->twice()->andReturn('123');
+ $this->assertEquals('bar', $mock->foo());
+ $this->assertEquals('123', $mock->foo("baz"));
+ $this->assertEquals('bar', $mock->foo("qux"));
+
+ $mock->shouldReceive("foo")->withNoArgs()->once()->andReturn('456');
+ $this->assertEquals('456', $mock->foo());
+ $this->assertEquals('123', $mock->foo("baz"));
+ $this->assertEquals('bar', $mock->foo("qux"));
+ }
+
+ public function testCanReturnSelf()
+ {
+ $this->mock->shouldReceive("foo")->andReturnSelf();
+ $this->assertSame($this->mock, $this->mock->foo());
+ }
+
+ public function testReturnsTrueIfTrueIsReturnValue()
+ {
+ $this->mock->shouldReceive("foo")->andReturnTrue();
+ $this->assertTrue($this->mock->foo());
+ }
+
+ public function testReturnsFalseIfFalseIsReturnValue()
+ {
+ $this->mock->shouldReceive("foo")->andReturnFalse();
+ $this->assertFalse($this->mock->foo());
+ }
+
+ public function testExpectationCanBeOverridden()
+ {
+ $this->mock->shouldReceive('foo')->once()->andReturn('green');
+ $this->mock->shouldReceive('foo')->andReturn('blue');
+ $this->assertEquals($this->mock->foo(), 'green');
+ $this->assertEquals($this->mock->foo(), 'blue');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testTimesExpectationForbidsFloatNumbers()
+ {
+ $this->mock->shouldReceive('foo')->times(1.3);
+ Mockery::close();
+ }
+
+ public function testIfExceptionIndicatesAbsenceOfMethodAndExpectationsOnMock()
+ {
+ $mock = mock('Mockery_Duck');
+
+ $this->expectException(
+ '\BadMethodCallException',
+ 'Method ' . get_class($mock) .
+ '::nonExistent() does not exist on this mock object'
+ );
+
+ $mock->nonExistent();
+ Mockery::close();
+ }
+
+ public function testIfCallingMethodWithNoExpectationsHasSpecificExceptionMessage()
+ {
+ $mock = mock('Mockery_Duck');
+
+ $this->expectException(
+ '\BadMethodCallException',
+ 'Received ' . get_class($mock) .
+ '::quack(), ' . 'but no expectations were specified'
+ );
+
+ $mock->quack();
+ Mockery::close();
+ }
+
+ public function testMockShouldNotBeAnonymousWhenImplementingSpecificInterface()
+ {
+ $waterMock = mock('IWater');
+ $this->assertFalse($waterMock->mockery_isAnonymous());
+ }
+
+ /**
+ * @expectedException \Mockery\Exception
+ */
+ public function testWetherMockWithInterfaceOnlyCanNotImplementNonExistingMethods()
+ {
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
+ $waterMock = \Mockery::mock('IWater');
+ $waterMock
+ ->shouldReceive('nonExistentMethod')
+ ->once()
+ ->andReturnNull();
+ \Mockery::close();
+ }
+
+ public function testCountWithBecauseExceptionMessage()
+ {
+ $this->expectException(InvalidCountException::class);
+ $this->expectExceptionMessageRegexp(
+ '/Method foo\(\) from Mockery_[\d]+ should be called' . PHP_EOL . ' ' .
+ 'exactly 1 times but called 0 times. Because We like foo/'
+ );
+
+ $this->mock->shouldReceive('foo')->once()->because('We like foo');
+ Mockery::close();
+ }
+
+ /** @test */
+ public function it_uses_a_matchers_to_string_method_in_the_exception_output()
+ {
+ $mock = Mockery::mock();
+
+ $mock->expects()->foo(Mockery::hasKey('foo'));
+
+ $this->expectException(
+ InvalidCountException::class,
+ "Method foo()"
+ );
+
+ Mockery::close();
+ }
+}
+
+interface IWater
+{
+ public function dry();
+}
+
+class MockeryTest_SubjectCall1
+{
+ public function foo()
+ {
+ return 'bar';
+ }
+}
+
+class MockeryTest_InterMethod1
+{
+ public function doFirst()
+ {
+ return $this->doSecond();
+ }
+
+ private function doSecond()
+ {
+ return $this->doThird();
+ }
+
+ public function doThird()
+ {
+ return false;
+ }
+}
+
+class MyService2
+{
+ public function login($user, $pass)
+ {
+ }
+ public function hasBookmarksTagged($tag)
+ {
+ }
+ public function addBookmark($uri, $tag)
+ {
+ }
+}
+
+class Mockery_Duck
+{
+ public function quack()
+ {
+ }
+ public function swim()
+ {
+ }
+}
+
+class Mockery_Duck_Nonswimmer
+{
+ public function quack()
+ {
+ }
+}
+
+class Mockery_Demeterowski
+{
+ public function foo()
+ {
+ return $this;
+ }
+ public function bar()
+ {
+ return $this;
+ }
+ public function baz()
+ {
+ return 'Ham!';
+ }
+}
+
+class Mockery_UseDemeter
+{
+ public function __construct($demeter)
+ {
+ $this->demeter = $demeter;
+ }
+ public function doit()
+ {
+ return $this->demeter->foo()->bar()->baz();
+ }
+ public function doitWithArgs()
+ {
+ return $this->demeter->foo("foo")->bar("bar")->baz("baz");
+ }
+}
+
+class MockeryTest_Foo
+{
+ public function foo()
+ {
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Fixtures/ClassWithAllLowerCaseMethod.php b/vendor/mockery/mockery/tests/Mockery/Fixtures/ClassWithAllLowerCaseMethod.php
new file mode 100644
index 0000000..2cf2b77
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Fixtures/ClassWithAllLowerCaseMethod.php
@@ -0,0 +1,30 @@
+
+ {
+ return array('key' => true);
+ }
+
+ public function HHVMVoid() : ?void
+ {
+ return null;
+ }
+
+ public function HHVMMixed() : mixed
+ {
+ return null;
+ }
+
+ public function HHVMThis() : this
+ {
+ return $this;
+ }
+
+ public function HHVMString() : string
+ {
+ return 'a string';
+ }
+
+ public function HHVMImmVector() : ImmVector
+ {
+ return new ImmVector([1, 2, 3]);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Fixtures/MethodWithIterableTypeHints.php b/vendor/mockery/mockery/tests/Mockery/Fixtures/MethodWithIterableTypeHints.php
new file mode 100644
index 0000000..49739c6
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Fixtures/MethodWithIterableTypeHints.php
@@ -0,0 +1,29 @@
+assertTrue($target->hasInternalAncestor());
+
+ $target = new DefinedTargetClass(new \ReflectionClass("Mockery\MockeryTest_ClassThatExtendsArrayObject"));
+ $this->assertTrue($target->hasInternalAncestor());
+
+ $target = new DefinedTargetClass(new \ReflectionClass("Mockery\DefinedTargetClassTest"));
+ $this->assertFalse($target->hasInternalAncestor());
+ }
+}
+
+class MockeryTest_ClassThatExtendsArrayObject extends \ArrayObject
+{
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Generator/MockConfigurationBuilderTest.php b/vendor/mockery/mockery/tests/Mockery/Generator/MockConfigurationBuilderTest.php
new file mode 100644
index 0000000..ac48ac1
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Generator/MockConfigurationBuilderTest.php
@@ -0,0 +1,85 @@
+assertContains('__halt_compiler', $builder->getMockConfiguration()->getBlackListedMethods());
+
+ // need a builtin for this
+ $this->markTestSkipped("Need a builtin class with a method that is a reserved word");
+ }
+
+ /**
+ * @test
+ */
+ public function magicMethodsAreBlackListedByDefault()
+ {
+ $builder = new MockConfigurationBuilder;
+ $builder->addTarget(ClassWithMagicCall::class);
+ $methods = $builder->getMockConfiguration()->getMethodsToMock();
+ $this->assertCount(1, $methods);
+ $this->assertEquals("foo", $methods[0]->getName());
+ }
+
+ /** @test */
+ public function xdebugs_debug_info_is_black_listed_by_default()
+ {
+ $builder = new MockConfigurationBuilder;
+ $builder->addTarget(ClassWithDebugInfo::class);
+ $methods = $builder->getMockConfiguration()->getMethodsToMock();
+ $this->assertCount(1, $methods);
+ $this->assertEquals("foo", $methods[0]->getName());
+ }
+}
+
+class ClassWithMagicCall
+{
+ public function foo()
+ {
+ }
+
+ public function __call($method, $args)
+ {
+ }
+}
+
+class ClassWithDebugInfo
+{
+ public function foo()
+ {
+ }
+
+ public function __debugInfo()
+ {
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Generator/MockConfigurationTest.php b/vendor/mockery/mockery/tests/Mockery/Generator/MockConfigurationTest.php
new file mode 100644
index 0000000..d32ac58
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Generator/MockConfigurationTest.php
@@ -0,0 +1,218 @@
+getMethodsToMock();
+ $this->assertCount(1, $methods);
+ $this->assertEquals("bar", $methods[0]->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function blackListsAreCaseInsensitive()
+ {
+ $config = new MockConfiguration(array("Mockery\Generator\\TestSubject"), array("FOO"));
+
+ $methods = $config->getMethodsToMock();
+ $this->assertCount(1, $methods);
+ $this->assertEquals("bar", $methods[0]->getName());
+ }
+
+
+ /**
+ * @test
+ */
+ public function onlyWhiteListedMethodsShouldBeInListToBeMocked()
+ {
+ $config = new MockConfiguration(array("Mockery\Generator\\TestSubject"), array(), array('foo'));
+
+ $methods = $config->getMethodsToMock();
+ $this->assertCount(1, $methods);
+ $this->assertEquals("foo", $methods[0]->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function whitelistOverRulesBlackList()
+ {
+ $config = new MockConfiguration(array("Mockery\Generator\\TestSubject"), array("foo"), array("foo"));
+
+ $methods = $config->getMethodsToMock();
+ $this->assertCount(1, $methods);
+ $this->assertEquals("foo", $methods[0]->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function whiteListsAreCaseInsensitive()
+ {
+ $config = new MockConfiguration(array("Mockery\Generator\\TestSubject"), array(), array("FOO"));
+
+ $methods = $config->getMethodsToMock();
+ $this->assertCount(1, $methods);
+ $this->assertEquals("foo", $methods[0]->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function finalMethodsAreExcluded()
+ {
+ $config = new MockConfiguration(array("Mockery\Generator\\ClassWithFinalMethod"));
+
+ $methods = $config->getMethodsToMock();
+ $this->assertCount(1, $methods);
+ $this->assertEquals("bar", $methods[0]->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function shouldIncludeMethodsFromAllTargets()
+ {
+ $config = new MockConfiguration(array("Mockery\\Generator\\TestInterface", "Mockery\\Generator\\TestInterface2"));
+ $methods = $config->getMethodsToMock();
+ $this->assertCount(2, $methods);
+ }
+
+ /**
+ * @test
+ * @expectedException Mockery\Exception
+ */
+ public function shouldThrowIfTargetClassIsFinal()
+ {
+ $config = new MockConfiguration(array("Mockery\\Generator\\TestFinal"));
+ $config->getTargetClass();
+ }
+
+ /**
+ * @test
+ */
+ public function shouldTargetIteratorAggregateIfTryingToMockTraversable()
+ {
+ $config = new MockConfiguration(array("\\Traversable"));
+
+ $interfaces = $config->getTargetInterfaces();
+ $this->assertCount(1, $interfaces);
+ $first = array_shift($interfaces);
+ $this->assertEquals("IteratorAggregate", $first->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function shouldTargetIteratorAggregateIfTraversableInTargetsTree()
+ {
+ $config = new MockConfiguration(array("Mockery\Generator\TestTraversableInterface"));
+
+ $interfaces = $config->getTargetInterfaces();
+ $this->assertCount(2, $interfaces);
+ $this->assertEquals("IteratorAggregate", $interfaces[0]->getName());
+ $this->assertEquals("Mockery\Generator\TestTraversableInterface", $interfaces[1]->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function shouldBringIteratorToHeadOfTargetListIfTraversablePresent()
+ {
+ $config = new MockConfiguration(array("Mockery\Generator\TestTraversableInterface2"));
+
+ $interfaces = $config->getTargetInterfaces();
+ $this->assertCount(2, $interfaces);
+ $this->assertEquals("Iterator", $interfaces[0]->getName());
+ $this->assertEquals("Mockery\Generator\TestTraversableInterface2", $interfaces[1]->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function shouldBringIteratorAggregateToHeadOfTargetListIfTraversablePresent()
+ {
+ $config = new MockConfiguration(array("Mockery\Generator\TestTraversableInterface3"));
+
+ $interfaces = $config->getTargetInterfaces();
+ $this->assertCount(2, $interfaces);
+ $this->assertEquals("IteratorAggregate", $interfaces[0]->getName());
+ $this->assertEquals("Mockery\Generator\TestTraversableInterface3", $interfaces[1]->getName());
+ }
+}
+
+interface TestTraversableInterface extends \Traversable
+{
+}
+interface TestTraversableInterface2 extends \Traversable, \Iterator
+{
+}
+interface TestTraversableInterface3 extends \Traversable, \IteratorAggregate
+{
+}
+
+final class TestFinal
+{
+}
+
+interface TestInterface
+{
+ public function foo();
+}
+
+interface TestInterface2
+{
+ public function bar();
+}
+
+class TestSubject
+{
+ public function foo()
+ {
+ }
+
+ public function bar()
+ {
+ }
+}
+
+class ClassWithFinalMethod
+{
+ final public function foo()
+ {
+ }
+
+ public function bar()
+ {
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/CallTypeHintPassTest.php b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/CallTypeHintPassTest.php
new file mode 100644
index 0000000..6ce54e9
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/CallTypeHintPassTest.php
@@ -0,0 +1,59 @@
+ true,
+ ))->makePartial();
+ $code = $pass->apply(static::CODE, $config);
+ $this->assertContains('__call($method, $args)', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function shouldRemoveCallStaticTypeHintIfRequired()
+ {
+ $pass = new CallTypeHintPass;
+ $config = m::mock("Mockery\Generator\MockConfiguration", array(
+ "requiresCallStaticTypeHintRemoval" => true,
+ ))->makePartial();
+ $code = $pass->apply(static::CODE, $config);
+ $this->assertContains('__callStatic($method, $args)', $code);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/ClassNamePassTest.php b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/ClassNamePassTest.php
new file mode 100644
index 0000000..d9209b8
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/ClassNamePassTest.php
@@ -0,0 +1,78 @@
+pass = new ClassNamePass();
+ }
+
+ /**
+ * @test
+ */
+ public function shouldRemoveNamespaceDefinition()
+ {
+ $config = new MockConfiguration(array(), array(), array(), "Dave\Dave");
+ $code = $this->pass->apply(static::CODE, $config);
+ $this->assertNotContains('namespace Mockery;', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function shouldReplaceNamespaceIfClassNameIsNamespaced()
+ {
+ $config = new MockConfiguration(array(), array(), array(), "Dave\Dave");
+ $code = $this->pass->apply(static::CODE, $config);
+ $this->assertNotContains('namespace Mockery;', $code);
+ $this->assertContains('namespace Dave;', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function shouldReplaceClassNameWithSpecifiedName()
+ {
+ $config = new MockConfiguration(array(), array(), array(), "Dave");
+ $code = $this->pass->apply(static::CODE, $config);
+ $this->assertContains('class Dave', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function shouldRemoveLeadingBackslashesFromNamespace()
+ {
+ $config = new MockConfiguration(array(), array(), array(), "\Dave\Dave");
+ $code = $this->pass->apply(static::CODE, $config);
+ $this->assertContains('namespace Dave;', $code);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/ConstantsPassTest.php b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/ConstantsPassTest.php
new file mode 100644
index 0000000..ae907bc
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/ConstantsPassTest.php
@@ -0,0 +1,52 @@
+ ['FOO' => 'test']]
+ );
+ $code = $pass->apply(static::CODE, $config);
+ $this->assertContains("const FOO = 'test'", $code);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/InstanceMockPassTest.php b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/InstanceMockPassTest.php
new file mode 100644
index 0000000..94be526
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/InstanceMockPassTest.php
@@ -0,0 +1,45 @@
+setInstanceMock(true);
+ $config = $builder->getMockConfiguration();
+ $pass = new InstanceMockPass;
+ $code = $pass->apply('class Dave { }', $config);
+ $this->assertContains('public function __construct', $code);
+ $this->assertContains('protected $_mockery_ignoreVerification', $code);
+ $this->assertContains('this->_mockery_constructorCalled(func_get_args());', $code);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/InterfacePassTest.php b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/InterfacePassTest.php
new file mode 100644
index 0000000..9930165
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Generator/StringManipulation/Pass/InterfacePassTest.php
@@ -0,0 +1,66 @@
+ array(),
+ ));
+
+ $code = $pass->apply(static::CODE, $config);
+ $this->assertEquals(static::CODE, $code);
+ }
+
+ /**
+ * @test
+ */
+ public function shouldAddAnyInterfaceNamesToImplementsDefinition()
+ {
+ $pass = new InterfacePass;
+
+ $config = m::mock("Mockery\Generator\MockConfiguration", array(
+ "getTargetInterfaces" => array(
+ m::mock(array("getName" => "Dave\Dave")),
+ m::mock(array("getName" => "Paddy\Paddy")),
+ ),
+ ));
+
+ $code = $pass->apply(static::CODE, $config);
+
+ $this->assertContains("implements MockInterface, \Dave\Dave, \Paddy\Paddy", $code);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/GlobalHelpersTest.php b/vendor/mockery/mockery/tests/Mockery/GlobalHelpersTest.php
new file mode 100644
index 0000000..0f2b7c4
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/GlobalHelpersTest.php
@@ -0,0 +1,63 @@
+assertInstanceOf(\Mockery\MockInterface::class, $double);
+ $this->expectException(\Exception::class);
+ $double->foo();
+ }
+
+ /** @test */
+ public function spy_creates_a_spy()
+ {
+ $double = spy();
+
+ $this->assertInstanceOf(\Mockery\MockInterface::class, $double);
+ $double->foo();
+ }
+
+ /** @test */
+ public function named_mock_creates_a_named_mock()
+ {
+ $className = "Class".uniqid();
+ $double = namedMock($className);
+
+ $this->assertInstanceOf(\Mockery\MockInterface::class, $double);
+ $this->assertInstanceOf($className, $double);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/HamcrestExpectationTest.php b/vendor/mockery/mockery/tests/Mockery/HamcrestExpectationTest.php
new file mode 100644
index 0000000..659397c
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/HamcrestExpectationTest.php
@@ -0,0 +1,62 @@
+mock = mock('foo');
+ }
+
+
+ public function tearDown()
+ {
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(true);
+ parent::tearDown();
+ }
+
+ /** Just a quickie roundup of a few Hamcrest matchers to check nothing obvious out of place **/
+
+ public function testAnythingConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(anything())->once();
+ $this->mock->foo(2);
+ }
+
+ public function testGreaterThanConstraintMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(greaterThan(1))->once();
+ $this->mock->foo(2);
+ }
+
+ /**
+ * @expectedException Mockery\Exception
+ */
+ public function testGreaterThanConstraintNotMatchesArgument()
+ {
+ $this->mock->shouldReceive('foo')->with(greaterThan(1));
+ $this->mock->foo(1);
+ Mockery::close();
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Loader/EvalLoaderTest.php b/vendor/mockery/mockery/tests/Mockery/Loader/EvalLoaderTest.php
new file mode 100644
index 0000000..025a1da
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Loader/EvalLoaderTest.php
@@ -0,0 +1,35 @@
+getLoader()->load($definition);
+
+ $this->assertTrue(class_exists($className));
+ }
+
+ abstract public function getLoader();
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Loader/RequireLoaderTest.php b/vendor/mockery/mockery/tests/Mockery/Loader/RequireLoaderTest.php
new file mode 100644
index 0000000..9f0664a
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Loader/RequireLoaderTest.php
@@ -0,0 +1,35 @@
+assertionFailedError = '\PHPUnit\Framework\AssertionFailedError';
+ $this->frameworkConstraint = '\PHPUnit\Framework\Constraint';
+ } else {
+ $this->assertionFailedError = '\PHPUnit_Framework_AssertionFailedError';
+ $this->frameworkConstraint = '\PHPUnit_Framework_Constraint';
+ }
+
+ $this->constraint = \Mockery::mock($this->frameworkConstraint);
+ $this->matcher = new PHPUnitConstraint($this->constraint);
+ $this->rethrowingMatcher = new PHPUnitConstraint($this->constraint, true);
+ }
+
+ public function testMatches()
+ {
+ $value1 = 'value1';
+ $value2 = 'value1';
+ $value3 = 'value1';
+ $this->constraint
+ ->shouldReceive('evaluate')
+ ->once()
+ ->with($value1)
+ ->getMock()
+ ->shouldReceive('evaluate')
+ ->once()
+ ->with($value2)
+ ->andThrow($this->assertionFailedError)
+ ->getMock()
+ ->shouldReceive('evaluate')
+ ->once()
+ ->with($value3)
+ ->getMock()
+ ;
+ $this->assertTrue($this->matcher->match($value1));
+ $this->assertFalse($this->matcher->match($value2));
+ $this->assertTrue($this->rethrowingMatcher->match($value3));
+ }
+
+ public function testMatchesWhereNotMatchAndRethrowing()
+ {
+ $this->expectException($this->assertionFailedError);
+ $value = 'value';
+ $this->constraint
+ ->shouldReceive('evaluate')
+ ->once()
+ ->with($value)
+ ->andThrow($this->assertionFailedError)
+ ;
+ $this->rethrowingMatcher->match($value);
+ }
+
+ public function test__toString()
+ {
+ $this->assertEquals('', $this->matcher);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Matcher/SubsetTest.php b/vendor/mockery/mockery/tests/Mockery/Matcher/SubsetTest.php
new file mode 100644
index 0000000..e45e17c
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Matcher/SubsetTest.php
@@ -0,0 +1,97 @@
+ 123]);
+
+ $actual = [
+ 'foo' => 'bar',
+ 'dave' => 123,
+ 'bar' => 'baz',
+ ];
+
+ $this->assertTrue($matcher->match($actual));
+ }
+
+ /** @test */
+ public function it_recursively_matches()
+ {
+ $matcher = Subset::strict(['foo' => ['bar' => ['baz' => 123]]]);
+
+ $actual = [
+ 'foo' => [
+ 'bar' => [
+ 'baz' => 123,
+ ]
+ ],
+ 'dave' => 123,
+ 'bar' => 'baz',
+ ];
+
+ $this->assertTrue($matcher->match($actual));
+ }
+
+ /** @test */
+ public function it_is_strict_by_default()
+ {
+ $matcher = new Subset(['dave' => 123]);
+
+ $actual = [
+ 'foo' => 'bar',
+ 'dave' => 123.0,
+ 'bar' => 'baz',
+ ];
+
+ $this->assertFalse($matcher->match($actual));
+ }
+
+ /** @test */
+ public function it_can_run_a_loose_comparison()
+ {
+ $matcher = Subset::loose(['dave' => 123]);
+
+ $actual = [
+ 'foo' => 'bar',
+ 'dave' => 123.0,
+ 'bar' => 'baz',
+ ];
+
+ $this->assertTrue($matcher->match($actual));
+ }
+
+ /** @test */
+ public function it_returns_false_if_actual_is_not_an_array()
+ {
+ $matcher = new Subset(['dave' => 123]);
+
+ $actual = null;
+
+ $this->assertFalse($matcher->match($actual));
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockClassWithFinalWakeupTest.php b/vendor/mockery/mockery/tests/Mockery/MockClassWithFinalWakeupTest.php
new file mode 100644
index 0000000..f84b30d
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockClassWithFinalWakeupTest.php
@@ -0,0 +1,94 @@
+
+ * @license http://github.com/padraic/mockery/blob/master/LICENSE New BSD License
+ */
+
+namespace test\Mockery;
+
+use Mockery\Adapter\Phpunit\MockeryTestCase;
+
+class MockClassWithFinalWakeupTest extends MockeryTestCase
+{
+ protected function setUp()
+ {
+ $this->container = new \Mockery\Container;
+ }
+
+ protected function tearDown()
+ {
+ $this->container->mockery_close();
+ }
+
+ /**
+ * @test
+ *
+ * Test that we are able to create partial mocks of classes that have
+ * a __wakeup method marked as final. As long as __wakeup is not one of the
+ * mocked methods.
+ */
+ public function testCreateMockForClassWithFinalWakeup()
+ {
+ $mock = $this->container->mock("test\Mockery\TestWithFinalWakeup");
+ $this->assertInstanceOf("test\Mockery\TestWithFinalWakeup", $mock);
+ $this->assertEquals('test\Mockery\TestWithFinalWakeup::__wakeup', $mock->__wakeup());
+
+ $mock = $this->container->mock('test\Mockery\SubclassWithFinalWakeup');
+ $this->assertInstanceOf('test\Mockery\SubclassWithFinalWakeup', $mock);
+ $this->assertEquals('test\Mockery\TestWithFinalWakeup::__wakeup', $mock->__wakeup());
+ }
+
+ public function testCreateMockForClassWithNonFinalWakeup()
+ {
+ $mock = $this->container->mock('test\Mockery\TestWithNonFinalWakeup');
+ $this->assertInstanceOf('test\Mockery\TestWithNonFinalWakeup', $mock);
+
+ // Make sure __wakeup is overridden and doesn't return anything.
+ $this->assertNull($mock->__wakeup());
+ }
+}
+
+class TestWithFinalWakeup
+{
+ public function foo()
+ {
+ return 'foo';
+ }
+
+ public function bar()
+ {
+ return 'bar';
+ }
+
+ final public function __wakeup()
+ {
+ return __METHOD__;
+ }
+}
+
+class SubclassWithFinalWakeup extends TestWithFinalWakeup
+{
+}
+
+class TestWithNonFinalWakeup
+{
+ public function __wakeup()
+ {
+ return __METHOD__;
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockClassWithMethodOverloadingTest.php b/vendor/mockery/mockery/tests/Mockery/MockClassWithMethodOverloadingTest.php
new file mode 100644
index 0000000..b0284dc
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockClassWithMethodOverloadingTest.php
@@ -0,0 +1,43 @@
+makePartial();
+ $this->assertInstanceOf('test\Mockery\TestWithMethodOverloading', $mock);
+
+ // TestWithMethodOverloading::__call wouldn't be used. See Gotchas!.
+ $mock->randomMethod();
+ }
+
+ public function testCreateMockForClassWithMethodOverloadingWithExistingMethod()
+ {
+ $mock = mock('test\Mockery\TestWithMethodOverloading')
+ ->makePartial();
+ $this->assertInstanceOf('test\Mockery\TestWithMethodOverloading', $mock);
+
+ $this->assertSame(1, $mock->thisIsRealMethod());
+ }
+}
+
+class TestWithMethodOverloading
+{
+ public function __call($name, $arguments)
+ {
+ return 1;
+ }
+
+ public function thisIsRealMethod()
+ {
+ return 1;
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockClassWithUnknownTypeHintTest.php b/vendor/mockery/mockery/tests/Mockery/MockClassWithUnknownTypeHintTest.php
new file mode 100644
index 0000000..8706f8d
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockClassWithUnknownTypeHintTest.php
@@ -0,0 +1,43 @@
+assertInstanceOf(MockInterface::class, $mock);
+ }
+}
+
+class HasUnknownClassAsTypeHintOnMethod
+{
+ public function foo(\UnknownTestClass\Bar $bar)
+ {
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockTest.php b/vendor/mockery/mockery/tests/Mockery/MockTest.php
new file mode 100644
index 0000000..15b4b7b
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockTest.php
@@ -0,0 +1,219 @@
+allowMockingNonExistentMethods(false);
+ $m = mock();
+ $m->shouldReceive("test123")->andReturn(true);
+ assertThat($m->test123(), equalTo(true));
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(true);
+ }
+
+ public function testMockWithNotAllowingMockingOfNonExistentMethodsCanBeGivenAdditionalMethodsToMockEvenIfTheyDontExistOnClass()
+ {
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
+ $m = mock('ExampleClassForTestingNonExistentMethod');
+ $m->shouldAllowMockingMethod('testSomeNonExistentMethod');
+ $m->shouldReceive("testSomeNonExistentMethod")->andReturn(true);
+ assertThat($m->testSomeNonExistentMethod(), equalTo(true));
+ \Mockery::getConfiguration()->allowMockingNonExistentMethods(true);
+ }
+
+ public function testShouldAllowMockingMethodReturnsMockInstance()
+ {
+ $m = Mockery::mock('someClass');
+ $this->assertInstanceOf('Mockery\MockInterface', $m->shouldAllowMockingMethod('testFunction'));
+ }
+
+ public function testShouldAllowMockingProtectedMethodReturnsMockInstance()
+ {
+ $m = Mockery::mock('someClass');
+ $this->assertInstanceOf('Mockery\MockInterface', $m->shouldAllowMockingProtectedMethods('testFunction'));
+ }
+
+ public function testMockAddsToString()
+ {
+ $mock = mock('ClassWithNoToString');
+ $this->assertTrue(method_exists($mock, '__toString'));
+ }
+
+ public function testMockToStringMayBeDeferred()
+ {
+ $mock = mock('ClassWithToString')->makePartial();
+ $this->assertEquals("foo", (string)$mock);
+ }
+
+ public function testMockToStringShouldIgnoreMissingAlwaysReturnsString()
+ {
+ $mock = mock('ClassWithNoToString')->shouldIgnoreMissing();
+ $this->assertNotEquals('', (string)$mock);
+
+ $mock->asUndefined();
+ $this->assertNotEquals('', (string)$mock);
+ }
+
+ public function testShouldIgnoreMissing()
+ {
+ $mock = mock('ClassWithNoToString')->shouldIgnoreMissing();
+ $this->assertNull($mock->nonExistingMethod());
+ }
+
+ /**
+ * @expectedException Mockery\Exception
+ */
+ public function testShouldIgnoreMissingDisallowMockingNonExistentMethodsUsingGlobalConfiguration()
+ {
+ Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
+ $mock = mock('ClassWithMethods')->shouldIgnoreMissing();
+ $mock->shouldReceive('nonExistentMethod');
+ }
+
+ /**
+ * @expectedException BadMethodCallException
+ */
+ public function testShouldIgnoreMissingCallingNonExistentMethodsUsingGlobalConfiguration()
+ {
+ Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
+ $mock = mock('ClassWithMethods')->shouldIgnoreMissing();
+ $mock->nonExistentMethod();
+ }
+
+ public function testShouldIgnoreMissingCallingExistentMethods()
+ {
+ Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
+ $mock = mock('ClassWithMethods')->shouldIgnoreMissing();
+ assertThat(nullValue($mock->foo()));
+ $mock->shouldReceive('bar')->passthru();
+ assertThat($mock->bar(), equalTo('bar'));
+ }
+
+ public function testShouldIgnoreMissingCallingNonExistentMethods()
+ {
+ Mockery::getConfiguration()->allowMockingNonExistentMethods(true);
+ $mock = mock('ClassWithMethods')->shouldIgnoreMissing();
+ assertThat(nullValue($mock->foo()));
+ assertThat(nullValue($mock->bar()));
+ assertThat(nullValue($mock->nonExistentMethod()));
+
+ $mock->shouldReceive(array('foo' => 'new_foo', 'nonExistentMethod' => 'result'));
+ $mock->shouldReceive('bar')->passthru();
+ assertThat($mock->foo(), equalTo('new_foo'));
+ assertThat($mock->bar(), equalTo('bar'));
+ assertThat($mock->nonExistentMethod(), equalTo('result'));
+ }
+
+ public function testCanMockException()
+ {
+ $exception = Mockery::mock('Exception');
+ $this->assertInstanceOf('Exception', $exception);
+ }
+
+ public function testCanMockSubclassOfException()
+ {
+ $errorException = Mockery::mock('ErrorException');
+ $this->assertInstanceOf('ErrorException', $errorException);
+ $this->assertInstanceOf('Exception', $errorException);
+ }
+
+ public function testCallingShouldReceiveWithoutAValidMethodName()
+ {
+ $mock = Mockery::mock();
+
+ $this->expectException("InvalidArgumentException", "Received empty method name");
+ $mock->shouldReceive("");
+ }
+
+ /**
+ * @expectedException Mockery\Exception
+ */
+ public function testShouldThrowExceptionWithInvalidClassName()
+ {
+ mock('ClassName.CannotContainDot');
+ }
+
+
+ /** @test */
+ public function expectation_count_will_count_expectations()
+ {
+ $mock = new Mock();
+ $mock->shouldReceive("doThis")->once();
+ $mock->shouldReceive("doThat")->once();
+
+ $this->assertEquals(2, $mock->mockery_getExpectationCount());
+ }
+
+ /** @test */
+ public function expectation_count_will_ignore_defaults_if_overriden()
+ {
+ $mock = new Mock();
+ $mock->shouldReceive("doThis")->once()->byDefault();
+ $mock->shouldReceive("doThis")->twice();
+ $mock->shouldReceive("andThis")->twice();
+
+ $this->assertEquals(2, $mock->mockery_getExpectationCount());
+ }
+
+ /** @test */
+ public function expectation_count_will_count_defaults_if_not_overriden()
+ {
+ $mock = new Mock();
+ $mock->shouldReceive("doThis")->once()->byDefault();
+ $mock->shouldReceive("doThat")->once()->byDefault();
+
+ $this->assertEquals(2, $mock->mockery_getExpectationCount());
+ }
+}
+
+
+class ExampleClassForTestingNonExistentMethod
+{
+}
+
+class ClassWithToString
+{
+ public function __toString()
+ {
+ return 'foo';
+ }
+}
+
+class ClassWithNoToString
+{
+}
+
+class ClassWithMethods
+{
+ public function foo()
+ {
+ return 'foo';
+ }
+
+ public function bar()
+ {
+ return 'bar';
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockeryCanMockClassesWithSemiReservedWordsTest.php b/vendor/mockery/mockery/tests/Mockery/MockeryCanMockClassesWithSemiReservedWordsTest.php
new file mode 100644
index 0000000..fe8ed91
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockeryCanMockClassesWithSemiReservedWordsTest.php
@@ -0,0 +1,28 @@
+shouldReceive("include")->andReturn("foo");
+
+ $this->assertTrue(method_exists($mock, "include"));
+ $this->assertEquals("foo", $mock->include());
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockeryCanMockMultipleInterfacesWhichOverlapTest.php b/vendor/mockery/mockery/tests/Mockery/MockeryCanMockMultipleInterfacesWhichOverlapTest.php
new file mode 100644
index 0000000..6f49428
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockeryCanMockMultipleInterfacesWhichOverlapTest.php
@@ -0,0 +1,65 @@
+mock('Mockery\Tests\Evenement_EventEmitter', 'Mockery\Tests\Chatroulette_ConnectionInterface');
+ }
+}
+
+interface Evenement_EventEmitterInterface
+{
+ public function on($name, $callback);
+}
+
+class Evenement_EventEmitter implements Evenement_EventEmitterInterface
+{
+ public function on($name, $callback)
+ {
+ }
+}
+
+interface React_StreamInterface extends Evenement_EventEmitterInterface
+{
+ public function close();
+}
+
+interface React_ReadableStreamInterface extends React_StreamInterface
+{
+ public function pause();
+}
+
+interface React_WritableStreamInterface extends React_StreamInterface
+{
+ public function write($data);
+}
+
+interface Chatroulette_ConnectionInterface extends React_ReadableStreamInterface, React_WritableStreamInterface
+{
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockingAllLowerCasedMethodsTest.php b/vendor/mockery/mockery/tests/Mockery/MockingAllLowerCasedMethodsTest.php
new file mode 100644
index 0000000..295ae6c
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockingAllLowerCasedMethodsTest.php
@@ -0,0 +1,43 @@
+shouldReceive('userExpectsCamelCaseMethod')
+ ->andReturn('mocked');
+
+ $result = $mock->userExpectsCamelCaseMethod();
+
+ $expected = 'mocked';
+
+ self::assertSame($expected, $result);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockingClassConstantsTest.php b/vendor/mockery/mockery/tests/Mockery/MockingClassConstantsTest.php
new file mode 100644
index 0000000..4cb7b83
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockingClassConstantsTest.php
@@ -0,0 +1,43 @@
+setConstantsMap([
+ 'ClassWithConstants' => [
+ 'FOO' => 'baz',
+ 'X' => 2,
+ ]
+ ]);
+
+ $mock = \Mockery::mock('overload:ClassWithConstants');
+
+ self::assertEquals('baz', $mock::FOO);
+ self::assertEquals(2, $mock::X);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockingHHVMMethodsTest.php b/vendor/mockery/mockery/tests/Mockery/MockingHHVMMethodsTest.php
new file mode 100644
index 0000000..7377f16
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockingHHVMMethodsTest.php
@@ -0,0 +1,107 @@
+isHHVM()) {
+ $this->markTestSkipped('For HHVM test only');
+ }
+
+ parent::setUp();
+
+ require_once __DIR__."/Fixtures/MethodWithHHVMReturnType.php";
+ }
+
+ /** @test */
+ public function it_strip_hhvm_array_return_types()
+ {
+ $mock = mock('test\Mockery\Fixtures\MethodWithHHVMReturnType');
+
+ $mock->shouldReceive('nullableHHVMArray')->andReturn(array('key' => true));
+ $mock->nullableHHVMArray();
+ }
+
+ /** @test */
+ public function it_strip_hhvm_void_return_types()
+ {
+ $mock = mock('test\Mockery\Fixtures\MethodWithHHVMReturnType');
+
+ $mock->shouldReceive('HHVMVoid')->andReturnNull();
+ $mock->HHVMVoid();
+ }
+
+ /** @test */
+ public function it_strip_hhvm_mixed_return_types()
+ {
+ $mock = mock('test\Mockery\Fixtures\MethodWithHHVMReturnType');
+
+ $mock->shouldReceive('HHVMMixed')->andReturnNull();
+ $mock->HHVMMixed();
+ }
+
+ /** @test */
+ public function it_strip_hhvm_this_return_types()
+ {
+ $mock = mock('test\Mockery\Fixtures\MethodWithHHVMReturnType');
+
+ $mock->shouldReceive('HHVMThis')->andReturn(new MethodWithHHVMReturnType());
+ $mock->HHVMThis();
+ }
+
+ /** @test */
+ public function it_allow_hhvm_string_return_types()
+ {
+ $mock = mock('test\Mockery\Fixtures\MethodWithHHVMReturnType');
+
+ $mock->shouldReceive('HHVMString')->andReturn('a string');
+ $mock->HHVMString();
+ }
+
+ /** @test */
+ public function it_allow_hhvm_imm_vector_return_types()
+ {
+ $mock = mock('test\Mockery\Fixtures\MethodWithHHVMReturnType');
+
+ $mock->shouldReceive('HHVMImmVector')->andReturn(new \HH\ImmVector([1, 2, 3]));
+ $mock->HHVMImmVector();
+ }
+
+ /**
+ * Returns true when it is HHVM.
+ */
+ private function isHHVM()
+ {
+ return \defined('HHVM_VERSION');
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockingMethodsWithIterableTypeHintsTest.php b/vendor/mockery/mockery/tests/Mockery/MockingMethodsWithIterableTypeHintsTest.php
new file mode 100644
index 0000000..34ef54c
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockingMethodsWithIterableTypeHintsTest.php
@@ -0,0 +1,39 @@
+assertInstanceOf(\test\Mockery\Fixtures\MethodWithIterableTypeHints::class, $mock);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockingMethodsWithNullableParametersTest.php b/vendor/mockery/mockery/tests/Mockery/MockingMethodsWithNullableParametersTest.php
new file mode 100644
index 0000000..e3aa767
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockingMethodsWithNullableParametersTest.php
@@ -0,0 +1,52 @@
+assertInstanceOf(\test\Mockery\Fixtures\MethodWithNullableTypedParameter::class, $mock);
+ }
+
+ /**
+ * @test
+ */
+ public function it_can_handle_default_parameters()
+ {
+ require __DIR__."/Fixtures/MethodWithParametersWithDefaultValues.php";
+ $mock = mock("test\Mockery\Fixtures\MethodWithParametersWithDefaultValues");
+
+ $this->assertInstanceOf(\test\Mockery\Fixtures\MethodWithParametersWithDefaultValues::class, $mock);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockingNullableMethodsTest.php b/vendor/mockery/mockery/tests/Mockery/MockingNullableMethodsTest.php
new file mode 100644
index 0000000..9b7bdc2
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockingNullableMethodsTest.php
@@ -0,0 +1,217 @@
+shouldReceive('nonNullablePrimitive')->andReturn('a string');
+ $mock->nonNullablePrimitive();
+ }
+
+ /**
+ * @test
+ * @expectedException \TypeError
+ */
+ public function itShouldNotAllowNonNullToBeNull()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nonNullablePrimitive')->andReturn(null);
+ $mock->nonNullablePrimitive();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowPrimitiveNullableToBeNull()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nullablePrimitive')->andReturn(null);
+ $mock->nullablePrimitive();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowPrimitiveNullabeToBeSet()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nullablePrimitive')->andReturn('a string');
+ $mock->nullablePrimitive();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowSelfToBeSet()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nonNullableSelf')->andReturn(new MethodWithNullableReturnType());
+ $mock->nonNullableSelf();
+ }
+
+ /**
+ * @test
+ * @expectedException \TypeError
+ */
+ public function itShouldNotAllowSelfToBeNull()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nonNullableSelf')->andReturn(null);
+ $mock->nonNullableSelf();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowNullableSelfToBeSet()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nullableSelf')->andReturn(new MethodWithNullableReturnType());
+ $mock->nullableSelf();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowNullableSelfToBeNull()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nullableSelf')->andReturn(null);
+ $mock->nullableSelf();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowClassToBeSet()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nonNullableClass')->andReturn(new MethodWithNullableReturnType());
+ $mock->nonNullableClass();
+ }
+
+ /**
+ * @test
+ * @expectedException \TypeError
+ */
+ public function itShouldNotAllowClassToBeNull()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nonNullableClass')->andReturn(null);
+ $mock->nonNullableClass();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowNullalbeClassToBeSet()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nullableClass')->andReturn(new MethodWithNullableReturnType());
+ $mock->nullableClass();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowNullableClassToBeNull()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithNullableReturnType");
+
+ $mock->shouldReceive('nullableClass')->andReturn(null);
+ $mock->nullableClass();
+ }
+
+ /** @test */
+ public function it_allows_returning_null_for_nullable_object_return_types()
+ {
+ $double= \Mockery::mock(MethodWithNullableReturnType::class);
+
+ $double->shouldReceive("nullableClass")->andReturnNull();
+
+ $this->assertNull($double->nullableClass());
+ }
+
+ /** @test */
+ public function it_allows_returning_null_for_nullable_string_return_types()
+ {
+ $double= \Mockery::mock(MethodWithNullableReturnType::class);
+
+ $double->shouldReceive("nullableString")->andReturnNull();
+
+ $this->assertNull($double->nullableString());
+ }
+
+ /** @test */
+ public function it_allows_returning_null_for_nullable_int_return_types()
+ {
+ $double= \Mockery::mock(MethodWithNullableReturnType::class);
+
+ $double->shouldReceive("nullableInt")->andReturnNull();
+
+ $this->assertNull($double->nullableInt());
+ }
+
+ /** @test */
+ public function it_returns_null_on_calls_to_ignored_methods_of_spies_if_return_type_is_nullable()
+ {
+ $double = \Mockery::spy(MethodWithNullableReturnType::class);
+
+ $this->assertNull($double->nullableClass());
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockingProtectedMethodsTest.php b/vendor/mockery/mockery/tests/Mockery/MockingProtectedMethodsTest.php
new file mode 100644
index 0000000..7810d1b
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockingProtectedMethodsTest.php
@@ -0,0 +1,133 @@
+assertEquals("bar", $mock->bar());
+ }
+
+ /**
+ * @test
+ *
+ * This is a regression test, basically we don't want the mock handling
+ * interfering with calling protected methods partials
+ */
+ public function shouldAutomaticallyDeferCallsToProtectedMethodsForRuntimePartials()
+ {
+ $mock = mock("test\Mockery\TestWithProtectedMethods")->makePartial();
+ $this->assertEquals("bar", $mock->bar());
+ }
+
+ /** @test */
+ public function shouldAutomaticallyIgnoreAbstractProtectedMethods()
+ {
+ $mock = mock("test\Mockery\TestWithProtectedMethods")->makePartial();
+ $this->assertNull($mock->foo());
+ }
+
+ /** @test */
+ public function shouldAllowMockingProtectedMethods()
+ {
+ $mock = mock("test\Mockery\TestWithProtectedMethods")
+ ->makePartial()
+ ->shouldAllowMockingProtectedMethods();
+
+ $mock->shouldReceive("protectedBar")->andReturn("notbar");
+ $this->assertEquals("notbar", $mock->bar());
+ }
+
+ /** @test */
+ public function shouldAllowMockingProtectedMethodOnDefinitionTimePartial()
+ {
+ $mock = mock("test\Mockery\TestWithProtectedMethods[protectedBar]")
+ ->shouldAllowMockingProtectedMethods();
+
+ $mock->shouldReceive("protectedBar")->andReturn("notbar");
+ $this->assertEquals("notbar", $mock->bar());
+ }
+
+ /** @test */
+ public function shouldAllowMockingAbstractProtectedMethods()
+ {
+ $mock = mock("test\Mockery\TestWithProtectedMethods")
+ ->makePartial()
+ ->shouldAllowMockingProtectedMethods();
+
+ $mock->shouldReceive("abstractProtected")->andReturn("abstractProtected");
+ $this->assertEquals("abstractProtected", $mock->foo());
+ }
+
+ /** @test */
+ public function shouldAllowMockingIncreasedVisabilityMethods()
+ {
+ $mock = mock("test\Mockery\TestIncreasedVisibilityChild");
+ $mock->shouldReceive('foobar')->andReturn("foobar");
+ $this->assertEquals('foobar', $mock->foobar());
+ }
+}
+
+
+abstract class TestWithProtectedMethods
+{
+ public function foo()
+ {
+ return $this->abstractProtected();
+ }
+
+ abstract protected function abstractProtected();
+
+ public function bar()
+ {
+ return $this->protectedBar();
+ }
+
+ protected function protectedBar()
+ {
+ return 'bar';
+ }
+}
+
+class TestIncreasedVisibilityParent
+{
+ protected function foobar()
+ {
+ }
+}
+
+class TestIncreasedVisibilityChild extends TestIncreasedVisibilityParent
+{
+ public function foobar()
+ {
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockingVariadicArgumentsTest.php b/vendor/mockery/mockery/tests/Mockery/MockingVariadicArgumentsTest.php
new file mode 100644
index 0000000..a940f63
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockingVariadicArgumentsTest.php
@@ -0,0 +1,45 @@
+shouldReceive("foo")->andReturn("notbar");
+ $this->assertEquals("notbar", $mock->foo());
+ }
+}
+
+
+abstract class TestWithVariadicArguments
+{
+ public function foo(...$bar)
+ {
+ return $bar;
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/MockingVoidMethodsTest.php b/vendor/mockery/mockery/tests/Mockery/MockingVoidMethodsTest.php
new file mode 100644
index 0000000..f1f167a
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/MockingVoidMethodsTest.php
@@ -0,0 +1,53 @@
+assertInstanceOf(\test\Mockery\Fixtures\MethodWithVoidReturnType::class, $mock);
+ }
+
+ /** @test */
+ public function it_can_stub_and_mock_void_methods()
+ {
+ $mock = mock("test\Mockery\Fixtures\MethodWithVoidReturnType");
+
+ $mock->shouldReceive("foo");
+ $mock->foo();
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/NamedMockTest.php b/vendor/mockery/mockery/tests/Mockery/NamedMockTest.php
new file mode 100644
index 0000000..b39355f
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/NamedMockTest.php
@@ -0,0 +1,86 @@
+assertInstanceOf("Mockery\Dave123", $mock);
+ }
+
+ /** @test */
+ public function itCreatesPassesFurtherArgumentsJustLikeMock()
+ {
+ $mock = Mockery::namedMock("Mockery\Dave456", "DateTime", array(
+ "getDave" => "dave"
+ ));
+
+ $this->assertInstanceOf("DateTime", $mock);
+ $this->assertEquals("dave", $mock->getDave());
+ }
+
+ /**
+ * @test
+ * @expectedException Mockery\Exception
+ * @expectedExceptionMessage The mock named 'Mockery\Dave7' has been already defined with a different mock configuration
+ */
+ public function itShouldThrowIfAttemptingToRedefineNamedMock()
+ {
+ $mock = Mockery::namedMock("Mockery\Dave7");
+ $mock = Mockery::namedMock("Mockery\Dave7", "DateTime");
+ }
+
+ /** @test */
+ public function itCreatesConcreteMethodImplementationWithReturnType()
+ {
+ $cactus = new \Nature\Plant();
+ $gardener = Mockery::namedMock(
+ "NewNamespace\\ClassName",
+ "Gardener",
+ array('water' => true)
+ );
+ $this->assertTrue($gardener->water($cactus));
+ }
+
+ /**
+ * @test
+ * @requires PHP 7.0.0
+ */
+ public function it_gracefully_handles_namespacing()
+ {
+ $animal = Mockery::namedMock(
+ uniqid(Animal::class, false),
+ Animal::class
+ );
+
+ $animal->shouldReceive("habitat")->andReturn(new Habitat());
+
+ $this->assertInstanceOf(Habitat::class, $animal->habitat());
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/SpyTest.php b/vendor/mockery/mockery/tests/Mockery/SpyTest.php
new file mode 100644
index 0000000..73de84c
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/SpyTest.php
@@ -0,0 +1,152 @@
+myMethod();
+ $spy->shouldHaveReceived("myMethod");
+
+ $this->expectException("Mockery\Exception\InvalidCountException");
+ $spy->shouldHaveReceived("someMethodThatWasNotCalled");
+ }
+
+ /** @test */
+ public function itVerifiesAMethodWasNotCalled()
+ {
+ $spy = m::spy();
+ $spy->shouldNotHaveReceived("myMethod");
+
+ $this->expectException("Mockery\Exception\InvalidCountException");
+ $spy->myMethod();
+ $spy->shouldNotHaveReceived("myMethod");
+ }
+
+ /** @test */
+ public function itVerifiesAMethodWasNotCalledWithParticularArguments()
+ {
+ $spy = m::spy();
+ $spy->myMethod(123, 456);
+
+ $spy->shouldNotHaveReceived("myMethod", array(789, 10));
+
+ $this->expectException("Mockery\Exception\InvalidCountException");
+ $spy->shouldNotHaveReceived("myMethod", array(123, 456));
+ }
+
+ /** @test */
+ public function itVerifiesAMethodWasCalledASpecificNumberOfTimes()
+ {
+ $spy = m::spy();
+ $spy->myMethod();
+ $spy->myMethod();
+ $spy->shouldHaveReceived("myMethod")->twice();
+
+ $this->expectException("Mockery\Exception\InvalidCountException");
+ $spy->myMethod();
+ $spy->shouldHaveReceived("myMethod")->twice();
+ }
+
+ /** @test */
+ public function itVerifiesAMethodWasCalledWithSpecificArguments()
+ {
+ $spy = m::spy();
+ $spy->myMethod(123, "a string");
+ $spy->shouldHaveReceived("myMethod")->with(123, "a string");
+ $spy->shouldHaveReceived("myMethod", array(123, "a string"));
+
+ $this->expectException("Mockery\Exception\InvalidCountException");
+ $spy->shouldHaveReceived("myMethod")->with(123);
+ }
+
+ /** @test */
+ public function itIncrementsExpectationCountWhenShouldHaveReceivedIsUsed()
+ {
+ $spy = m::spy();
+ $spy->myMethod('param1', 'param2');
+ $spy->shouldHaveReceived('myMethod')->with('param1', 'param2');
+ $this->assertEquals(1, $spy->mockery_getExpectationCount());
+ }
+
+ /** @test */
+ public function itIncrementsExpectationCountWhenShouldNotHaveReceivedIsUsed()
+ {
+ $spy = m::spy();
+ $spy->shouldNotHaveReceived('method');
+ $this->assertEquals(1, $spy->mockery_getExpectationCount());
+ }
+
+ /** @test */
+ public function any_args_can_be_used_with_alternative_syntax()
+ {
+ $spy = m::spy();
+ $spy->foo(123, 456);
+
+ $spy->shouldHaveReceived()->foo(anyArgs());
+ }
+
+ /** @test */
+ public function should_have_received_higher_order_message_call_a_method_with_correct_arguments()
+ {
+ $spy = m::spy();
+ $spy->foo(123);
+
+ $spy->shouldHaveReceived()->foo(123);
+ }
+
+ /** @test */
+ public function should_have_received_higher_order_message_call_a_method_with_incorrect_arguments_throws_exception()
+ {
+ $spy = m::spy();
+ $spy->foo(123);
+
+ $this->expectException("Mockery\Exception\InvalidCountException");
+ $spy->shouldHaveReceived()->foo(456);
+ }
+
+ /** @test */
+ public function should_not_have_received_higher_order_message_call_a_method_with_incorrect_arguments()
+ {
+ $spy = m::spy();
+ $spy->foo(123);
+
+ $spy->shouldNotHaveReceived()->foo(456);
+ }
+
+ /** @test */
+ public function should_not_have_received_higher_order_message_call_a_method_with_correct_arguments_throws_an_exception()
+ {
+ $spy = m::spy();
+ $spy->foo(123);
+
+ $this->expectException("Mockery\Exception\InvalidCountException");
+ $spy->shouldNotHaveReceived()->foo(123);
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/Stubs/Animal.php b/vendor/mockery/mockery/tests/Mockery/Stubs/Animal.php
new file mode 100644
index 0000000..50de129
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/Stubs/Animal.php
@@ -0,0 +1,29 @@
+assertEquals('bar', $trait->foo());
+ }
+
+ /** @test */
+ public function it_creates_abstract_methods_as_necessary()
+ {
+ $trait = mock(TraitWithAbstractMethod::class, ['doBaz' => 'baz']);
+
+ $this->assertEquals('baz', $trait->baz());
+ }
+
+ /** @test */
+ public function it_can_create_an_object_using_multiple_traits()
+ {
+ $trait = mock(SimpleTrait::class, TraitWithAbstractMethod::class, [
+ 'doBaz' => 123,
+ ]);
+
+ $this->assertEquals('bar', $trait->foo());
+ $this->assertEquals(123, $trait->baz());
+ }
+}
+
+trait SimpleTrait
+{
+ public function foo()
+ {
+ return 'bar';
+ }
+}
+
+trait TraitWithAbstractMethod
+{
+ public function baz()
+ {
+ return $this->doBaz();
+ }
+
+ abstract public function doBaz();
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/WithFormatterExpectationTest.php b/vendor/mockery/mockery/tests/Mockery/WithFormatterExpectationTest.php
new file mode 100644
index 0000000..2e3c4f9
--- /dev/null
+++ b/vendor/mockery/mockery/tests/Mockery/WithFormatterExpectationTest.php
@@ -0,0 +1,123 @@
+assertEquals(
+ $expected,
+ Mockery::formatObjects($args)
+ );
+ }
+
+ /**
+ * @expectedException Mockery\Exception\NoMatchingExpectationException
+ *
+ * Note that without the patch checked in with this test, rather than throwing
+ * an exception, the program will go into an infinite recursive loop
+ */
+ public function testFormatObjectsWithMockCalledInGetterDoesNotLeadToRecursion()
+ {
+ $mock = Mockery::mock('stdClass');
+ $mock->shouldReceive('doBar')->with('foo');
+ $obj = new ClassWithGetter($mock);
+ $obj->getFoo();
+ }
+
+ public function formatObjectsDataProvider()
+ {
+ return array(
+ array(
+ array(null),
+ ''
+ ),
+ array(
+ array('a string', 98768, array('a', 'nother', 'array')),
+ ''
+ ),
+ );
+ }
+
+ /** @test */
+ public function format_objects_should_not_call_getters_with_params()
+ {
+ $obj = new ClassWithGetterWithParam();
+ $string = Mockery::formatObjects(array($obj));
+
+ $this->assertNotContains('Missing argument 1 for', $string);
+ }
+
+ public function testFormatObjectsExcludesStaticProperties()
+ {
+ $obj = new ClassWithPublicStaticProperty();
+ $string = Mockery::formatObjects(array($obj));
+
+ $this->assertNotContains('excludedProperty', $string);
+ }
+
+ public function testFormatObjectsExcludesStaticGetters()
+ {
+ $obj = new ClassWithPublicStaticGetter();
+ $string = Mockery::formatObjects(array($obj));
+
+ $this->assertNotContains('getExcluded', $string);
+ }
+}
+
+class ClassWithGetter
+{
+ private $dep;
+
+ public function __construct($dep)
+ {
+ $this->dep = $dep;
+ }
+
+ public function getFoo()
+ {
+ return $this->dep->doBar('bar', $this);
+ }
+}
+
+class ClassWithGetterWithParam
+{
+ public function getBar($bar)
+ {
+ }
+}
+
+class ClassWithPublicStaticProperty
+{
+ public static $excludedProperty;
+}
+
+class ClassWithPublicStaticGetter
+{
+ public static function getExcluded()
+ {
+ }
+}
diff --git a/vendor/mockery/mockery/tests/Mockery/_files/file.txt b/vendor/mockery/mockery/tests/Mockery/_files/file.txt
new file mode 100644
index 0000000..e69de29
diff --git a/vendor/mockery/mockery/tests/PHP56/MockingOldStyleConstructorTest.php b/vendor/mockery/mockery/tests/PHP56/MockingOldStyleConstructorTest.php
new file mode 100644
index 0000000..89e66c0
--- /dev/null
+++ b/vendor/mockery/mockery/tests/PHP56/MockingOldStyleConstructorTest.php
@@ -0,0 +1,44 @@
+assertInstanceOf(MockInterface::class, mock('MockeryTest_OldStyleConstructor'));
+ }
+}
+
+class MockeryTest_OldStyleConstructor
+{
+ public function MockeryTest_OldStyleConstructor($arg)
+ {
+ }
+}
diff --git a/vendor/mockery/mockery/tests/PHP70/Generator/StringManipulation/Pass/MagicMethodTypeHintsPassTest.php b/vendor/mockery/mockery/tests/PHP70/Generator/StringManipulation/Pass/MagicMethodTypeHintsPassTest.php
new file mode 100644
index 0000000..a1957ff
--- /dev/null
+++ b/vendor/mockery/mockery/tests/PHP70/Generator/StringManipulation/Pass/MagicMethodTypeHintsPassTest.php
@@ -0,0 +1,392 @@
+pass = new MagicMethodTypeHintsPass;
+ $this->mockedConfiguration = m::mock(
+ 'Mockery\Generator\MockConfiguration'
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWork()
+ {
+ $this->assertTrue(true);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGrabClassMagicMethods()
+ {
+ $targetClass = DefinedTargetClass::factory(
+ 'Mockery\Test\Generator\StringManipulation\Pass\MagicDummy'
+ );
+ $magicMethods = $this->pass->getMagicMethods($targetClass);
+
+ $this->assertCount(6, $magicMethods);
+ $this->assertEquals('__isset', $magicMethods[0]->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGrabInterfaceMagicMethods()
+ {
+ $targetClass = DefinedTargetClass::factory(
+ 'Mockery\Test\Generator\StringManipulation\Pass\MagicInterfaceDummy'
+ );
+ $magicMethods = $this->pass->getMagicMethods($targetClass);
+
+ $this->assertCount(6, $magicMethods);
+ $this->assertEquals('__isset', $magicMethods[0]->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAddStringTypeHintOnMagicMethod()
+ {
+ $this->configureForClass();
+ $code = $this->pass->apply(
+ 'public function __isset($name) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('string $name', $code);
+
+ $this->configureForInterface();
+ $code = $this->pass->apply(
+ 'public function __isset($name) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('string $name', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAddStringTypeHintOnAllMagicMethods()
+ {
+ $this->configureForInterfaces([
+ 'Mockery\Test\Generator\StringManipulation\Pass\MagicInterfaceDummy',
+ 'Mockery\Test\Generator\StringManipulation\Pass\MagicUnsetInterfaceDummy'
+ ]);
+ $code = $this->pass->apply(
+ 'public function __isset($name) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('string $name', $code);
+ $code = $this->pass->apply(
+ 'public function __unset($name) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('string $name', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAddBooleanReturnOnMagicMethod()
+ {
+ $this->configureForClass();
+ $code = $this->pass->apply(
+ 'public function __isset($name) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains(' : bool', $code);
+
+ $this->configureForInterface();
+ $code = $this->pass->apply(
+ 'public function __isset($name) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains(' : bool', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAddTypeHintsOnToStringMethod()
+ {
+ $this->configureForClass();
+ $code = $this->pass->apply(
+ 'public function __toString() {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains(' : string', $code);
+
+ $this->configureForInterface();
+ $code = $this->pass->apply(
+ 'public function __toString() {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains(' : string', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAddTypeHintsOnCallMethod()
+ {
+ $this->configureForClass();
+ $code = $this->pass->apply(
+ 'public function __call($method, array $args) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('string $method', $code);
+
+ $this->configureForInterface();
+ $code = $this->pass->apply(
+ 'public function __call($method, array $args) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('string $method', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAddTypeHintsOnCallStaticMethod()
+ {
+ $this->configureForClass();
+ $code = $this->pass->apply(
+ 'public static function __callStatic($method, array $args) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('string $method', $code);
+
+ $this->configureForInterface();
+ $code = $this->pass->apply(
+ 'public static function __callStatic($method, array $args) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('string $method', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldNotAddReturnTypeHintIfOneIsNotFound()
+ {
+ $this->configureForClass('Mockery\Test\Generator\StringManipulation\Pass\MagicReturnDummy');
+ $code = $this->pass->apply(
+ 'public static function __isset($parameter) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains(') {', $code);
+
+ $this->configureForInterface('Mockery\Test\Generator\StringManipulation\Pass\MagicReturnInterfaceDummy');
+ $code = $this->pass->apply(
+ 'public static function __isset($parameter) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains(') {', $code);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnEmptyArrayIfClassDoesNotHaveMagicMethods()
+ {
+ $targetClass = DefinedTargetClass::factory(
+ '\StdClass'
+ );
+ $magicMethods = $this->pass->getMagicMethods($targetClass);
+ $this->assertInternalType('array', $magicMethods);
+ $this->assertEmpty($magicMethods);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnEmptyArrayIfClassTypeIsNotExpected()
+ {
+ $magicMethods = $this->pass->getMagicMethods(null);
+ $this->assertInternalType('array', $magicMethods);
+ $this->assertEmpty($magicMethods);
+ }
+
+ /**
+ * Tests if the pass correclty replaces all the magic
+ * method parameters with those found in the
+ * Mock class. This is made to avoid variable
+ * conflicts withing Mock's magic methods
+ * implementations.
+ *
+ * @test
+ */
+ public function itShouldGrabAndReplaceAllParametersWithTheCodeStringMatches()
+ {
+ $this->configureForClass();
+ $code = $this->pass->apply(
+ 'public function __call($method, array $args) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('$method', $code);
+ $this->assertContains('array $args', $code);
+
+ $this->configureForInterface();
+ $code = $this->pass->apply(
+ 'public function __call($method, array $args) {}',
+ $this->mockedConfiguration
+ );
+ $this->assertContains('$method', $code);
+ $this->assertContains('array $args', $code);
+ }
+
+ protected function configureForClass(string $className = 'Mockery\Test\Generator\StringManipulation\Pass\MagicDummy')
+ {
+ $targetClass = DefinedTargetClass::factory($className);
+
+ $this->mockedConfiguration
+ ->shouldReceive('getTargetClass')
+ ->andReturn($targetClass)
+ ->byDefault();
+ $this->mockedConfiguration
+ ->shouldReceive('getTargetInterfaces')
+ ->andReturn([])
+ ->byDefault();
+ }
+
+ protected function configureForInterface(string $interfaceName = 'Mockery\Test\Generator\StringManipulation\Pass\MagicDummy')
+ {
+ $targetInterface = DefinedTargetClass::factory($interfaceName);
+
+ $this->mockedConfiguration
+ ->shouldReceive('getTargetClass')
+ ->andReturn(null)
+ ->byDefault();
+ $this->mockedConfiguration
+ ->shouldReceive('getTargetInterfaces')
+ ->andReturn([$targetInterface])
+ ->byDefault();
+ }
+
+ protected function configureForInterfaces(array $interfaceNames)
+ {
+ $targetInterfaces = array_map([DefinedTargetClass::class, 'factory'], $interfaceNames);
+
+ $this->mockedConfiguration
+ ->shouldReceive('getTargetClass')
+ ->andReturn(null)
+ ->byDefault();
+ $this->mockedConfiguration
+ ->shouldReceive('getTargetInterfaces')
+ ->andReturn($targetInterfaces)
+ ->byDefault();
+ }
+}
+
+class MagicDummy
+{
+ public function __isset(string $name) : bool
+ {
+ return false;
+ }
+
+ public function __toString() : string
+ {
+ return '';
+ }
+
+ public function __wakeup()
+ {
+ }
+
+ public function __destruct()
+ {
+ }
+
+ public function __call(string $name, array $arguments) : string
+ {
+ }
+
+ public static function __callStatic(string $name, array $arguments) : int
+ {
+ }
+
+ public function nonMagicMethod()
+ {
+ }
+}
+
+class MagicReturnDummy
+{
+ public function __isset(string $name)
+ {
+ return false;
+ }
+}
+
+interface MagicInterfaceDummy
+{
+ public function __isset(string $name) : bool;
+
+ public function __toString() : string;
+
+ public function __wakeup();
+
+ public function __destruct();
+
+ public function __call(string $name, array $arguments) : string;
+
+ public static function __callStatic(string $name, array $arguments) : int;
+
+ public function nonMagicMethod();
+}
+
+interface MagicReturnInterfaceDummy
+{
+ public function __isset(string $name);
+}
+
+interface MagicUnsetInterfaceDummy
+{
+ public function __unset(string $name);
+}
diff --git a/vendor/mockery/mockery/tests/PHP70/MockingParameterAndReturnTypesTest.php b/vendor/mockery/mockery/tests/PHP70/MockingParameterAndReturnTypesTest.php
new file mode 100644
index 0000000..690625f
--- /dev/null
+++ b/vendor/mockery/mockery/tests/PHP70/MockingParameterAndReturnTypesTest.php
@@ -0,0 +1,177 @@
+shouldReceive("returnString");
+ $this->assertSame("", $mock->returnString());
+ }
+
+ public function testMockingIntegerReturnType()
+ {
+ $mock = mock("test\Mockery\TestWithParameterAndReturnType");
+
+ $mock->shouldReceive("returnInteger");
+ $this->assertSame(0, $mock->returnInteger());
+ }
+
+ public function testMockingFloatReturnType()
+ {
+ $mock = mock("test\Mockery\TestWithParameterAndReturnType");
+
+ $mock->shouldReceive("returnFloat");
+ $this->assertSame(0.0, $mock->returnFloat());
+ }
+
+ public function testMockingBooleanReturnType()
+ {
+ $mock = mock("test\Mockery\TestWithParameterAndReturnType");
+
+ $mock->shouldReceive("returnBoolean");
+ $this->assertFalse($mock->returnBoolean());
+ }
+
+ public function testMockingArrayReturnType()
+ {
+ $mock = mock("test\Mockery\TestWithParameterAndReturnType");
+
+ $mock->shouldReceive("returnArray");
+ $this->assertSame([], $mock->returnArray());
+ }
+
+ public function testMockingGeneratorReturnTyps()
+ {
+ $mock = mock("test\Mockery\TestWithParameterAndReturnType");
+
+ $mock->shouldReceive("returnGenerator");
+ $this->assertInstanceOf("\Generator", $mock->returnGenerator());
+ }
+
+ public function testMockingCallableReturnType()
+ {
+ $mock = mock("test\Mockery\TestWithParameterAndReturnType");
+
+ $mock->shouldReceive("returnCallable");
+ $this->assertInternalType('callable', $mock->returnCallable());
+ }
+
+ public function testMockingClassReturnTypes()
+ {
+ $mock = mock("test\Mockery\TestWithParameterAndReturnType");
+
+ $mock->shouldReceive("withClassReturnType");
+ $this->assertInstanceOf("test\Mockery\TestWithParameterAndReturnType", $mock->withClassReturnType());
+ }
+
+ public function testMockingParameterTypes()
+ {
+ $mock = mock("test\Mockery\TestWithParameterAndReturnType");
+
+ $mock->shouldReceive("withScalarParameters");
+ $mock->withScalarParameters(1, 1.0, true, 'string');
+ }
+
+ public function testIgnoringMissingReturnsType()
+ {
+ $mock = mock("test\Mockery\TestWithParameterAndReturnType");
+
+ $mock->shouldIgnoreMissing();
+
+ $this->assertSame('', $mock->returnString());
+ $this->assertSame(0, $mock->returnInteger());
+ $this->assertSame(0.0, $mock->returnFloat());
+ $this->assertFalse( $mock->returnBoolean());
+ $this->assertSame([], $mock->returnArray());
+ $this->assertInternalType('callable', $mock->returnCallable());
+ $this->assertInstanceOf("\Generator", $mock->returnGenerator());
+ $this->assertInstanceOf("test\Mockery\TestWithParameterAndReturnType", $mock->withClassReturnType());
+ }
+
+ public function testAutoStubbingSelf()
+ {
+ $spy = \Mockery::spy("test\Mockery\TestWithParameterAndReturnType");
+
+ $this->assertInstanceOf("test\Mockery\TestWithParameterAndReturnType", $spy->returnSelf());
+ }
+
+ public function testItShouldMockClassWithHintedParamsInMagicMethod()
+ {
+ $this->assertNotNull(
+ \Mockery::mock('test\Mockery\MagicParams')
+ );
+ }
+
+ public function testItShouldMockClassWithHintedReturnInMagicMethod()
+ {
+ $this->assertNotNull(
+ \Mockery::mock('test\Mockery\MagicReturns')
+ );
+ }
+}
+
+class MagicParams
+{
+ public function __isset(string $property)
+ {
+ return false;
+ }
+}
+
+class MagicReturns
+{
+ public function __isset($property) : bool
+ {
+ return false;
+ }
+}
+
+abstract class TestWithParameterAndReturnType
+{
+ public function returnString(): string {}
+
+ public function returnInteger(): int {}
+
+ public function returnFloat(): float {}
+
+ public function returnBoolean(): bool {}
+
+ public function returnArray(): array {}
+
+ public function returnCallable(): callable {}
+
+ public function returnGenerator(): \Generator {}
+
+ public function withClassReturnType(): TestWithParameterAndReturnType {}
+
+ public function withScalarParameters(int $integer, float $float, bool $boolean, string $string) {}
+
+ public function returnSelf(): self {}
+}
diff --git a/vendor/mockery/mockery/tests/PHP72/Php72LanguageFeaturesTest.php b/vendor/mockery/mockery/tests/PHP72/Php72LanguageFeaturesTest.php
new file mode 100644
index 0000000..f6fb957
--- /dev/null
+++ b/vendor/mockery/mockery/tests/PHP72/Php72LanguageFeaturesTest.php
@@ -0,0 +1,45 @@
+allows()->foo($object);
+
+ $mock->foo($object);
+ }
+
+ /** @test */
+ public function it_can_mock_a_class_with_an_object_return_type_hint()
+ {
+ $mock = spy(ReturnTypeObjectTypeHint::class);
+
+ $object = $mock->foo();
+
+ $this->assertTrue(is_object($object));
+ }
+}
+
+class ArgumentObjectTypeHint
+{
+ public function foo(object $foo)
+ {
+ }
+}
+
+class ReturnTypeObjectTypeHint
+{
+ public function foo(): object
+ {
+ }
+}
diff --git a/vendor/myclabs/deep-copy/.gitattributes b/vendor/myclabs/deep-copy/.gitattributes
new file mode 100755
index 0000000..8018068
--- /dev/null
+++ b/vendor/myclabs/deep-copy/.gitattributes
@@ -0,0 +1,7 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+*.png binary
+
+tests/ export-ignore
+phpunit.xml.dist export-ignore
diff --git a/vendor/myclabs/deep-copy/.gitignore b/vendor/myclabs/deep-copy/.gitignore
new file mode 100755
index 0000000..eef72f7
--- /dev/null
+++ b/vendor/myclabs/deep-copy/.gitignore
@@ -0,0 +1,3 @@
+/composer.phar
+/composer.lock
+/vendor/*
diff --git a/vendor/myclabs/deep-copy/.scrutinizer.yml b/vendor/myclabs/deep-copy/.scrutinizer.yml
new file mode 100644
index 0000000..6934299
--- /dev/null
+++ b/vendor/myclabs/deep-copy/.scrutinizer.yml
@@ -0,0 +1,4 @@
+build:
+ environment:
+ variables:
+ COMPOSER_ROOT_VERSION: '1.8.0'
diff --git a/vendor/myclabs/deep-copy/.travis.yml b/vendor/myclabs/deep-copy/.travis.yml
new file mode 100755
index 0000000..88f9d2e
--- /dev/null
+++ b/vendor/myclabs/deep-copy/.travis.yml
@@ -0,0 +1,40 @@
+language: php
+
+sudo: false
+
+env:
+ global:
+ - COMPOSER_ROOT_VERSION=1.8.0
+
+php:
+ - '7.1'
+ - '7.2'
+ - nightly
+
+matrix:
+ fast_finish: true
+ include:
+ - php: '7.1'
+ env: COMPOSER_FLAGS="--prefer-lowest"
+ allow_failures:
+ - php: nightly
+
+cache:
+ directories:
+ - $HOME/.composer/cache/files
+
+install:
+ - composer update --no-interaction --no-progress --no-suggest --prefer-dist $COMPOSER_FLAGS
+ - wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.0/coveralls.phar
+
+before_script:
+ - mkdir -p build/logs
+
+script:
+ - vendor/bin/phpunit --coverage-clover build/logs/clover.xml
+
+after_script:
+ - php coveralls.phar -v
+
+notifications:
+ email: false
diff --git a/vendor/myclabs/deep-copy/LICENSE b/vendor/myclabs/deep-copy/LICENSE
new file mode 100644
index 0000000..c3e8350
--- /dev/null
+++ b/vendor/myclabs/deep-copy/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 My C-Sense
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/myclabs/deep-copy/README.md b/vendor/myclabs/deep-copy/README.md
new file mode 100644
index 0000000..7abe5dc
--- /dev/null
+++ b/vendor/myclabs/deep-copy/README.md
@@ -0,0 +1,376 @@
+# DeepCopy
+
+DeepCopy helps you create deep copies (clones) of your objects. It is designed to handle cycles in the association graph.
+
+[![Build Status](https://travis-ci.org/myclabs/DeepCopy.png?branch=1.x)](https://travis-ci.org/myclabs/DeepCopy)
+[![Coverage Status](https://coveralls.io/repos/myclabs/DeepCopy/badge.png?branch=1.x)](https://coveralls.io/r/myclabs/DeepCopy?branch=1.x)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/myclabs/DeepCopy/badges/quality-score.png?s=2747100c19b275f93a777e3297c6c12d1b68b934)](https://scrutinizer-ci.com/g/myclabs/DeepCopy/)
+[![Total Downloads](https://poser.pugx.org/myclabs/deep-copy/downloads.svg)](https://packagist.org/packages/myclabs/deep-copy)
+
+
+**You are browsing the 1.x version, this version is in maintenance mode only. Please check the new
+[2.x](https://github.com/myclabs/DeepCopy/tree/2.x) version.**
+
+
+## Table of Contents
+
+1. [How](#how)
+1. [Why](#why)
+ 1. [Using simply `clone`](#using-simply-clone)
+ 1. [Overridding `__clone()`](#overridding-__clone)
+ 1. [With `DeepCopy`](#with-deepcopy)
+1. [How it works](#how-it-works)
+1. [Going further](#going-further)
+ 1. [Matchers](#matchers)
+ 1. [Property name](#property-name)
+ 1. [Specific property](#specific-property)
+ 1. [Type](#type)
+ 1. [Filters](#filters)
+ 1. [`SetNullFilter`](#setnullfilter-filter)
+ 1. [`KeepFilter`](#keepfilter-filter)
+ 1. [`DoctrineCollectionFilter`](#doctrinecollectionfilter-filter)
+ 1. [`DoctrineEmptyCollectionFilter`](#doctrineemptycollectionfilter-filter)
+ 1. [`DoctrineProxyFilter`](#doctrineproxyfilter-filter)
+ 1. [`ReplaceFilter`](#replacefilter-type-filter)
+ 1. [`ShallowCopyFilter`](#shallowcopyfilter-type-filter)
+1. [Edge cases](#edge-cases)
+1. [Contributing](#contributing)
+ 1. [Tests](#tests)
+
+
+## How?
+
+Install with Composer:
+
+```json
+composer require myclabs/deep-copy
+```
+
+Use simply:
+
+```php
+use DeepCopy\DeepCopy;
+
+$copier = new DeepCopy();
+$myCopy = $copier->copy($myObject);
+```
+
+
+## Why?
+
+- How do you create copies of your objects?
+
+```php
+$myCopy = clone $myObject;
+```
+
+- How do you create **deep** copies of your objects (i.e. copying also all the objects referenced in the properties)?
+
+You use [`__clone()`](http://www.php.net/manual/en/language.oop5.cloning.php#object.clone) and implement the behavior
+yourself.
+
+- But how do you handle **cycles** in the association graph?
+
+Now you're in for a big mess :(
+
+![association graph](doc/graph.png)
+
+
+### Using simply `clone`
+
+![Using clone](doc/clone.png)
+
+
+### Overridding `__clone()`
+
+![Overridding __clone](doc/deep-clone.png)
+
+
+### With `DeepCopy`
+
+![With DeepCopy](doc/deep-copy.png)
+
+
+## How it works
+
+DeepCopy recursively traverses all the object's properties and clones them. To avoid cloning the same object twice it
+keeps a hash map of all instances and thus preserves the object graph.
+
+To use it:
+
+```php
+use function DeepCopy\deep_copy;
+
+$copy = deep_copy($var);
+```
+
+Alternatively, you can create your own `DeepCopy` instance to configure it differently for example:
+
+```php
+use DeepCopy\DeepCopy;
+
+$copier = new DeepCopy(true);
+
+$copy = $copier->copy($var);
+```
+
+You may want to roll your own deep copy function:
+
+```php
+namespace Acme;
+
+use DeepCopy\DeepCopy;
+
+function deep_copy($var)
+{
+ static $copier = null;
+
+ if (null === $copier) {
+ $copier = new DeepCopy(true);
+ }
+
+ return $copier->copy($var);
+}
+```
+
+
+## Going further
+
+You can add filters to customize the copy process.
+
+The method to add a filter is `DeepCopy\DeepCopy::addFilter($filter, $matcher)`,
+with `$filter` implementing `DeepCopy\Filter\Filter`
+and `$matcher` implementing `DeepCopy\Matcher\Matcher`.
+
+We provide some generic filters and matchers.
+
+
+### Matchers
+
+ - `DeepCopy\Matcher` applies on a object attribute.
+ - `DeepCopy\TypeMatcher` applies on any element found in graph, including array elements.
+
+
+#### Property name
+
+The `PropertyNameMatcher` will match a property by its name:
+
+```php
+use DeepCopy\Matcher\PropertyNameMatcher;
+
+// Will apply a filter to any property of any objects named "id"
+$matcher = new PropertyNameMatcher('id');
+```
+
+
+#### Specific property
+
+The `PropertyMatcher` will match a specific property of a specific class:
+
+```php
+use DeepCopy\Matcher\PropertyMatcher;
+
+// Will apply a filter to the property "id" of any objects of the class "MyClass"
+$matcher = new PropertyMatcher('MyClass', 'id');
+```
+
+
+#### Type
+
+The `TypeMatcher` will match any element by its type (instance of a class or any value that could be parameter of
+[gettype()](http://php.net/manual/en/function.gettype.php) function):
+
+```php
+use DeepCopy\TypeMatcher\TypeMatcher;
+
+// Will apply a filter to any object that is an instance of Doctrine\Common\Collections\Collection
+$matcher = new TypeMatcher('Doctrine\Common\Collections\Collection');
+```
+
+
+### Filters
+
+- `DeepCopy\Filter` applies a transformation to the object attribute matched by `DeepCopy\Matcher`
+- `DeepCopy\TypeFilter` applies a transformation to any element matched by `DeepCopy\TypeMatcher`
+
+
+#### `SetNullFilter` (filter)
+
+Let's say for example that you are copying a database record (or a Doctrine entity), so you want the copy not to have
+any ID:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\SetNullFilter;
+use DeepCopy\Matcher\PropertyNameMatcher;
+
+$object = MyClass::load(123);
+echo $object->id; // 123
+
+$copier = new DeepCopy();
+$copier->addFilter(new SetNullFilter(), new PropertyNameMatcher('id'));
+
+$copy = $copier->copy($object);
+
+echo $copy->id; // null
+```
+
+
+#### `KeepFilter` (filter)
+
+If you want a property to remain untouched (for example, an association to an object):
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\KeepFilter;
+use DeepCopy\Matcher\PropertyMatcher;
+
+$copier = new DeepCopy();
+$copier->addFilter(new KeepFilter(), new PropertyMatcher('MyClass', 'category'));
+
+$copy = $copier->copy($object);
+// $copy->category has not been touched
+```
+
+
+#### `DoctrineCollectionFilter` (filter)
+
+If you use Doctrine and want to copy an entity, you will need to use the `DoctrineCollectionFilter`:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter;
+use DeepCopy\Matcher\PropertyTypeMatcher;
+
+$copier = new DeepCopy();
+$copier->addFilter(new DoctrineCollectionFilter(), new PropertyTypeMatcher('Doctrine\Common\Collections\Collection'));
+
+$copy = $copier->copy($object);
+```
+
+
+#### `DoctrineEmptyCollectionFilter` (filter)
+
+If you use Doctrine and want to copy an entity who contains a `Collection` that you want to be reset, you can use the
+`DoctrineEmptyCollectionFilter`
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter;
+use DeepCopy\Matcher\PropertyMatcher;
+
+$copier = new DeepCopy();
+$copier->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher('MyClass', 'myProperty'));
+
+$copy = $copier->copy($object);
+
+// $copy->myProperty will return an empty collection
+```
+
+
+#### `DoctrineProxyFilter` (filter)
+
+If you use Doctrine and use cloning on lazy loaded entities, you might encounter errors mentioning missing fields on a
+Doctrine proxy class (...\\\_\_CG\_\_\Proxy).
+You can use the `DoctrineProxyFilter` to load the actual entity behind the Doctrine proxy class.
+**Make sure, though, to put this as one of your very first filters in the filter chain so that the entity is loaded
+before other filters are applied!**
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\Doctrine\DoctrineProxyFilter;
+use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher;
+
+$copier = new DeepCopy();
+$copier->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher());
+
+$copy = $copier->copy($object);
+
+// $copy should now contain a clone of all entities, including those that were not yet fully loaded.
+```
+
+
+#### `ReplaceFilter` (type filter)
+
+1. If you want to replace the value of a property:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\ReplaceFilter;
+use DeepCopy\Matcher\PropertyMatcher;
+
+$copier = new DeepCopy();
+$callback = function ($currentValue) {
+ return $currentValue . ' (copy)'
+};
+$copier->addFilter(new ReplaceFilter($callback), new PropertyMatcher('MyClass', 'title'));
+
+$copy = $copier->copy($object);
+
+// $copy->title will contain the data returned by the callback, e.g. 'The title (copy)'
+```
+
+2. If you want to replace whole element:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\TypeFilter\ReplaceFilter;
+use DeepCopy\TypeMatcher\TypeMatcher;
+
+$copier = new DeepCopy();
+$callback = function (MyClass $myClass) {
+ return get_class($myClass);
+};
+$copier->addTypeFilter(new ReplaceFilter($callback), new TypeMatcher('MyClass'));
+
+$copy = $copier->copy([new MyClass, 'some string', new MyClass]);
+
+// $copy will contain ['MyClass', 'some string', 'MyClass']
+```
+
+
+The `$callback` parameter of the `ReplaceFilter` constructor accepts any PHP callable.
+
+
+#### `ShallowCopyFilter` (type filter)
+
+Stop *DeepCopy* from recursively copying element, using standard `clone` instead:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\TypeFilter\ShallowCopyFilter;
+use DeepCopy\TypeMatcher\TypeMatcher;
+use Mockery as m;
+
+$this->deepCopy = new DeepCopy();
+$this->deepCopy->addTypeFilter(
+ new ShallowCopyFilter,
+ new TypeMatcher(m\MockInterface::class)
+);
+
+$myServiceWithMocks = new MyService(m::mock(MyDependency1::class), m::mock(MyDependency2::class));
+// All mocks will be just cloned, not deep copied
+```
+
+
+## Edge cases
+
+The following structures cannot be deep-copied with PHP Reflection. As a result they are shallow cloned and filters are
+not applied. There is two ways for you to handle them:
+
+- Implement your own `__clone()` method
+- Use a filter with a type matcher
+
+
+## Contributing
+
+DeepCopy is distributed under the MIT license.
+
+
+### Tests
+
+Running the tests is simple:
+
+```php
+vendor/bin/phpunit
+```
diff --git a/vendor/myclabs/deep-copy/composer.json b/vendor/myclabs/deep-copy/composer.json
new file mode 100644
index 0000000..4108a23
--- /dev/null
+++ b/vendor/myclabs/deep-copy/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "myclabs/deep-copy",
+ "type": "library",
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": ["clone", "copy", "duplicate", "object", "object graph"],
+ "license": "MIT",
+
+ "autoload": {
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ },
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ]
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "DeepCopy\\": "fixtures/",
+ "DeepCopyTest\\": "tests/DeepCopyTest/"
+ }
+ },
+
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.0",
+ "doctrine/common": "^2.6",
+ "phpunit/phpunit": "^7.1"
+ },
+ "replace": {
+ "myclabs/deep-copy": "self.version"
+ },
+
+ "config": {
+ "sort-packages": true
+ }
+}
diff --git a/vendor/myclabs/deep-copy/doc/clone.png b/vendor/myclabs/deep-copy/doc/clone.png
new file mode 100644
index 0000000..376afd4
Binary files /dev/null and b/vendor/myclabs/deep-copy/doc/clone.png differ
diff --git a/vendor/myclabs/deep-copy/doc/deep-clone.png b/vendor/myclabs/deep-copy/doc/deep-clone.png
new file mode 100644
index 0000000..2b37a6d
Binary files /dev/null and b/vendor/myclabs/deep-copy/doc/deep-clone.png differ
diff --git a/vendor/myclabs/deep-copy/doc/deep-copy.png b/vendor/myclabs/deep-copy/doc/deep-copy.png
new file mode 100644
index 0000000..68c508a
Binary files /dev/null and b/vendor/myclabs/deep-copy/doc/deep-copy.png differ
diff --git a/vendor/myclabs/deep-copy/doc/graph.png b/vendor/myclabs/deep-copy/doc/graph.png
new file mode 100644
index 0000000..4d5c942
Binary files /dev/null and b/vendor/myclabs/deep-copy/doc/graph.png differ
diff --git a/vendor/myclabs/deep-copy/fixtures/f001/A.php b/vendor/myclabs/deep-copy/fixtures/f001/A.php
new file mode 100644
index 0000000..648d5df
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f001/A.php
@@ -0,0 +1,20 @@
+aProp;
+ }
+
+ public function setAProp($prop)
+ {
+ $this->aProp = $prop;
+
+ return $this;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f001/B.php b/vendor/myclabs/deep-copy/fixtures/f001/B.php
new file mode 100644
index 0000000..462bb44
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f001/B.php
@@ -0,0 +1,20 @@
+bProp;
+ }
+
+ public function setBProp($prop)
+ {
+ $this->bProp = $prop;
+
+ return $this;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f002/A.php b/vendor/myclabs/deep-copy/fixtures/f002/A.php
new file mode 100644
index 0000000..d9aa5c3
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f002/A.php
@@ -0,0 +1,33 @@
+prop1;
+ }
+
+ public function setProp1($prop)
+ {
+ $this->prop1 = $prop;
+
+ return $this;
+ }
+
+ public function getProp2()
+ {
+ return $this->prop2;
+ }
+
+ public function setProp2($prop)
+ {
+ $this->prop2 = $prop;
+
+ return $this;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f003/Foo.php b/vendor/myclabs/deep-copy/fixtures/f003/Foo.php
new file mode 100644
index 0000000..9cd7622
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f003/Foo.php
@@ -0,0 +1,26 @@
+name = $name;
+ }
+
+ public function getProp()
+ {
+ return $this->prop;
+ }
+
+ public function setProp($prop)
+ {
+ $this->prop = $prop;
+
+ return $this;
+ }
+}
\ No newline at end of file
diff --git a/vendor/myclabs/deep-copy/fixtures/f004/UnclonableItem.php b/vendor/myclabs/deep-copy/fixtures/f004/UnclonableItem.php
new file mode 100644
index 0000000..82c6c67
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f004/UnclonableItem.php
@@ -0,0 +1,13 @@
+cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f006/A.php b/vendor/myclabs/deep-copy/fixtures/f006/A.php
new file mode 100644
index 0000000..d9efb11
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f006/A.php
@@ -0,0 +1,26 @@
+aProp;
+ }
+
+ public function setAProp($prop)
+ {
+ $this->aProp = $prop;
+
+ return $this;
+ }
+
+ public function __clone()
+ {
+ $this->cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f006/B.php b/vendor/myclabs/deep-copy/fixtures/f006/B.php
new file mode 100644
index 0000000..1f80b3d
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f006/B.php
@@ -0,0 +1,26 @@
+bProp;
+ }
+
+ public function setBProp($prop)
+ {
+ $this->bProp = $prop;
+
+ return $this;
+ }
+
+ public function __clone()
+ {
+ $this->cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f007/FooDateInterval.php b/vendor/myclabs/deep-copy/fixtures/f007/FooDateInterval.php
new file mode 100644
index 0000000..e16bc6a
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f007/FooDateInterval.php
@@ -0,0 +1,15 @@
+cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f007/FooDateTimeZone.php b/vendor/myclabs/deep-copy/fixtures/f007/FooDateTimeZone.php
new file mode 100644
index 0000000..6f4e61f
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f007/FooDateTimeZone.php
@@ -0,0 +1,15 @@
+cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f008/A.php b/vendor/myclabs/deep-copy/fixtures/f008/A.php
new file mode 100644
index 0000000..88471d0
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f008/A.php
@@ -0,0 +1,18 @@
+foo = $foo;
+ }
+
+ public function getFoo()
+ {
+ return $this->foo;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f008/B.php b/vendor/myclabs/deep-copy/fixtures/f008/B.php
new file mode 100644
index 0000000..6053092
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f008/B.php
@@ -0,0 +1,7 @@
+ Filter, 'matcher' => Matcher] pairs.
+ */
+ private $filters = [];
+
+ /**
+ * Type Filters to apply.
+ *
+ * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
+ */
+ private $typeFilters = [];
+
+ /**
+ * @var bool
+ */
+ private $skipUncloneable = false;
+
+ /**
+ * @var bool
+ */
+ private $useCloneMethod;
+
+ /**
+ * @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used
+ * instead of the regular deep cloning.
+ */
+ public function __construct($useCloneMethod = false)
+ {
+ $this->useCloneMethod = $useCloneMethod;
+
+ $this->addTypeFilter(new DateIntervalFilter(), new TypeMatcher(DateInterval::class));
+ $this->addTypeFilter(new SplDoublyLinkedListFilter($this), new TypeMatcher(SplDoublyLinkedList::class));
+ }
+
+ /**
+ * If enabled, will not throw an exception when coming across an uncloneable property.
+ *
+ * @param $skipUncloneable
+ *
+ * @return $this
+ */
+ public function skipUncloneable($skipUncloneable = true)
+ {
+ $this->skipUncloneable = $skipUncloneable;
+
+ return $this;
+ }
+
+ /**
+ * Deep copies the given object.
+ *
+ * @param mixed $object
+ *
+ * @return mixed
+ */
+ public function copy($object)
+ {
+ $this->hashMap = [];
+
+ return $this->recursiveCopy($object);
+ }
+
+ public function addFilter(Filter $filter, Matcher $matcher)
+ {
+ $this->filters[] = [
+ 'matcher' => $matcher,
+ 'filter' => $filter,
+ ];
+ }
+
+ public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher)
+ {
+ $this->typeFilters[] = [
+ 'matcher' => $matcher,
+ 'filter' => $filter,
+ ];
+ }
+
+ private function recursiveCopy($var)
+ {
+ // Matches Type Filter
+ if ($filter = $this->getFirstMatchedTypeFilter($this->typeFilters, $var)) {
+ return $filter->apply($var);
+ }
+
+ // Resource
+ if (is_resource($var)) {
+ return $var;
+ }
+
+ // Array
+ if (is_array($var)) {
+ return $this->copyArray($var);
+ }
+
+ // Scalar
+ if (! is_object($var)) {
+ return $var;
+ }
+
+ // Object
+ return $this->copyObject($var);
+ }
+
+ /**
+ * Copy an array
+ * @param array $array
+ * @return array
+ */
+ private function copyArray(array $array)
+ {
+ foreach ($array as $key => $value) {
+ $array[$key] = $this->recursiveCopy($value);
+ }
+
+ return $array;
+ }
+
+ /**
+ * Copies an object.
+ *
+ * @param object $object
+ *
+ * @throws CloneException
+ *
+ * @return object
+ */
+ private function copyObject($object)
+ {
+ $objectHash = spl_object_hash($object);
+
+ if (isset($this->hashMap[$objectHash])) {
+ return $this->hashMap[$objectHash];
+ }
+
+ $reflectedObject = new ReflectionObject($object);
+ $isCloneable = $reflectedObject->isCloneable();
+
+ if (false === $isCloneable) {
+ if ($this->skipUncloneable) {
+ $this->hashMap[$objectHash] = $object;
+
+ return $object;
+ }
+
+ throw new CloneException(
+ sprintf(
+ 'The class "%s" is not cloneable.',
+ $reflectedObject->getName()
+ )
+ );
+ }
+
+ $newObject = clone $object;
+ $this->hashMap[$objectHash] = $newObject;
+
+ if ($this->useCloneMethod && $reflectedObject->hasMethod('__clone')) {
+ return $newObject;
+ }
+
+ if ($newObject instanceof DateTimeInterface || $newObject instanceof DateTimeZone) {
+ return $newObject;
+ }
+
+ foreach (ReflectionHelper::getProperties($reflectedObject) as $property) {
+ $this->copyObjectProperty($newObject, $property);
+ }
+
+ return $newObject;
+ }
+
+ private function copyObjectProperty($object, ReflectionProperty $property)
+ {
+ // Ignore static properties
+ if ($property->isStatic()) {
+ return;
+ }
+
+ // Apply the filters
+ foreach ($this->filters as $item) {
+ /** @var Matcher $matcher */
+ $matcher = $item['matcher'];
+ /** @var Filter $filter */
+ $filter = $item['filter'];
+
+ if ($matcher->matches($object, $property->getName())) {
+ $filter->apply(
+ $object,
+ $property->getName(),
+ function ($object) {
+ return $this->recursiveCopy($object);
+ }
+ );
+
+ // If a filter matches, we stop processing this property
+ return;
+ }
+ }
+
+ $property->setAccessible(true);
+ $propertyValue = $property->getValue($object);
+
+ // Copy the property
+ $property->setValue($object, $this->recursiveCopy($propertyValue));
+ }
+
+ /**
+ * Returns first filter that matches variable, `null` if no such filter found.
+ *
+ * @param array $filterRecords Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and
+ * 'matcher' with value of type {@see TypeMatcher}
+ * @param mixed $var
+ *
+ * @return TypeFilter|null
+ */
+ private function getFirstMatchedTypeFilter(array $filterRecords, $var)
+ {
+ $matched = $this->first(
+ $filterRecords,
+ function (array $record) use ($var) {
+ /* @var TypeMatcher $matcher */
+ $matcher = $record['matcher'];
+
+ return $matcher->matches($var);
+ }
+ );
+
+ return isset($matched) ? $matched['filter'] : null;
+ }
+
+ /**
+ * Returns first element that matches predicate, `null` if no such element found.
+ *
+ * @param array $elements Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
+ * @param callable $predicate Predicate arguments are: element.
+ *
+ * @return array|null Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and 'matcher'
+ * with value of type {@see TypeMatcher} or `null`.
+ */
+ private function first(array $elements, callable $predicate)
+ {
+ foreach ($elements as $element) {
+ if (call_user_func($predicate, $element)) {
+ return $element;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php b/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php
new file mode 100644
index 0000000..c046706
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php
@@ -0,0 +1,9 @@
+setAccessible(true);
+ $oldCollection = $reflectionProperty->getValue($object);
+
+ $newCollection = $oldCollection->map(
+ function ($item) use ($objectCopier) {
+ return $objectCopier($item);
+ }
+ );
+
+ $reflectionProperty->setValue($object, $newCollection);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php
new file mode 100644
index 0000000..7b33fd5
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php
@@ -0,0 +1,28 @@
+setAccessible(true);
+
+ $reflectionProperty->setValue($object, new ArrayCollection());
+ }
+}
\ No newline at end of file
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php
new file mode 100644
index 0000000..8bee8f7
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php
@@ -0,0 +1,22 @@
+__load();
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php
new file mode 100644
index 0000000..85ba18c
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php
@@ -0,0 +1,18 @@
+callback = $callable;
+ }
+
+ /**
+ * Replaces the object property by the result of the callback called with the object property.
+ *
+ * {@inheritdoc}
+ */
+ public function apply($object, $property, $objectCopier)
+ {
+ $reflectionProperty = ReflectionHelper::getProperty($object, $property);
+ $reflectionProperty->setAccessible(true);
+
+ $value = call_user_func($this->callback, $reflectionProperty->getValue($object));
+
+ $reflectionProperty->setValue($object, $value);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php
new file mode 100644
index 0000000..bea86b8
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php
@@ -0,0 +1,24 @@
+setAccessible(true);
+ $reflectionProperty->setValue($object, null);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php
new file mode 100644
index 0000000..ec8856f
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php
@@ -0,0 +1,22 @@
+class = $class;
+ $this->property = $property;
+ }
+
+ /**
+ * Matches a specific property of a specific class.
+ *
+ * {@inheritdoc}
+ */
+ public function matches($object, $property)
+ {
+ return ($object instanceof $this->class) && $property == $this->property;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php
new file mode 100644
index 0000000..c8ec0d2
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php
@@ -0,0 +1,32 @@
+property = $property;
+ }
+
+ /**
+ * Matches a property by its name.
+ *
+ * {@inheritdoc}
+ */
+ public function matches($object, $property)
+ {
+ return $property == $this->property;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php
new file mode 100644
index 0000000..a6b0c0b
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php
@@ -0,0 +1,46 @@
+propertyType = $propertyType;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function matches($object, $property)
+ {
+ try {
+ $reflectionProperty = ReflectionHelper::getProperty($object, $property);
+ } catch (ReflectionException $exception) {
+ return false;
+ }
+
+ $reflectionProperty->setAccessible(true);
+
+ return $reflectionProperty->getValue($object) instanceof $this->propertyType;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php b/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php
new file mode 100644
index 0000000..742410c
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php
@@ -0,0 +1,78 @@
+getProperties() does not return private properties from ancestor classes.
+ *
+ * @author muratyaman@gmail.com
+ * @see http://php.net/manual/en/reflectionclass.getproperties.php
+ *
+ * @param ReflectionClass $ref
+ *
+ * @return ReflectionProperty[]
+ */
+ public static function getProperties(ReflectionClass $ref)
+ {
+ $props = $ref->getProperties();
+ $propsArr = array();
+
+ foreach ($props as $prop) {
+ $propertyName = $prop->getName();
+ $propsArr[$propertyName] = $prop;
+ }
+
+ if ($parentClass = $ref->getParentClass()) {
+ $parentPropsArr = self::getProperties($parentClass);
+ foreach ($propsArr as $key => $property) {
+ $parentPropsArr[$key] = $property;
+ }
+
+ return $parentPropsArr;
+ }
+
+ return $propsArr;
+ }
+
+ /**
+ * Retrieves property by name from object and all its ancestors.
+ *
+ * @param object|string $object
+ * @param string $name
+ *
+ * @throws PropertyException
+ * @throws ReflectionException
+ *
+ * @return ReflectionProperty
+ */
+ public static function getProperty($object, $name)
+ {
+ $reflection = is_object($object) ? new ReflectionObject($object) : new ReflectionClass($object);
+
+ if ($reflection->hasProperty($name)) {
+ return $reflection->getProperty($name);
+ }
+
+ if ($parentClass = $reflection->getParentClass()) {
+ return self::getProperty($parentClass->getName(), $name);
+ }
+
+ throw new PropertyException(
+ sprintf(
+ 'The class "%s" doesn\'t have a property with the given name: "%s".',
+ is_object($object) ? get_class($object) : $object,
+ $name
+ )
+ );
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php
new file mode 100644
index 0000000..becd1cf
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php
@@ -0,0 +1,33 @@
+ $propertyValue) {
+ $copy->{$propertyName} = $propertyValue;
+ }
+
+ return $copy;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php
new file mode 100644
index 0000000..164f8b8
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php
@@ -0,0 +1,30 @@
+callback = $callable;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function apply($element)
+ {
+ return call_user_func($this->callback, $element);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php
new file mode 100644
index 0000000..a5fbd7a
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php
@@ -0,0 +1,17 @@
+copier = $copier;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function apply($element)
+ {
+ $newElement = clone $element;
+
+ $copy = $this->createCopyClosure();
+
+ return $copy($newElement);
+ }
+
+ private function createCopyClosure()
+ {
+ $copier = $this->copier;
+
+ $copy = function (SplDoublyLinkedList $list) use ($copier) {
+ // Replace each element in the list with a deep copy of itself
+ for ($i = 1; $i <= $list->count(); $i++) {
+ $copy = $copier->recursiveCopy($list->shift());
+
+ $list->push($copy);
+ }
+
+ return $list;
+ };
+
+ return Closure::bind($copy, null, DeepCopy::class);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php
new file mode 100644
index 0000000..5785a7d
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php
@@ -0,0 +1,13 @@
+type = $type;
+ }
+
+ /**
+ * @param mixed $element
+ *
+ * @return boolean
+ */
+ public function matches($element)
+ {
+ return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php b/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php
new file mode 100644
index 0000000..55dcc92
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php
@@ -0,0 +1,20 @@
+copy($value);
+ }
+}
diff --git a/vendor/phar-io/manifest/.gitignore b/vendor/phar-io/manifest/.gitignore
new file mode 100644
index 0000000..374459d
--- /dev/null
+++ b/vendor/phar-io/manifest/.gitignore
@@ -0,0 +1,7 @@
+/.idea
+/.php_cs.cache
+/src/autoload.php
+/tools
+/vendor
+
+/build
diff --git a/vendor/phar-io/manifest/.php_cs b/vendor/phar-io/manifest/.php_cs
new file mode 100644
index 0000000..159d6a3
--- /dev/null
+++ b/vendor/phar-io/manifest/.php_cs
@@ -0,0 +1,67 @@
+files()
+ ->in('src')
+ ->in('tests')
+ ->name('*.php');
+
+return Symfony\CS\Config\Config::create()
+ ->setUsingCache(true)
+ ->level(\Symfony\CS\FixerInterface::NONE_LEVEL)
+ ->fixers(
+ array(
+ 'align_double_arrow',
+ 'align_equals',
+ 'concat_with_spaces',
+ 'duplicate_semicolon',
+ 'elseif',
+ 'empty_return',
+ 'encoding',
+ 'eof_ending',
+ 'extra_empty_lines',
+ 'function_call_space',
+ 'function_declaration',
+ 'indentation',
+ 'join_function',
+ 'line_after_namespace',
+ 'linefeed',
+ 'list_commas',
+ 'lowercase_constants',
+ 'lowercase_keywords',
+ 'method_argument_space',
+ 'multiple_use',
+ 'namespace_no_leading_whitespace',
+ 'no_blank_lines_after_class_opening',
+ 'no_empty_lines_after_phpdocs',
+ 'parenthesis',
+ 'php_closing_tag',
+ 'phpdoc_indent',
+ 'phpdoc_no_access',
+ 'phpdoc_no_empty_return',
+ 'phpdoc_no_package',
+ 'phpdoc_params',
+ 'phpdoc_scalar',
+ 'phpdoc_separation',
+ 'phpdoc_to_comment',
+ 'phpdoc_trim',
+ 'phpdoc_types',
+ 'phpdoc_var_without_name',
+ 'remove_lines_between_uses',
+ 'return',
+ 'self_accessor',
+ 'short_array_syntax',
+ 'short_tag',
+ 'single_line_after_imports',
+ 'single_quote',
+ 'spaces_before_semicolon',
+ 'spaces_cast',
+ 'ternary_spaces',
+ 'trailing_spaces',
+ 'trim_array_spaces',
+ 'unused_use',
+ 'visibility',
+ 'whitespacy_lines'
+ )
+ )
+ ->finder($finder);
+
diff --git a/vendor/phar-io/manifest/.travis.yml b/vendor/phar-io/manifest/.travis.yml
new file mode 100644
index 0000000..b4be10f
--- /dev/null
+++ b/vendor/phar-io/manifest/.travis.yml
@@ -0,0 +1,33 @@
+os:
+- linux
+
+language: php
+
+before_install:
+ - wget https://phar.io/releases/phive.phar
+ - wget https://phar.io/releases/phive.phar.asc
+ - gpg --keyserver hkps.pool.sks-keyservers.net --recv-keys 0x9B2D5D79
+ - gpg --verify phive.phar.asc phive.phar
+ - chmod +x phive.phar
+ - sudo mv phive.phar /usr/bin/phive
+
+install:
+ - ant setup
+
+script: ./tools/phpunit
+
+php:
+ - 5.6
+ - 7.0
+ - 7.1
+ - 7.0snapshot
+ - 7.1snapshot
+ - master
+
+matrix:
+ allow_failures:
+ - php: master
+ fast_finish: true
+
+notifications:
+ email: false
diff --git a/vendor/phar-io/manifest/LICENSE b/vendor/phar-io/manifest/LICENSE
new file mode 100644
index 0000000..96051b1
--- /dev/null
+++ b/vendor/phar-io/manifest/LICENSE
@@ -0,0 +1,31 @@
+manifest
+
+Copyright (c) 2016 Arne Blankerts , Sebastian Heuer , Sebastian Bergmann , and contributors
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of Arne Blankerts nor the names of contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/vendor/phar-io/manifest/README.md b/vendor/phar-io/manifest/README.md
new file mode 100644
index 0000000..e6d0b05
--- /dev/null
+++ b/vendor/phar-io/manifest/README.md
@@ -0,0 +1,30 @@
+# Manifest
+
+Component for reading [phar.io](https://phar.io/) manifest information from a [PHP Archive (PHAR)](http://php.net/phar).
+
+[![Build Status](https://travis-ci.org/phar-io/manifest.svg?branch=master)](https://travis-ci.org/phar-io/manifest)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/phar-io/manifest/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/phar-io/manifest/?branch=master)
+[![SensioLabsInsight](https://insight.sensiolabs.com/projects/d8cc6035-69ad-477d-bd1a-ccc605480fd7/mini.png)](https://insight.sensiolabs.com/projects/d8cc6035-69ad-477d-bd1a-ccc605480fd7)
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+ composer require phar-io/manifest
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+ composer require --dev phar-io/manifest
+
+## Usage
+
+```php
+use PharIo\Manifest\ManifestLoader;
+use PharIo\Manifest\ManifestSerializer;
+
+$manifest = ManifestLoader::fromFile('manifest.xml');
+
+var_dump($manifest);
+
+echo (new ManifestSerializer)->serializeToString($manifest);
+```
diff --git a/vendor/phar-io/manifest/build.xml b/vendor/phar-io/manifest/build.xml
new file mode 100644
index 0000000..fc6eb1a
--- /dev/null
+++ b/vendor/phar-io/manifest/build.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/manifest/composer.json b/vendor/phar-io/manifest/composer.json
new file mode 100644
index 0000000..cfaa7fa
--- /dev/null
+++ b/vendor/phar-io/manifest/composer.json
@@ -0,0 +1,42 @@
+{
+ "name": "phar-io/manifest",
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "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"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/phar-io/manifest/issues"
+ },
+ "require": {
+ "php": "^5.6 || ^7.0",
+ "ext-dom": "*",
+ "ext-phar": "*",
+ "phar-io/version": "^2.0"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
+
diff --git a/vendor/phar-io/manifest/composer.lock b/vendor/phar-io/manifest/composer.lock
new file mode 100644
index 0000000..d876819
--- /dev/null
+++ b/vendor/phar-io/manifest/composer.lock
@@ -0,0 +1,69 @@
+{
+ "_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#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "f00846dde236d314a19d00d268d737dd",
+ "packages": [
+ {
+ "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"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": "^5.6 || ^7.0",
+ "ext-dom": "*",
+ "ext-phar": "*"
+ },
+ "platform-dev": []
+}
diff --git a/vendor/phar-io/manifest/examples/example-01.php b/vendor/phar-io/manifest/examples/example-01.php
new file mode 100644
index 0000000..345c407
--- /dev/null
+++ b/vendor/phar-io/manifest/examples/example-01.php
@@ -0,0 +1,23 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PharIo\Manifest\ManifestLoader;
+use PharIo\Manifest\ManifestSerializer;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+$manifest = ManifestLoader::fromFile(__DIR__ . '/../tests/_fixture/phpunit-5.6.5.xml');
+
+echo sprintf(
+ "Manifest for %s (%s):\n\n",
+ $manifest->getName(),
+ $manifest->getVersion()->getVersionString()
+);
+echo (new ManifestSerializer)->serializeToString($manifest);
diff --git a/vendor/phar-io/manifest/phive.xml b/vendor/phar-io/manifest/phive.xml
new file mode 100644
index 0000000..69f2f91
--- /dev/null
+++ b/vendor/phar-io/manifest/phive.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/vendor/phar-io/manifest/phpunit.xml b/vendor/phar-io/manifest/phpunit.xml
new file mode 100644
index 0000000..2d7708e
--- /dev/null
+++ b/vendor/phar-io/manifest/phpunit.xml
@@ -0,0 +1,20 @@
+
+
+
+ tests
+
+
+
+
+ src
+
+
+
diff --git a/vendor/phar-io/manifest/src/ManifestDocumentMapper.php b/vendor/phar-io/manifest/src/ManifestDocumentMapper.php
new file mode 100644
index 0000000..d41e4f9
--- /dev/null
+++ b/vendor/phar-io/manifest/src/ManifestDocumentMapper.php
@@ -0,0 +1,193 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\Version;
+use PharIo\Version\Exception as VersionException;
+use PharIo\Version\VersionConstraintParser;
+
+class ManifestDocumentMapper {
+ /**
+ * @param ManifestDocument $document
+ *
+ * @returns Manifest
+ *
+ * @throws ManifestDocumentMapperException
+ */
+ public function map(ManifestDocument $document) {
+ try {
+ $contains = $document->getContainsElement();
+ $type = $this->mapType($contains);
+ $copyright = $this->mapCopyright($document->getCopyrightElement());
+ $requirements = $this->mapRequirements($document->getRequiresElement());
+ $bundledComponents = $this->mapBundledComponents($document);
+
+ return new Manifest(
+ new ApplicationName($contains->getName()),
+ new Version($contains->getVersion()),
+ $type,
+ $copyright,
+ $requirements,
+ $bundledComponents
+ );
+ } catch (VersionException $e) {
+ throw new ManifestDocumentMapperException($e->getMessage(), $e->getCode(), $e);
+ } catch (Exception $e) {
+ throw new ManifestDocumentMapperException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * @param ContainsElement $contains
+ *
+ * @return Type
+ *
+ * @throws ManifestDocumentMapperException
+ */
+ private function mapType(ContainsElement $contains) {
+ switch ($contains->getType()) {
+ case 'application':
+ return Type::application();
+ case 'library':
+ return Type::library();
+ case 'extension':
+ return $this->mapExtension($contains->getExtensionElement());
+ }
+
+ throw new ManifestDocumentMapperException(
+ sprintf('Unsupported type %s', $contains->getType())
+ );
+ }
+
+ /**
+ * @param CopyrightElement $copyright
+ *
+ * @return CopyrightInformation
+ *
+ * @throws InvalidUrlException
+ * @throws InvalidEmailException
+ */
+ private function mapCopyright(CopyrightElement $copyright) {
+ $authors = new AuthorCollection();
+
+ foreach($copyright->getAuthorElements() as $authorElement) {
+ $authors->add(
+ new Author(
+ $authorElement->getName(),
+ new Email($authorElement->getEmail())
+ )
+ );
+ }
+
+ $licenseElement = $copyright->getLicenseElement();
+ $license = new License(
+ $licenseElement->getType(),
+ new Url($licenseElement->getUrl())
+ );
+
+ return new CopyrightInformation(
+ $authors,
+ $license
+ );
+ }
+
+ /**
+ * @param RequiresElement $requires
+ *
+ * @return RequirementCollection
+ *
+ * @throws ManifestDocumentMapperException
+ */
+ private function mapRequirements(RequiresElement $requires) {
+ $collection = new RequirementCollection();
+ $phpElement = $requires->getPHPElement();
+ $parser = new VersionConstraintParser;
+
+ try {
+ $versionConstraint = $parser->parse($phpElement->getVersion());
+ } catch (VersionException $e) {
+ throw new ManifestDocumentMapperException(
+ sprintf('Unsupported version constraint - %s', $e->getMessage()),
+ $e->getCode(),
+ $e
+ );
+ }
+
+ $collection->add(
+ new PhpVersionRequirement(
+ $versionConstraint
+ )
+ );
+
+ if (!$phpElement->hasExtElements()) {
+ return $collection;
+ }
+
+ foreach($phpElement->getExtElements() as $extElement) {
+ $collection->add(
+ new PhpExtensionRequirement($extElement->getName())
+ );
+ }
+
+ return $collection;
+ }
+
+ /**
+ * @param ManifestDocument $document
+ *
+ * @return BundledComponentCollection
+ */
+ private function mapBundledComponents(ManifestDocument $document) {
+ $collection = new BundledComponentCollection();
+
+ if (!$document->hasBundlesElement()) {
+ return $collection;
+ }
+
+ foreach($document->getBundlesElement()->getComponentElements() as $componentElement) {
+ $collection->add(
+ new BundledComponent(
+ $componentElement->getName(),
+ new Version(
+ $componentElement->getVersion()
+ )
+ )
+ );
+ }
+
+ return $collection;
+ }
+
+ /**
+ * @param ExtensionElement $extension
+ *
+ * @return Extension
+ *
+ * @throws ManifestDocumentMapperException
+ */
+ private function mapExtension(ExtensionElement $extension) {
+ try {
+ $parser = new VersionConstraintParser;
+ $versionConstraint = $parser->parse($extension->getCompatible());
+
+ return Type::extension(
+ new ApplicationName($extension->getFor()),
+ $versionConstraint
+ );
+ } catch (VersionException $e) {
+ throw new ManifestDocumentMapperException(
+ sprintf('Unsupported version constraint - %s', $e->getMessage()),
+ $e->getCode(),
+ $e
+ );
+ }
+ }
+}
diff --git a/vendor/phar-io/manifest/src/ManifestLoader.php b/vendor/phar-io/manifest/src/ManifestLoader.php
new file mode 100644
index 0000000..81c5c90
--- /dev/null
+++ b/vendor/phar-io/manifest/src/ManifestLoader.php
@@ -0,0 +1,66 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class ManifestLoader {
+ /**
+ * @param string $filename
+ *
+ * @return Manifest
+ *
+ * @throws ManifestLoaderException
+ */
+ public static function fromFile($filename) {
+ try {
+ return (new ManifestDocumentMapper())->map(
+ ManifestDocument::fromFile($filename)
+ );
+ } catch (Exception $e) {
+ throw new ManifestLoaderException(
+ sprintf('Loading %s failed.', $filename),
+ $e->getCode(),
+ $e
+ );
+ }
+ }
+
+ /**
+ * @param string $filename
+ *
+ * @return Manifest
+ *
+ * @throws ManifestLoaderException
+ */
+ public static function fromPhar($filename) {
+ return self::fromFile('phar://' . $filename . '/manifest.xml');
+ }
+
+ /**
+ * @param string $manifest
+ *
+ * @return Manifest
+ *
+ * @throws ManifestLoaderException
+ */
+ public static function fromString($manifest) {
+ try {
+ return (new ManifestDocumentMapper())->map(
+ ManifestDocument::fromString($manifest)
+ );
+ } catch (Exception $e) {
+ throw new ManifestLoaderException(
+ 'Processing string failed',
+ $e->getCode(),
+ $e
+ );
+ }
+ }
+}
diff --git a/vendor/phar-io/manifest/src/ManifestSerializer.php b/vendor/phar-io/manifest/src/ManifestSerializer.php
new file mode 100644
index 0000000..4c18ddd
--- /dev/null
+++ b/vendor/phar-io/manifest/src/ManifestSerializer.php
@@ -0,0 +1,163 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\AnyVersionConstraint;
+use PharIo\Version\Version;
+use PharIo\Version\VersionConstraint;
+use XMLWriter;
+
+class ManifestSerializer {
+ /**
+ * @var XMLWriter
+ */
+ private $xmlWriter;
+
+ public function serializeToFile(Manifest $manifest, $filename) {
+ file_put_contents(
+ $filename,
+ $this->serializeToString($manifest)
+ );
+ }
+
+ public function serializeToString(Manifest $manifest) {
+ $this->startDocument();
+
+ $this->addContains($manifest->getName(), $manifest->getVersion(), $manifest->getType());
+ $this->addCopyright($manifest->getCopyrightInformation());
+ $this->addRequirements($manifest->getRequirements());
+ $this->addBundles($manifest->getBundledComponents());
+
+ return $this->finishDocument();
+ }
+
+ private function startDocument() {
+ $xmlWriter = new XMLWriter();
+ $xmlWriter->openMemory();
+ $xmlWriter->setIndent(true);
+ $xmlWriter->setIndentString(str_repeat(' ', 4));
+ $xmlWriter->startDocument('1.0', 'UTF-8');
+ $xmlWriter->startElement('phar');
+ $xmlWriter->writeAttribute('xmlns', 'https://phar.io/xml/manifest/1.0');
+
+ $this->xmlWriter = $xmlWriter;
+ }
+
+ private function finishDocument() {
+ $this->xmlWriter->endElement();
+ $this->xmlWriter->endDocument();
+
+ return $this->xmlWriter->outputMemory();
+ }
+
+ private function addContains($name, Version $version, Type $type) {
+ $this->xmlWriter->startElement('contains');
+ $this->xmlWriter->writeAttribute('name', $name);
+ $this->xmlWriter->writeAttribute('version', $version->getVersionString());
+
+ switch (true) {
+ case $type->isApplication(): {
+ $this->xmlWriter->writeAttribute('type', 'application');
+ break;
+ }
+
+ case $type->isLibrary(): {
+ $this->xmlWriter->writeAttribute('type', 'library');
+ break;
+ }
+
+ case $type->isExtension(): {
+ /* @var $type Extension */
+ $this->xmlWriter->writeAttribute('type', 'extension');
+ $this->addExtension($type->getApplicationName(), $type->getVersionConstraint());
+ break;
+ }
+
+ default: {
+ $this->xmlWriter->writeAttribute('type', 'custom');
+ }
+ }
+
+ $this->xmlWriter->endElement();
+ }
+
+ private function addCopyright(CopyrightInformation $copyrightInformation) {
+ $this->xmlWriter->startElement('copyright');
+
+ foreach($copyrightInformation->getAuthors() as $author) {
+ $this->xmlWriter->startElement('author');
+ $this->xmlWriter->writeAttribute('name', $author->getName());
+ $this->xmlWriter->writeAttribute('email', (string) $author->getEmail());
+ $this->xmlWriter->endElement();
+ }
+
+ $license = $copyrightInformation->getLicense();
+
+ $this->xmlWriter->startElement('license');
+ $this->xmlWriter->writeAttribute('type', $license->getName());
+ $this->xmlWriter->writeAttribute('url', $license->getUrl());
+ $this->xmlWriter->endElement();
+
+ $this->xmlWriter->endElement();
+ }
+
+ private function addRequirements(RequirementCollection $requirementCollection) {
+ $phpRequirement = new AnyVersionConstraint();
+ $extensions = [];
+
+ foreach($requirementCollection as $requirement) {
+ if ($requirement instanceof PhpVersionRequirement) {
+ $phpRequirement = $requirement->getVersionConstraint();
+ continue;
+ }
+
+ if ($requirement instanceof PhpExtensionRequirement) {
+ $extensions[] = (string) $requirement;
+ }
+ }
+
+ $this->xmlWriter->startElement('requires');
+ $this->xmlWriter->startElement('php');
+ $this->xmlWriter->writeAttribute('version', $phpRequirement->asString());
+
+ foreach($extensions as $extension) {
+ $this->xmlWriter->startElement('ext');
+ $this->xmlWriter->writeAttribute('name', $extension);
+ $this->xmlWriter->endElement();
+ }
+
+ $this->xmlWriter->endElement();
+ $this->xmlWriter->endElement();
+ }
+
+ private function addBundles(BundledComponentCollection $bundledComponentCollection) {
+ if (count($bundledComponentCollection) === 0) {
+ return;
+ }
+ $this->xmlWriter->startElement('bundles');
+
+ foreach($bundledComponentCollection as $bundledComponent) {
+ $this->xmlWriter->startElement('component');
+ $this->xmlWriter->writeAttribute('name', $bundledComponent->getName());
+ $this->xmlWriter->writeAttribute('version', $bundledComponent->getVersion()->getVersionString());
+ $this->xmlWriter->endElement();
+ }
+
+ $this->xmlWriter->endElement();
+ }
+
+ private function addExtension($application, VersionConstraint $versionConstraint) {
+ $this->xmlWriter->startElement('extension');
+ $this->xmlWriter->writeAttribute('for', $application);
+ $this->xmlWriter->writeAttribute('compatible', $versionConstraint->asString());
+ $this->xmlWriter->endElement();
+ }
+}
diff --git a/vendor/phar-io/manifest/src/exceptions/Exception.php b/vendor/phar-io/manifest/src/exceptions/Exception.php
new file mode 100644
index 0000000..3ce46f2
--- /dev/null
+++ b/vendor/phar-io/manifest/src/exceptions/Exception.php
@@ -0,0 +1,14 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+interface Exception {
+}
diff --git a/vendor/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php b/vendor/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php
new file mode 100644
index 0000000..a53735a
--- /dev/null
+++ b/vendor/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php
@@ -0,0 +1,16 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class InvalidApplicationNameException extends \InvalidArgumentException implements Exception {
+ const NotAString = 1;
+ const InvalidFormat = 2;
+}
diff --git a/vendor/phar-io/manifest/src/exceptions/InvalidEmailException.php b/vendor/phar-io/manifest/src/exceptions/InvalidEmailException.php
new file mode 100644
index 0000000..854399b
--- /dev/null
+++ b/vendor/phar-io/manifest/src/exceptions/InvalidEmailException.php
@@ -0,0 +1,14 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class InvalidEmailException extends \InvalidArgumentException implements Exception {
+}
diff --git a/vendor/phar-io/manifest/src/exceptions/InvalidUrlException.php b/vendor/phar-io/manifest/src/exceptions/InvalidUrlException.php
new file mode 100644
index 0000000..cdd8323
--- /dev/null
+++ b/vendor/phar-io/manifest/src/exceptions/InvalidUrlException.php
@@ -0,0 +1,14 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class InvalidUrlException extends \InvalidArgumentException implements Exception {
+}
diff --git a/vendor/phar-io/manifest/src/exceptions/ManifestDocumentException.php b/vendor/phar-io/manifest/src/exceptions/ManifestDocumentException.php
new file mode 100644
index 0000000..8b40195
--- /dev/null
+++ b/vendor/phar-io/manifest/src/exceptions/ManifestDocumentException.php
@@ -0,0 +1,6 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class Application extends Type {
+ /**
+ * @return bool
+ */
+ public function isApplication() {
+ return true;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/ApplicationName.php b/vendor/phar-io/manifest/src/values/ApplicationName.php
new file mode 100644
index 0000000..1e71af4
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/ApplicationName.php
@@ -0,0 +1,65 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class ApplicationName {
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * ApplicationName constructor.
+ *
+ * @param string $name
+ *
+ * @throws InvalidApplicationNameException
+ */
+ public function __construct($name) {
+ $this->ensureIsString($name);
+ $this->ensureValidFormat($name);
+ $this->name = $name;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString() {
+ return $this->name;
+ }
+
+ public function isEqual(ApplicationName $name) {
+ return $this->name === $name->name;
+ }
+
+ /**
+ * @param string $name
+ *
+ * @throws InvalidApplicationNameException
+ */
+ private function ensureValidFormat($name) {
+ if (!preg_match('#\w/\w#', $name)) {
+ throw new InvalidApplicationNameException(
+ sprintf('Format of name "%s" is not valid - expected: vendor/packagename', $name),
+ InvalidApplicationNameException::InvalidFormat
+ );
+ }
+ }
+
+ private function ensureIsString($name) {
+ if (!is_string($name)) {
+ throw new InvalidApplicationNameException(
+ 'Name must be a string',
+ InvalidApplicationNameException::NotAString
+ );
+ }
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/Author.php b/vendor/phar-io/manifest/src/values/Author.php
new file mode 100644
index 0000000..8295f51
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/Author.php
@@ -0,0 +1,57 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class Author {
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var Email
+ */
+ private $email;
+
+ /**
+ * @param string $name
+ * @param Email $email
+ */
+ public function __construct($name, Email $email) {
+ $this->name = $name;
+ $this->email = $email;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * @return Email
+ */
+ public function getEmail() {
+ return $this->email;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString() {
+ return sprintf(
+ '%s <%s>',
+ $this->name,
+ $this->email
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/AuthorCollection.php b/vendor/phar-io/manifest/src/values/AuthorCollection.php
new file mode 100644
index 0000000..d915879
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/AuthorCollection.php
@@ -0,0 +1,43 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class AuthorCollection implements \Countable, \IteratorAggregate {
+ /**
+ * @var Author[]
+ */
+ private $authors = [];
+
+ public function add(Author $author) {
+ $this->authors[] = $author;
+ }
+
+ /**
+ * @return Author[]
+ */
+ public function getAuthors() {
+ return $this->authors;
+ }
+
+ /**
+ * @return int
+ */
+ public function count() {
+ return count($this->authors);
+ }
+
+ /**
+ * @return AuthorCollectionIterator
+ */
+ public function getIterator() {
+ return new AuthorCollectionIterator($this);
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/AuthorCollectionIterator.php b/vendor/phar-io/manifest/src/values/AuthorCollectionIterator.php
new file mode 100644
index 0000000..792a050
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/AuthorCollectionIterator.php
@@ -0,0 +1,56 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class AuthorCollectionIterator implements \Iterator {
+ /**
+ * @var Author[]
+ */
+ private $authors = [];
+
+ /**
+ * @var int
+ */
+ private $position;
+
+ public function __construct(AuthorCollection $authors) {
+ $this->authors = $authors->getAuthors();
+ }
+
+ public function rewind() {
+ $this->position = 0;
+ }
+
+ /**
+ * @return bool
+ */
+ public function valid() {
+ return $this->position < count($this->authors);
+ }
+
+ /**
+ * @return int
+ */
+ public function key() {
+ return $this->position;
+ }
+
+ /**
+ * @return Author
+ */
+ public function current() {
+ return $this->authors[$this->position];
+ }
+
+ public function next() {
+ $this->position++;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/BundledComponent.php b/vendor/phar-io/manifest/src/values/BundledComponent.php
new file mode 100644
index 0000000..846d15a
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/BundledComponent.php
@@ -0,0 +1,48 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\Version;
+
+class BundledComponent {
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var Version
+ */
+ private $version;
+
+ /**
+ * @param string $name
+ * @param Version $version
+ */
+ public function __construct($name, Version $version) {
+ $this->name = $name;
+ $this->version = $version;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * @return Version
+ */
+ public function getVersion() {
+ return $this->version;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/BundledComponentCollection.php b/vendor/phar-io/manifest/src/values/BundledComponentCollection.php
new file mode 100644
index 0000000..2dbb918
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/BundledComponentCollection.php
@@ -0,0 +1,43 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class BundledComponentCollection implements \Countable, \IteratorAggregate {
+ /**
+ * @var BundledComponent[]
+ */
+ private $bundledComponents = [];
+
+ public function add(BundledComponent $bundledComponent) {
+ $this->bundledComponents[] = $bundledComponent;
+ }
+
+ /**
+ * @return BundledComponent[]
+ */
+ public function getBundledComponents() {
+ return $this->bundledComponents;
+ }
+
+ /**
+ * @return int
+ */
+ public function count() {
+ return count($this->bundledComponents);
+ }
+
+ /**
+ * @return BundledComponentCollectionIterator
+ */
+ public function getIterator() {
+ return new BundledComponentCollectionIterator($this);
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/BundledComponentCollectionIterator.php b/vendor/phar-io/manifest/src/values/BundledComponentCollectionIterator.php
new file mode 100644
index 0000000..13b8f05
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/BundledComponentCollectionIterator.php
@@ -0,0 +1,56 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class BundledComponentCollectionIterator implements \Iterator {
+ /**
+ * @var BundledComponent[]
+ */
+ private $bundledComponents = [];
+
+ /**
+ * @var int
+ */
+ private $position;
+
+ public function __construct(BundledComponentCollection $bundledComponents) {
+ $this->bundledComponents = $bundledComponents->getBundledComponents();
+ }
+
+ public function rewind() {
+ $this->position = 0;
+ }
+
+ /**
+ * @return bool
+ */
+ public function valid() {
+ return $this->position < count($this->bundledComponents);
+ }
+
+ /**
+ * @return int
+ */
+ public function key() {
+ return $this->position;
+ }
+
+ /**
+ * @return BundledComponent
+ */
+ public function current() {
+ return $this->bundledComponents[$this->position];
+ }
+
+ public function next() {
+ $this->position++;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/CopyrightInformation.php b/vendor/phar-io/manifest/src/values/CopyrightInformation.php
new file mode 100644
index 0000000..ece60b1
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/CopyrightInformation.php
@@ -0,0 +1,42 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class CopyrightInformation {
+ /**
+ * @var AuthorCollection
+ */
+ private $authors;
+
+ /**
+ * @var License
+ */
+ private $license;
+
+ public function __construct(AuthorCollection $authors, License $license) {
+ $this->authors = $authors;
+ $this->license = $license;
+ }
+
+ /**
+ * @return AuthorCollection
+ */
+ public function getAuthors() {
+ return $this->authors;
+ }
+
+ /**
+ * @return License
+ */
+ public function getLicense() {
+ return $this->license;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/Email.php b/vendor/phar-io/manifest/src/values/Email.php
new file mode 100644
index 0000000..57cce04
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/Email.php
@@ -0,0 +1,47 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class Email {
+ /**
+ * @var string
+ */
+ private $email;
+
+ /**
+ * @param string $email
+ *
+ * @throws InvalidEmailException
+ */
+ public function __construct($email) {
+ $this->ensureEmailIsValid($email);
+
+ $this->email = $email;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString() {
+ return $this->email;
+ }
+
+ /**
+ * @param string $url
+ *
+ * @throws InvalidEmailException
+ */
+ private function ensureEmailIsValid($url) {
+ if (filter_var($url, \FILTER_VALIDATE_EMAIL) === false) {
+ throw new InvalidEmailException;
+ }
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/Extension.php b/vendor/phar-io/manifest/src/values/Extension.php
new file mode 100644
index 0000000..90d6a6f
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/Extension.php
@@ -0,0 +1,75 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\Version;
+use PharIo\Version\VersionConstraint;
+
+class Extension extends Type {
+ /**
+ * @var ApplicationName
+ */
+ private $application;
+
+ /**
+ * @var VersionConstraint
+ */
+ private $versionConstraint;
+
+ /**
+ * @param ApplicationName $application
+ * @param VersionConstraint $versionConstraint
+ */
+ public function __construct(ApplicationName $application, VersionConstraint $versionConstraint) {
+ $this->application = $application;
+ $this->versionConstraint = $versionConstraint;
+ }
+
+ /**
+ * @return ApplicationName
+ */
+ public function getApplicationName() {
+ return $this->application;
+ }
+
+ /**
+ * @return VersionConstraint
+ */
+ public function getVersionConstraint() {
+ return $this->versionConstraint;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isExtension() {
+ return true;
+ }
+
+ /**
+ * @param ApplicationName $name
+ *
+ * @return bool
+ */
+ public function isExtensionFor(ApplicationName $name) {
+ return $this->application->isEqual($name);
+ }
+
+ /**
+ * @param ApplicationName $name
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function isCompatibleWith(ApplicationName $name, Version $version) {
+ return $this->isExtensionFor($name) && $this->versionConstraint->complies($version);
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/Library.php b/vendor/phar-io/manifest/src/values/Library.php
new file mode 100644
index 0000000..a6ff944
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/Library.php
@@ -0,0 +1,20 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class Library extends Type {
+ /**
+ * @return bool
+ */
+ public function isLibrary() {
+ return true;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/License.php b/vendor/phar-io/manifest/src/values/License.php
new file mode 100644
index 0000000..e278670
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/License.php
@@ -0,0 +1,42 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class License {
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var Url
+ */
+ private $url;
+
+ public function __construct($name, Url $url) {
+ $this->name = $name;
+ $this->url = $url;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * @return Url
+ */
+ public function getUrl() {
+ return $this->url;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/Manifest.php b/vendor/phar-io/manifest/src/values/Manifest.php
new file mode 100644
index 0000000..217acef
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/Manifest.php
@@ -0,0 +1,138 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\Version;
+
+class Manifest {
+ /**
+ * @var ApplicationName
+ */
+ private $name;
+
+ /**
+ * @var Version
+ */
+ private $version;
+
+ /**
+ * @var Type
+ */
+ private $type;
+
+ /**
+ * @var CopyrightInformation
+ */
+ private $copyrightInformation;
+
+ /**
+ * @var RequirementCollection
+ */
+ private $requirements;
+
+ /**
+ * @var BundledComponentCollection
+ */
+ private $bundledComponents;
+
+ public function __construct(ApplicationName $name, Version $version, Type $type, CopyrightInformation $copyrightInformation, RequirementCollection $requirements, BundledComponentCollection $bundledComponents) {
+ $this->name = $name;
+ $this->version = $version;
+ $this->type = $type;
+ $this->copyrightInformation = $copyrightInformation;
+ $this->requirements = $requirements;
+ $this->bundledComponents = $bundledComponents;
+ }
+
+ /**
+ * @return ApplicationName
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * @return Version
+ */
+ public function getVersion() {
+ return $this->version;
+ }
+
+ /**
+ * @return Type
+ */
+ public function getType() {
+ return $this->type;
+ }
+
+ /**
+ * @return CopyrightInformation
+ */
+ public function getCopyrightInformation() {
+ return $this->copyrightInformation;
+ }
+
+ /**
+ * @return RequirementCollection
+ */
+ public function getRequirements() {
+ return $this->requirements;
+ }
+
+ /**
+ * @return BundledComponentCollection
+ */
+ public function getBundledComponents() {
+ return $this->bundledComponents;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isApplication() {
+ return $this->type->isApplication();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isLibrary() {
+ return $this->type->isLibrary();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isExtension() {
+ return $this->type->isExtension();
+ }
+
+ /**
+ * @param ApplicationName $application
+ * @param Version|null $version
+ *
+ * @return bool
+ */
+ public function isExtensionFor(ApplicationName $application, Version $version = null) {
+ if (!$this->isExtension()) {
+ return false;
+ }
+
+ /** @var Extension $type */
+ $type = $this->type;
+
+ if ($version !== null) {
+ return $type->isCompatibleWith($application, $version);
+ }
+
+ return $type->isExtensionFor($application);
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/PhpExtensionRequirement.php b/vendor/phar-io/manifest/src/values/PhpExtensionRequirement.php
new file mode 100644
index 0000000..6dd9296
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/PhpExtensionRequirement.php
@@ -0,0 +1,32 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class PhpExtensionRequirement implements Requirement {
+ /**
+ * @var string
+ */
+ private $extension;
+
+ /**
+ * @param string $extension
+ */
+ public function __construct($extension) {
+ $this->extension = $extension;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString() {
+ return $this->extension;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/PhpVersionRequirement.php b/vendor/phar-io/manifest/src/values/PhpVersionRequirement.php
new file mode 100644
index 0000000..8ad3e76
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/PhpVersionRequirement.php
@@ -0,0 +1,31 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\VersionConstraint;
+
+class PhpVersionRequirement implements Requirement {
+ /**
+ * @var VersionConstraint
+ */
+ private $versionConstraint;
+
+ public function __construct(VersionConstraint $versionConstraint) {
+ $this->versionConstraint = $versionConstraint;
+ }
+
+ /**
+ * @return VersionConstraint
+ */
+ public function getVersionConstraint() {
+ return $this->versionConstraint;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/Requirement.php b/vendor/phar-io/manifest/src/values/Requirement.php
new file mode 100644
index 0000000..03bb56d
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/Requirement.php
@@ -0,0 +1,14 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+interface Requirement {
+}
diff --git a/vendor/phar-io/manifest/src/values/RequirementCollection.php b/vendor/phar-io/manifest/src/values/RequirementCollection.php
new file mode 100644
index 0000000..af0e09b
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/RequirementCollection.php
@@ -0,0 +1,43 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class RequirementCollection implements \Countable, \IteratorAggregate {
+ /**
+ * @var Requirement[]
+ */
+ private $requirements = [];
+
+ public function add(Requirement $requirement) {
+ $this->requirements[] = $requirement;
+ }
+
+ /**
+ * @return Requirement[]
+ */
+ public function getRequirements() {
+ return $this->requirements;
+ }
+
+ /**
+ * @return int
+ */
+ public function count() {
+ return count($this->requirements);
+ }
+
+ /**
+ * @return RequirementCollectionIterator
+ */
+ public function getIterator() {
+ return new RequirementCollectionIterator($this);
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/RequirementCollectionIterator.php b/vendor/phar-io/manifest/src/values/RequirementCollectionIterator.php
new file mode 100644
index 0000000..9bb7003
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/RequirementCollectionIterator.php
@@ -0,0 +1,56 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class RequirementCollectionIterator implements \Iterator {
+ /**
+ * @var Requirement[]
+ */
+ private $requirements = [];
+
+ /**
+ * @var int
+ */
+ private $position;
+
+ public function __construct(RequirementCollection $requirements) {
+ $this->requirements = $requirements->getRequirements();
+ }
+
+ public function rewind() {
+ $this->position = 0;
+ }
+
+ /**
+ * @return bool
+ */
+ public function valid() {
+ return $this->position < count($this->requirements);
+ }
+
+ /**
+ * @return int
+ */
+ public function key() {
+ return $this->position;
+ }
+
+ /**
+ * @return Requirement
+ */
+ public function current() {
+ return $this->requirements[$this->position];
+ }
+
+ public function next() {
+ $this->position++;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/Type.php b/vendor/phar-io/manifest/src/values/Type.php
new file mode 100644
index 0000000..31fbd44
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/Type.php
@@ -0,0 +1,60 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\VersionConstraint;
+
+abstract class Type {
+ /**
+ * @return Application
+ */
+ public static function application() {
+ return new Application;
+ }
+
+ /**
+ * @return Library
+ */
+ public static function library() {
+ return new Library;
+ }
+
+ /**
+ * @param ApplicationName $application
+ * @param VersionConstraint $versionConstraint
+ *
+ * @return Extension
+ */
+ public static function extension(ApplicationName $application, VersionConstraint $versionConstraint) {
+ return new Extension($application, $versionConstraint);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isApplication() {
+ return false;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isLibrary() {
+ return false;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isExtension() {
+ return false;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/values/Url.php b/vendor/phar-io/manifest/src/values/Url.php
new file mode 100644
index 0000000..37917c8
--- /dev/null
+++ b/vendor/phar-io/manifest/src/values/Url.php
@@ -0,0 +1,47 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class Url {
+ /**
+ * @var string
+ */
+ private $url;
+
+ /**
+ * @param string $url
+ *
+ * @throws InvalidUrlException
+ */
+ public function __construct($url) {
+ $this->ensureUrlIsValid($url);
+
+ $this->url = $url;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString() {
+ return $this->url;
+ }
+
+ /**
+ * @param string $url
+ *
+ * @throws InvalidUrlException
+ */
+ private function ensureUrlIsValid($url) {
+ if (filter_var($url, \FILTER_VALIDATE_URL) === false) {
+ throw new InvalidUrlException;
+ }
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/AuthorElement.php b/vendor/phar-io/manifest/src/xml/AuthorElement.php
new file mode 100644
index 0000000..a32f397
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/AuthorElement.php
@@ -0,0 +1,21 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class AuthorElement extends ManifestElement {
+ public function getName() {
+ return $this->getAttributeValue('name');
+ }
+
+ public function getEmail() {
+ return $this->getAttributeValue('email');
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/AuthorElementCollection.php b/vendor/phar-io/manifest/src/xml/AuthorElementCollection.php
new file mode 100644
index 0000000..1240d8c
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/AuthorElementCollection.php
@@ -0,0 +1,19 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class AuthorElementCollection extends ElementCollection {
+ public function current() {
+ return new AuthorElement(
+ $this->getCurrentElement()
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/BundlesElement.php b/vendor/phar-io/manifest/src/xml/BundlesElement.php
new file mode 100644
index 0000000..b90023e
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/BundlesElement.php
@@ -0,0 +1,19 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class BundlesElement extends ManifestElement {
+ public function getComponentElements() {
+ return new ComponentElementCollection(
+ $this->getChildrenByName('component')
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/ComponentElement.php b/vendor/phar-io/manifest/src/xml/ComponentElement.php
new file mode 100644
index 0000000..64ed6b0
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ComponentElement.php
@@ -0,0 +1,21 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class ComponentElement extends ManifestElement {
+ public function getName() {
+ return $this->getAttributeValue('name');
+ }
+
+ public function getVersion() {
+ return $this->getAttributeValue('version');
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/ComponentElementCollection.php b/vendor/phar-io/manifest/src/xml/ComponentElementCollection.php
new file mode 100644
index 0000000..9d375f9
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ComponentElementCollection.php
@@ -0,0 +1,19 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class ComponentElementCollection extends ElementCollection {
+ public function current() {
+ return new ComponentElement(
+ $this->getCurrentElement()
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/ContainsElement.php b/vendor/phar-io/manifest/src/xml/ContainsElement.php
new file mode 100644
index 0000000..8172f33
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ContainsElement.php
@@ -0,0 +1,31 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class ContainsElement extends ManifestElement {
+ public function getName() {
+ return $this->getAttributeValue('name');
+ }
+
+ public function getVersion() {
+ return $this->getAttributeValue('version');
+ }
+
+ public function getType() {
+ return $this->getAttributeValue('type');
+ }
+
+ public function getExtensionElement() {
+ return new ExtensionElement(
+ $this->getChildByName('extension')
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/CopyrightElement.php b/vendor/phar-io/manifest/src/xml/CopyrightElement.php
new file mode 100644
index 0000000..bf7848e
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/CopyrightElement.php
@@ -0,0 +1,25 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class CopyrightElement extends ManifestElement {
+ public function getAuthorElements() {
+ return new AuthorElementCollection(
+ $this->getChildrenByName('author')
+ );
+ }
+
+ public function getLicenseElement() {
+ return new LicenseElement(
+ $this->getChildByName('license')
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/ElementCollection.php b/vendor/phar-io/manifest/src/xml/ElementCollection.php
new file mode 100644
index 0000000..284e77b
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ElementCollection.php
@@ -0,0 +1,58 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use DOMElement;
+use DOMNodeList;
+
+abstract class ElementCollection implements \Iterator {
+ /**
+ * @var DOMNodeList
+ */
+ private $nodeList;
+
+ private $position;
+
+ /**
+ * ElementCollection constructor.
+ *
+ * @param DOMNodeList $nodeList
+ */
+ public function __construct(DOMNodeList $nodeList) {
+ $this->nodeList = $nodeList;
+ $this->position = 0;
+ }
+
+ abstract public function current();
+
+ /**
+ * @return DOMElement
+ */
+ protected function getCurrentElement() {
+ return $this->nodeList->item($this->position);
+ }
+
+ public function next() {
+ $this->position++;
+ }
+
+ public function key() {
+ return $this->position;
+ }
+
+ public function valid() {
+ return $this->position < $this->nodeList->length;
+ }
+
+ public function rewind() {
+ $this->position = 0;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/ExtElement.php b/vendor/phar-io/manifest/src/xml/ExtElement.php
new file mode 100644
index 0000000..7a824ab
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ExtElement.php
@@ -0,0 +1,17 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class ExtElement extends ManifestElement {
+ public function getName() {
+ return $this->getAttributeValue('name');
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/ExtElementCollection.php b/vendor/phar-io/manifest/src/xml/ExtElementCollection.php
new file mode 100644
index 0000000..17acc62
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ExtElementCollection.php
@@ -0,0 +1,20 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class ExtElementCollection extends ElementCollection {
+ public function current() {
+ return new ExtElement(
+ $this->getCurrentElement()
+ );
+ }
+
+}
diff --git a/vendor/phar-io/manifest/src/xml/ExtensionElement.php b/vendor/phar-io/manifest/src/xml/ExtensionElement.php
new file mode 100644
index 0000000..536c085
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ExtensionElement.php
@@ -0,0 +1,21 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class ExtensionElement extends ManifestElement {
+ public function getFor() {
+ return $this->getAttributeValue('for');
+ }
+
+ public function getCompatible() {
+ return $this->getAttributeValue('compatible');
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/LicenseElement.php b/vendor/phar-io/manifest/src/xml/LicenseElement.php
new file mode 100644
index 0000000..ee001df
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/LicenseElement.php
@@ -0,0 +1,21 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class LicenseElement extends ManifestElement {
+ public function getType() {
+ return $this->getAttributeValue('type');
+ }
+
+ public function getUrl() {
+ return $this->getAttributeValue('url');
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/ManifestDocument.php b/vendor/phar-io/manifest/src/xml/ManifestDocument.php
new file mode 100644
index 0000000..9b0bd9d
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ManifestDocument.php
@@ -0,0 +1,118 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use DOMDocument;
+use DOMElement;
+
+class ManifestDocument {
+ const XMLNS = 'https://phar.io/xml/manifest/1.0';
+
+ /**
+ * @var DOMDocument
+ */
+ private $dom;
+
+ /**
+ * ManifestDocument constructor.
+ *
+ * @param DOMDocument $dom
+ */
+ private function __construct(DOMDocument $dom) {
+ $this->ensureCorrectDocumentType($dom);
+
+ $this->dom = $dom;
+ }
+
+ public static function fromFile($filename) {
+ if (!file_exists($filename)) {
+ throw new ManifestDocumentException(
+ sprintf('File "%s" not found', $filename)
+ );
+ }
+
+ return self::fromString(
+ file_get_contents($filename)
+ );
+ }
+
+ public static function fromString($xmlString) {
+ $prev = libxml_use_internal_errors(true);
+ libxml_clear_errors();
+
+ $dom = new DOMDocument();
+ $dom->loadXML($xmlString);
+
+ $errors = libxml_get_errors();
+ libxml_use_internal_errors($prev);
+
+ if (count($errors) !== 0) {
+ throw new ManifestDocumentLoadingException($errors);
+ }
+
+ return new self($dom);
+ }
+
+ public function getContainsElement() {
+ return new ContainsElement(
+ $this->fetchElementByName('contains')
+ );
+ }
+
+ public function getCopyrightElement() {
+ return new CopyrightElement(
+ $this->fetchElementByName('copyright')
+ );
+ }
+
+ public function getRequiresElement() {
+ return new RequiresElement(
+ $this->fetchElementByName('requires')
+ );
+ }
+
+ public function hasBundlesElement() {
+ return $this->dom->getElementsByTagNameNS(self::XMLNS, 'bundles')->length === 1;
+ }
+
+ public function getBundlesElement() {
+ return new BundlesElement(
+ $this->fetchElementByName('bundles')
+ );
+ }
+
+ private function ensureCorrectDocumentType(DOMDocument $dom) {
+ $root = $dom->documentElement;
+
+ if ($root->localName !== 'phar' || $root->namespaceURI !== self::XMLNS) {
+ throw new ManifestDocumentException('Not a phar.io manifest document');
+ }
+ }
+
+ /**
+ * @param $elementName
+ *
+ * @return DOMElement
+ *
+ * @throws ManifestDocumentException
+ */
+ private function fetchElementByName($elementName) {
+ $element = $this->dom->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);
+
+ if (!$element instanceof DOMElement) {
+ throw new ManifestDocumentException(
+ sprintf('Element %s missing', $elementName)
+ );
+ }
+
+ return $element;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php b/vendor/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php
new file mode 100644
index 0000000..59ac5c6
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php
@@ -0,0 +1,48 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use LibXMLError;
+
+class ManifestDocumentLoadingException extends \Exception implements Exception {
+ /**
+ * @var LibXMLError[]
+ */
+ private $libxmlErrors;
+
+ /**
+ * ManifestDocumentLoadingException constructor.
+ *
+ * @param LibXMLError[] $libxmlErrors
+ */
+ public function __construct(array $libxmlErrors) {
+ $this->libxmlErrors = $libxmlErrors;
+ $first = $this->libxmlErrors[0];
+
+ parent::__construct(
+ sprintf(
+ '%s (Line: %d / Column: %d / File: %s)',
+ $first->message,
+ $first->line,
+ $first->column,
+ $first->file
+ ),
+ $first->code
+ );
+ }
+
+ /**
+ * @return LibXMLError[]
+ */
+ public function getLibxmlErrors() {
+ return $this->libxmlErrors;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/ManifestElement.php b/vendor/phar-io/manifest/src/xml/ManifestElement.php
new file mode 100644
index 0000000..09d07cc
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/ManifestElement.php
@@ -0,0 +1,100 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use DOMElement;
+use DOMNodeList;
+
+class ManifestElement {
+ const XMLNS = 'https://phar.io/xml/manifest/1.0';
+
+ /**
+ * @var DOMElement
+ */
+ private $element;
+
+ /**
+ * ContainsElement constructor.
+ *
+ * @param DOMElement $element
+ */
+ public function __construct(DOMElement $element) {
+ $this->element = $element;
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return string
+ *
+ * @throws ManifestElementException
+ */
+ protected function getAttributeValue($name) {
+ if (!$this->element->hasAttribute($name)) {
+ throw new ManifestElementException(
+ sprintf(
+ 'Attribute %s not set on element %s',
+ $name,
+ $this->element->localName
+ )
+ );
+ }
+
+ return $this->element->getAttribute($name);
+ }
+
+ /**
+ * @param $elementName
+ *
+ * @return DOMElement
+ *
+ * @throws ManifestElementException
+ */
+ protected function getChildByName($elementName) {
+ $element = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);
+
+ if (!$element instanceof DOMElement) {
+ throw new ManifestElementException(
+ sprintf('Element %s missing', $elementName)
+ );
+ }
+
+ return $element;
+ }
+
+ /**
+ * @param $elementName
+ *
+ * @return DOMNodeList
+ *
+ * @throws ManifestElementException
+ */
+ protected function getChildrenByName($elementName) {
+ $elementList = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName);
+
+ if ($elementList->length === 0) {
+ throw new ManifestElementException(
+ sprintf('Element(s) %s missing', $elementName)
+ );
+ }
+
+ return $elementList;
+ }
+
+ /**
+ * @param string $elementName
+ *
+ * @return bool
+ */
+ protected function hasChild($elementName) {
+ return $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->length !== 0;
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/PhpElement.php b/vendor/phar-io/manifest/src/xml/PhpElement.php
new file mode 100644
index 0000000..e7340c0
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/PhpElement.php
@@ -0,0 +1,27 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class PhpElement extends ManifestElement {
+ public function getVersion() {
+ return $this->getAttributeValue('version');
+ }
+
+ public function hasExtElements() {
+ return $this->hasChild('ext');
+ }
+
+ public function getExtElements() {
+ return new ExtElementCollection(
+ $this->getChildrenByName('ext')
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/src/xml/RequiresElement.php b/vendor/phar-io/manifest/src/xml/RequiresElement.php
new file mode 100644
index 0000000..5f41b2e
--- /dev/null
+++ b/vendor/phar-io/manifest/src/xml/RequiresElement.php
@@ -0,0 +1,19 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+class RequiresElement extends ManifestElement {
+ public function getPHPElement() {
+ return new PhpElement(
+ $this->getChildByName('php')
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/ManifestDocumentMapperTest.php b/vendor/phar-io/manifest/tests/ManifestDocumentMapperTest.php
new file mode 100644
index 0000000..c69d761
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/ManifestDocumentMapperTest.php
@@ -0,0 +1,110 @@
+assertInstanceOf(
+ Manifest::class,
+ $mapper->map($manifestDocument)
+ );
+ }
+
+ public function dataProvider() {
+ return [
+ 'application' => [__DIR__ . '/_fixture/phpunit-5.6.5.xml'],
+ 'library' => [__DIR__ . '/_fixture/library.xml'],
+ 'extension' => [__DIR__ . '/_fixture/extension.xml']
+ ];
+ }
+
+ public function testThrowsExceptionOnUnsupportedType() {
+ $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/custom.xml');
+ $mapper = new ManifestDocumentMapper();
+
+ $this->expectException(ManifestDocumentMapperException::class);
+ $mapper->map($manifestDocument);
+ }
+
+ public function testInvalidVersionInformationThrowsException() {
+ $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/invalidversion.xml');
+ $mapper = new ManifestDocumentMapper();
+
+ $this->expectException(ManifestDocumentMapperException::class);
+ $mapper->map($manifestDocument);
+ }
+
+ public function testInvalidVersionConstraintThrowsException() {
+ $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/invalidversionconstraint.xml');
+ $mapper = new ManifestDocumentMapper();
+
+ $this->expectException(ManifestDocumentMapperException::class);
+ $mapper->map($manifestDocument);
+ }
+
+ /**
+ * @uses \PharIo\Manifest\ExtensionElement
+ */
+ public function testInvalidCompatibleConstraintThrowsException() {
+ $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/extension-invalidcompatible.xml');
+ $mapper = new ManifestDocumentMapper();
+
+ $this->expectException(ManifestDocumentMapperException::class);
+ $mapper->map($manifestDocument);
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/ManifestLoaderTest.php b/vendor/phar-io/manifest/tests/ManifestLoaderTest.php
new file mode 100644
index 0000000..919143a
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/ManifestLoaderTest.php
@@ -0,0 +1,83 @@
+assertInstanceOf(
+ Manifest::class,
+ ManifestLoader::fromFile(__DIR__ . '/_fixture/library.xml')
+ );
+ }
+
+ public function testCanBeLoadedFromString() {
+ $this->assertInstanceOf(
+ Manifest::class,
+ ManifestLoader::fromString(
+ file_get_contents(__DIR__ . '/_fixture/library.xml')
+ )
+ );
+ }
+
+ public function testCanBeLoadedFromPhar() {
+ $this->assertInstanceOf(
+ Manifest::class,
+ ManifestLoader::fromPhar(__DIR__ . '/_fixture/test.phar')
+ );
+
+ }
+
+ public function testLoadingNonExistingFileThrowsException() {
+ $this->expectException(ManifestLoaderException::class);
+ ManifestLoader::fromFile('/not/existing');
+ }
+
+ /**
+ * @uses \PharIo\Manifest\ManifestDocumentLoadingException
+ */
+ public function testLoadingInvalidXmlThrowsException() {
+ $this->expectException(ManifestLoaderException::class);
+ ManifestLoader::fromString('');
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/ManifestSerializerTest.php b/vendor/phar-io/manifest/tests/ManifestSerializerTest.php
new file mode 100644
index 0000000..5fdf799
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/ManifestSerializerTest.php
@@ -0,0 +1,114 @@
+assertXmlStringEqualsXmlString(
+ $expected,
+ $serializer->serializeToString($manifest)
+ );
+ }
+
+ public function dataProvider() {
+ return [
+ 'application' => [file_get_contents(__DIR__ . '/_fixture/phpunit-5.6.5.xml')],
+ 'library' => [file_get_contents(__DIR__ . '/_fixture/library.xml')],
+ 'extension' => [file_get_contents(__DIR__ . '/_fixture/extension.xml')]
+ ];
+ }
+
+ /**
+ * @uses \PharIo\Manifest\Library
+ * @uses \PharIo\Manifest\ApplicationName
+ */
+ public function testCanSerializeToFile() {
+ $src = __DIR__ . '/_fixture/library.xml';
+ $dest = '/tmp/' . uniqid('serializer', true);
+ $manifest = ManifestLoader::fromFile($src);
+ $serializer = new ManifestSerializer();
+ $serializer->serializeToFile($manifest, $dest);
+ $this->assertXmlFileEqualsXmlFile($src, $dest);
+ unlink($dest);
+ }
+
+ /**
+ * @uses \PharIo\Manifest\ApplicationName
+ */
+ public function testCanHandleUnknownType() {
+ $type = $this->getMockForAbstractClass(Type::class);
+ $manifest = new Manifest(
+ new ApplicationName('testvendor/testname'),
+ new Version('1.0.0'),
+ $type,
+ new CopyrightInformation(
+ new AuthorCollection(),
+ new License('bsd-3', new Url('https://some/uri'))
+ ),
+ new RequirementCollection(),
+ new BundledComponentCollection()
+ );
+
+ $serializer = new ManifestSerializer();
+ $this->assertXmlStringEqualsXmlFile(
+ __DIR__ . '/_fixture/custom.xml',
+ $serializer->serializeToString($manifest)
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/_fixture/custom.xml b/vendor/phar-io/manifest/tests/_fixture/custom.xml
new file mode 100644
index 0000000..4f43828
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/_fixture/custom.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/manifest/tests/_fixture/extension-invalidcompatible.xml b/vendor/phar-io/manifest/tests/_fixture/extension-invalidcompatible.xml
new file mode 100644
index 0000000..a78111c
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/_fixture/extension-invalidcompatible.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/manifest/tests/_fixture/extension.xml b/vendor/phar-io/manifest/tests/_fixture/extension.xml
new file mode 100644
index 0000000..a870aee
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/_fixture/extension.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/manifest/tests/_fixture/invalidversion.xml b/vendor/phar-io/manifest/tests/_fixture/invalidversion.xml
new file mode 100644
index 0000000..788dd4c
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/_fixture/invalidversion.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/manifest/tests/_fixture/invalidversionconstraint.xml b/vendor/phar-io/manifest/tests/_fixture/invalidversionconstraint.xml
new file mode 100644
index 0000000..f881f8b
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/_fixture/invalidversionconstraint.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/manifest/tests/_fixture/library.xml b/vendor/phar-io/manifest/tests/_fixture/library.xml
new file mode 100644
index 0000000..a5e2523
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/_fixture/library.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/manifest/tests/_fixture/manifest.xml b/vendor/phar-io/manifest/tests/_fixture/manifest.xml
new file mode 100644
index 0000000..a5e2523
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/_fixture/manifest.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/manifest/tests/_fixture/phpunit-5.6.5.xml b/vendor/phar-io/manifest/tests/_fixture/phpunit-5.6.5.xml
new file mode 100644
index 0000000..aadbea2
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/_fixture/phpunit-5.6.5.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/manifest/tests/_fixture/test.phar b/vendor/phar-io/manifest/tests/_fixture/test.phar
new file mode 100644
index 0000000..d2a3e39
Binary files /dev/null and b/vendor/phar-io/manifest/tests/_fixture/test.phar differ
diff --git a/vendor/phar-io/manifest/tests/exceptions/ManifestDocumentLoadingExceptionTest.php b/vendor/phar-io/manifest/tests/exceptions/ManifestDocumentLoadingExceptionTest.php
new file mode 100644
index 0000000..70f7553
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/exceptions/ManifestDocumentLoadingExceptionTest.php
@@ -0,0 +1,19 @@
+loadXML('');
+ $exception = new ManifestDocumentLoadingException(libxml_get_errors());
+ libxml_use_internal_errors($prev);
+
+ $this->assertContainsOnlyInstancesOf(LibXMLError::class, $exception->getLibxmlErrors());
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/values/ApplicationNameTest.php b/vendor/phar-io/manifest/tests/values/ApplicationNameTest.php
new file mode 100644
index 0000000..8ed3f3a
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/ApplicationNameTest.php
@@ -0,0 +1,57 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+class ApplicationNameTest extends TestCase {
+
+ public function testCanBeCreatedWithValidName() {
+ $this->assertInstanceOf(
+ ApplicationName::class,
+ new ApplicationName('foo/bar')
+ );
+ }
+
+ public function testUsingInvalidFormatForNameThrowsException() {
+ $this->expectException(InvalidApplicationNameException::class);
+ $this->expectExceptionCode(InvalidApplicationNameException::InvalidFormat);
+ new ApplicationName('foo');
+ }
+
+ public function testUsingWrongTypeForNameThrowsException() {
+ $this->expectException(InvalidApplicationNameException::class);
+ $this->expectExceptionCode(InvalidApplicationNameException::NotAString);
+ new ApplicationName(123);
+ }
+
+ public function testReturnsTrueForEqualNamesWhenCompared() {
+ $app = new ApplicationName('foo/bar');
+ $this->assertTrue(
+ $app->isEqual($app)
+ );
+ }
+
+ public function testReturnsFalseForNonEqualNamesWhenCompared() {
+ $app1 = new ApplicationName('foo/bar');
+ $app2 = new ApplicationName('foo/foo');
+ $this->assertFalse(
+ $app1->isEqual($app2)
+ );
+ }
+
+ public function testCanBeConvertedToString() {
+ $this->assertEquals(
+ 'foo/bar',
+ new ApplicationName('foo/bar')
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/ApplicationTest.php b/vendor/phar-io/manifest/tests/values/ApplicationTest.php
new file mode 100644
index 0000000..86b5da6
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/ApplicationTest.php
@@ -0,0 +1,44 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\Application
+ * @covers PharIo\Manifest\Type
+ */
+class ApplicationTest extends TestCase {
+ /**
+ * @var Application
+ */
+ private $type;
+
+ protected function setUp() {
+ $this->type = Type::application();
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(Application::class, $this->type);
+ }
+
+ public function testIsApplication() {
+ $this->assertTrue($this->type->isApplication());
+ }
+
+ public function testIsNotLibrary() {
+ $this->assertFalse($this->type->isLibrary());
+ }
+
+ public function testIsNotExtension() {
+ $this->assertFalse($this->type->isExtension());
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/AuthorCollectionTest.php b/vendor/phar-io/manifest/tests/values/AuthorCollectionTest.php
new file mode 100644
index 0000000..0fa1b95
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/AuthorCollectionTest.php
@@ -0,0 +1,62 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Manifest\AuthorCollection
+ * @covers \PharIo\Manifest\AuthorCollectionIterator
+ *
+ * @uses \PharIo\Manifest\Author
+ * @uses \PharIo\Manifest\Email
+ */
+class AuthorCollectionTest extends TestCase {
+ /**
+ * @var AuthorCollection
+ */
+ private $collection;
+
+ /**
+ * @var Author
+ */
+ private $item;
+
+ protected function setUp() {
+ $this->collection = new AuthorCollection;
+ $this->item = new Author('Joe Developer', new Email('user@example.com'));
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(AuthorCollection::class, $this->collection);
+ }
+
+ public function testCanBeCounted() {
+ $this->collection->add($this->item);
+
+ $this->assertCount(1, $this->collection);
+ }
+
+ public function testCanBeIterated() {
+ $this->collection->add(
+ new Author('Dummy First', new Email('dummy@example.com'))
+ );
+ $this->collection->add($this->item);
+ $this->assertContains($this->item, $this->collection);
+ }
+
+ public function testKeyPositionCanBeRetreived() {
+ $this->collection->add($this->item);
+ foreach($this->collection as $key => $item) {
+ $this->assertEquals(0, $key);
+ }
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/AuthorTest.php b/vendor/phar-io/manifest/tests/values/AuthorTest.php
new file mode 100644
index 0000000..b7317fa
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/AuthorTest.php
@@ -0,0 +1,45 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\Author
+ *
+ * @uses PharIo\Manifest\Email
+ */
+class AuthorTest extends TestCase {
+ /**
+ * @var Author
+ */
+ private $author;
+
+ protected function setUp() {
+ $this->author = new Author('Joe Developer', new Email('user@example.com'));
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(Author::class, $this->author);
+ }
+
+ public function testNameCanBeRetrieved() {
+ $this->assertEquals('Joe Developer', $this->author->getName());
+ }
+
+ public function testEmailCanBeRetrieved() {
+ $this->assertEquals('user@example.com', $this->author->getEmail());
+ }
+
+ public function testCanBeUsedAsString() {
+ $this->assertEquals('Joe Developer ', $this->author);
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/BundledComponentCollectionTest.php b/vendor/phar-io/manifest/tests/values/BundledComponentCollectionTest.php
new file mode 100644
index 0000000..66cd0c4
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/BundledComponentCollectionTest.php
@@ -0,0 +1,63 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\Version;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Manifest\BundledComponentCollection
+ * @covers \PharIo\Manifest\BundledComponentCollectionIterator
+ *
+ * @uses \PharIo\Manifest\BundledComponent
+ * @uses \PharIo\Version\Version
+ */
+class BundledComponentCollectionTest extends TestCase {
+ /**
+ * @var BundledComponentCollection
+ */
+ private $collection;
+
+ /**
+ * @var BundledComponent
+ */
+ private $item;
+
+ protected function setUp() {
+ $this->collection = new BundledComponentCollection;
+ $this->item = new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2'));
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(BundledComponentCollection::class, $this->collection);
+ }
+
+ public function testCanBeCounted() {
+ $this->collection->add($this->item);
+
+ $this->assertCount(1, $this->collection);
+ }
+
+ public function testCanBeIterated() {
+ $this->collection->add($this->createMock(BundledComponent::class));
+ $this->collection->add($this->item);
+
+ $this->assertContains($this->item, $this->collection);
+ }
+
+ public function testKeyPositionCanBeRetreived() {
+ $this->collection->add($this->item);
+ foreach($this->collection as $key => $item) {
+ $this->assertEquals(0, $key);
+ }
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/values/BundledComponentTest.php b/vendor/phar-io/manifest/tests/values/BundledComponentTest.php
new file mode 100644
index 0000000..01b8e13
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/BundledComponentTest.php
@@ -0,0 +1,42 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\Version;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\BundledComponent
+ *
+ * @uses \PharIo\Version\Version
+ */
+class BundledComponentTest extends TestCase {
+ /**
+ * @var BundledComponent
+ */
+ private $bundledComponent;
+
+ protected function setUp() {
+ $this->bundledComponent = new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2'));
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(BundledComponent::class, $this->bundledComponent);
+ }
+
+ public function testNameCanBeRetrieved() {
+ $this->assertEquals('phpunit/php-code-coverage', $this->bundledComponent->getName());
+ }
+
+ public function testVersionCanBeRetrieved() {
+ $this->assertEquals('4.0.2', $this->bundledComponent->getVersion()->getVersionString());
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/CopyrightInformationTest.php b/vendor/phar-io/manifest/tests/values/CopyrightInformationTest.php
new file mode 100644
index 0000000..de738f4
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/CopyrightInformationTest.php
@@ -0,0 +1,62 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\CopyrightInformation
+ *
+ * @uses PharIo\Manifest\AuthorCollection
+ * @uses PharIo\Manifest\AuthorCollectionIterator
+ * @uses PharIo\Manifest\Author
+ * @uses PharIo\Manifest\Email
+ * @uses PharIo\Manifest\License
+ * @uses PharIo\Manifest\Url
+ */
+class CopyrightInformationTest extends TestCase {
+ /**
+ * @var CopyrightInformation
+ */
+ private $copyrightInformation;
+
+ /**
+ * @var Author
+ */
+ private $author;
+
+ /**
+ * @var License
+ */
+ private $license;
+
+ protected function setUp() {
+ $this->author = new Author('Joe Developer', new Email('user@example.com'));
+ $this->license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE'));
+
+ $authors = new AuthorCollection;
+ $authors->add($this->author);
+
+ $this->copyrightInformation = new CopyrightInformation($authors, $this->license);
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(CopyrightInformation::class, $this->copyrightInformation);
+ }
+
+ public function testAuthorsCanBeRetrieved() {
+ $this->assertContains($this->author, $this->copyrightInformation->getAuthors());
+ }
+
+ public function testLicenseCanBeRetrieved() {
+ $this->assertEquals($this->license, $this->copyrightInformation->getLicense());
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/EmailTest.php b/vendor/phar-io/manifest/tests/values/EmailTest.php
new file mode 100644
index 0000000..ee38531
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/EmailTest.php
@@ -0,0 +1,35 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\Email
+ */
+class EmailTest extends TestCase {
+ public function testCanBeCreatedForValidEmail() {
+ $this->assertInstanceOf(Email::class, new Email('user@example.com'));
+ }
+
+ public function testCanBeUsedAsString() {
+ $this->assertEquals('user@example.com', new Email('user@example.com'));
+ }
+
+ /**
+ * @covers PharIo\Manifest\InvalidEmailException
+ */
+ public function testCannotBeCreatedForInvalidEmail() {
+ $this->expectException(InvalidEmailException::class);
+
+ new Email('invalid');
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/ExtensionTest.php b/vendor/phar-io/manifest/tests/values/ExtensionTest.php
new file mode 100644
index 0000000..1c9d676
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/ExtensionTest.php
@@ -0,0 +1,109 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\AnyVersionConstraint;
+use PharIo\Version\Version;
+use PharIo\Version\VersionConstraint;
+use PharIo\Version\VersionConstraintParser;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Manifest\Extension
+ * @covers \PharIo\Manifest\Type
+ *
+ * @uses \PharIo\Version\VersionConstraint
+ * @uses \PharIo\Manifest\ApplicationName
+ */
+class ExtensionTest extends TestCase {
+ /**
+ * @var Extension
+ */
+ private $type;
+
+ /**
+ * @var ApplicationName|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $name;
+
+ protected function setUp() {
+ $this->name = $this->createMock(ApplicationName::class);
+ $this->type = Type::extension($this->name, new AnyVersionConstraint);
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(Extension::class, $this->type);
+ }
+
+ public function testIsNotApplication() {
+ $this->assertFalse($this->type->isApplication());
+ }
+
+ public function testIsNotLibrary() {
+ $this->assertFalse($this->type->isLibrary());
+ }
+
+ public function testIsExtension() {
+ $this->assertTrue($this->type->isExtension());
+ }
+
+ public function testApplicationCanBeRetrieved()
+ {
+ $this->assertInstanceOf(ApplicationName::class, $this->type->getApplicationName());
+ }
+
+ public function testVersionConstraintCanBeRetrieved() {
+ $this->assertInstanceOf(
+ VersionConstraint::class,
+ $this->type->getVersionConstraint()
+ );
+ }
+
+ public function testApplicationCanBeQueried()
+ {
+ $this->name->method('isEqual')->willReturn(true);
+ $this->assertTrue(
+ $this->type->isExtensionFor($this->createMock(ApplicationName::class))
+ );
+ }
+
+ public function testCompatibleWithReturnsTrueForMatchingVersionConstraintAndApplicaiton() {
+ $app = new ApplicationName('foo/bar');
+ $extension = Type::extension($app, (new VersionConstraintParser)->parse('^1.0'));
+ $version = new Version('1.0.0');
+
+ $this->assertTrue(
+ $extension->isCompatibleWith($app, $version)
+ );
+ }
+
+ public function testCompatibleWithReturnsFalseForNotMatchingVersionConstraint() {
+ $app = new ApplicationName('foo/bar');
+ $extension = Type::extension($app, (new VersionConstraintParser)->parse('^1.0'));
+ $version = new Version('2.0.0');
+
+ $this->assertFalse(
+ $extension->isCompatibleWith($app, $version)
+ );
+ }
+
+ public function testCompatibleWithReturnsFalseForNotMatchingApplication() {
+ $app1 = new ApplicationName('foo/bar');
+ $app2 = new ApplicationName('foo/foo');
+ $extension = Type::extension($app1, (new VersionConstraintParser)->parse('^1.0'));
+ $version = new Version('1.0.0');
+
+ $this->assertFalse(
+ $extension->isCompatibleWith($app2, $version)
+ );
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/values/LibraryTest.php b/vendor/phar-io/manifest/tests/values/LibraryTest.php
new file mode 100644
index 0000000..f8d1c64
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/LibraryTest.php
@@ -0,0 +1,44 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\Library
+ * @covers PharIo\Manifest\Type
+ */
+class LibraryTest extends TestCase {
+ /**
+ * @var Library
+ */
+ private $type;
+
+ protected function setUp() {
+ $this->type = Type::library();
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(Library::class, $this->type);
+ }
+
+ public function testIsNotApplication() {
+ $this->assertFalse($this->type->isApplication());
+ }
+
+ public function testIsLibrary() {
+ $this->assertTrue($this->type->isLibrary());
+ }
+
+ public function testIsNotExtension() {
+ $this->assertFalse($this->type->isExtension());
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/LicenseTest.php b/vendor/phar-io/manifest/tests/values/LicenseTest.php
new file mode 100644
index 0000000..c9c5c3c
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/LicenseTest.php
@@ -0,0 +1,41 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\License
+ *
+ * @uses PharIo\Manifest\Url
+ */
+class LicenseTest extends TestCase {
+ /**
+ * @var License
+ */
+ private $license;
+
+ protected function setUp() {
+ $this->license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE'));
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(License::class, $this->license);
+ }
+
+ public function testNameCanBeRetrieved() {
+ $this->assertEquals('BSD-3-Clause', $this->license->getName());
+ }
+
+ public function testUrlCanBeRetrieved() {
+ $this->assertEquals('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE', $this->license->getUrl());
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/ManifestTest.php b/vendor/phar-io/manifest/tests/values/ManifestTest.php
new file mode 100644
index 0000000..cff0a68
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/ManifestTest.php
@@ -0,0 +1,187 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\Version;
+use PharIo\Version\AnyVersionConstraint;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Manifest\Manifest
+ *
+ * @uses \PharIo\Manifest\ApplicationName
+ * @uses \PharIo\Manifest\Author
+ * @uses \PharIo\Manifest\AuthorCollection
+ * @uses \PharIo\Manifest\BundledComponent
+ * @uses \PharIo\Manifest\BundledComponentCollection
+ * @uses \PharIo\Manifest\CopyrightInformation
+ * @uses \PharIo\Manifest\Email
+ * @uses \PharIo\Manifest\License
+ * @uses \PharIo\Manifest\RequirementCollection
+ * @uses \PharIo\Manifest\PhpVersionRequirement
+ * @uses \PharIo\Manifest\Type
+ * @uses \PharIo\Manifest\Application
+ * @uses \PharIo\Manifest\Url
+ * @uses \PharIo\Version\Version
+ * @uses \PharIo\Version\VersionConstraint
+ */
+class ManifestTest extends TestCase {
+ /**
+ * @var ApplicationName
+ */
+ private $name;
+
+ /**
+ * @var Version
+ */
+ private $version;
+
+ /**
+ * @var Type
+ */
+ private $type;
+
+ /**
+ * @var CopyrightInformation
+ */
+ private $copyrightInformation;
+
+ /**
+ * @var RequirementCollection
+ */
+ private $requirements;
+
+ /**
+ * @var BundledComponentCollection
+ */
+ private $bundledComponents;
+
+ /**
+ * @var Manifest
+ */
+ private $manifest;
+
+ protected function setUp() {
+ $this->version = new Version('5.6.5');
+
+ $this->type = Type::application();
+
+ $author = new Author('Joe Developer', new Email('user@example.com'));
+ $license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE'));
+
+ $authors = new AuthorCollection;
+ $authors->add($author);
+
+ $this->copyrightInformation = new CopyrightInformation($authors, $license);
+
+ $this->requirements = new RequirementCollection;
+ $this->requirements->add(new PhpVersionRequirement(new AnyVersionConstraint));
+
+ $this->bundledComponents = new BundledComponentCollection;
+ $this->bundledComponents->add(new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2')));
+
+ $this->name = new ApplicationName('phpunit/phpunit');
+
+ $this->manifest = new Manifest(
+ $this->name,
+ $this->version,
+ $this->type,
+ $this->copyrightInformation,
+ $this->requirements,
+ $this->bundledComponents
+ );
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(Manifest::class, $this->manifest);
+ }
+
+ public function testNameCanBeRetrieved() {
+ $this->assertEquals($this->name, $this->manifest->getName());
+ }
+
+ public function testVersionCanBeRetrieved() {
+ $this->assertEquals($this->version, $this->manifest->getVersion());
+ }
+
+ public function testTypeCanBeRetrieved() {
+ $this->assertEquals($this->type, $this->manifest->getType());
+ }
+
+ public function testTypeCanBeQueried() {
+ $this->assertTrue($this->manifest->isApplication());
+ $this->assertFalse($this->manifest->isLibrary());
+ $this->assertFalse($this->manifest->isExtension());
+ }
+
+ public function testCopyrightInformationCanBeRetrieved() {
+ $this->assertEquals($this->copyrightInformation, $this->manifest->getCopyrightInformation());
+ }
+
+ public function testRequirementsCanBeRetrieved() {
+ $this->assertEquals($this->requirements, $this->manifest->getRequirements());
+ }
+
+ public function testBundledComponentsCanBeRetrieved() {
+ $this->assertEquals($this->bundledComponents, $this->manifest->getBundledComponents());
+ }
+
+ /**
+ * @uses \PharIo\Manifest\Extension
+ */
+ public function testExtendedApplicationCanBeQueriedForExtension()
+ {
+ $appName = new ApplicationName('foo/bar');
+ $manifest = new Manifest(
+ new ApplicationName('foo/foo'),
+ new Version('1.0.0'),
+ Type::extension($appName, new AnyVersionConstraint),
+ $this->copyrightInformation,
+ new RequirementCollection,
+ new BundledComponentCollection
+ );
+
+ $this->assertTrue($manifest->isExtensionFor($appName));
+ }
+
+ public function testNonExtensionReturnsFalseWhenQueriesForExtension() {
+ $appName = new ApplicationName('foo/bar');
+ $manifest = new Manifest(
+ new ApplicationName('foo/foo'),
+ new Version('1.0.0'),
+ Type::library(),
+ $this->copyrightInformation,
+ new RequirementCollection,
+ new BundledComponentCollection
+ );
+
+ $this->assertFalse($manifest->isExtensionFor($appName));
+ }
+
+ /**
+ * @uses \PharIo\Manifest\Extension
+ */
+ public function testExtendedApplicationCanBeQueriedForExtensionWithVersion()
+ {
+ $appName = new ApplicationName('foo/bar');
+ $manifest = new Manifest(
+ new ApplicationName('foo/foo'),
+ new Version('1.0.0'),
+ Type::extension($appName, new AnyVersionConstraint),
+ $this->copyrightInformation,
+ new RequirementCollection,
+ new BundledComponentCollection
+ );
+
+ $this->assertTrue($manifest->isExtensionFor($appName, new Version('1.2.3')));
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/values/PhpExtensionRequirementTest.php b/vendor/phar-io/manifest/tests/values/PhpExtensionRequirementTest.php
new file mode 100644
index 0000000..ae1c058
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/PhpExtensionRequirementTest.php
@@ -0,0 +1,26 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\PhpExtensionRequirement
+ */
+class PhpExtensionRequirementTest extends TestCase {
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(PhpExtensionRequirement::class, new PhpExtensionRequirement('dom'));
+ }
+
+ public function testCanBeUsedAsString() {
+ $this->assertEquals('dom', new PhpExtensionRequirement('dom'));
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/PhpVersionRequirementTest.php b/vendor/phar-io/manifest/tests/values/PhpVersionRequirementTest.php
new file mode 100644
index 0000000..67ac41a
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/PhpVersionRequirementTest.php
@@ -0,0 +1,38 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\ExactVersionConstraint;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\PhpVersionRequirement
+ *
+ * @uses \PharIo\Version\VersionConstraint
+ */
+class PhpVersionRequirementTest extends TestCase {
+ /**
+ * @var PhpVersionRequirement
+ */
+ private $requirement;
+
+ protected function setUp() {
+ $this->requirement = new PhpVersionRequirement(new ExactVersionConstraint('7.1.0'));
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(PhpVersionRequirement::class, $this->requirement);
+ }
+
+ public function testVersionConstraintCanBeRetrieved() {
+ $this->assertEquals('7.1.0', $this->requirement->getVersionConstraint()->asString());
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/values/RequirementCollectionTest.php b/vendor/phar-io/manifest/tests/values/RequirementCollectionTest.php
new file mode 100644
index 0000000..2afeb1a
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/RequirementCollectionTest.php
@@ -0,0 +1,63 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PharIo\Version\ExactVersionConstraint;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Manifest\RequirementCollection
+ * @covers \PharIo\Manifest\RequirementCollectionIterator
+ *
+ * @uses \PharIo\Manifest\PhpVersionRequirement
+ * @uses \PharIo\Version\VersionConstraint
+ */
+class RequirementCollectionTest extends TestCase {
+ /**
+ * @var RequirementCollection
+ */
+ private $collection;
+
+ /**
+ * @var Requirement
+ */
+ private $item;
+
+ protected function setUp() {
+ $this->collection = new RequirementCollection;
+ $this->item = new PhpVersionRequirement(new ExactVersionConstraint('7.1.0'));
+ }
+
+ public function testCanBeCreated() {
+ $this->assertInstanceOf(RequirementCollection::class, $this->collection);
+ }
+
+ public function testCanBeCounted() {
+ $this->collection->add($this->item);
+
+ $this->assertCount(1, $this->collection);
+ }
+
+ public function testCanBeIterated() {
+ $this->collection->add(new PhpVersionRequirement(new ExactVersionConstraint('5.6.0')));
+ $this->collection->add($this->item);
+
+ $this->assertContains($this->item, $this->collection);
+ }
+
+ public function testKeyPositionCanBeRetreived() {
+ $this->collection->add($this->item);
+ foreach($this->collection as $key => $item) {
+ $this->assertEquals(0, $key);
+ }
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/values/UrlTest.php b/vendor/phar-io/manifest/tests/values/UrlTest.php
new file mode 100644
index 0000000..20f09c1
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/values/UrlTest.php
@@ -0,0 +1,35 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Manifest;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers PharIo\Manifest\Url
+ */
+class UrlTest extends TestCase {
+ public function testCanBeCreatedForValidUrl() {
+ $this->assertInstanceOf(Url::class, new Url('https://phar.io/'));
+ }
+
+ public function testCanBeUsedAsString() {
+ $this->assertEquals('https://phar.io/', new Url('https://phar.io/'));
+ }
+
+ /**
+ * @covers PharIo\Manifest\InvalidUrlException
+ */
+ public function testCannotBeCreatedForInvalidUrl() {
+ $this->expectException(InvalidUrlException::class);
+
+ new Url('invalid');
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/xml/AuthorElementCollectionTest.php b/vendor/phar-io/manifest/tests/xml/AuthorElementCollectionTest.php
new file mode 100644
index 0000000..588558e
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/AuthorElementCollectionTest.php
@@ -0,0 +1,18 @@
+loadXML(' ');
+ $collection = new AuthorElementCollection($dom->childNodes);
+
+ foreach($collection as $authorElement) {
+ $this->assertInstanceOf(AuthorElement::class, $authorElement);
+ }
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/AuthorElementTest.php b/vendor/phar-io/manifest/tests/xml/AuthorElementTest.php
new file mode 100644
index 0000000..6fce1d4
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/AuthorElementTest.php
@@ -0,0 +1,25 @@
+loadXML(' ');
+ $this->author = new AuthorElement($dom->documentElement);
+ }
+
+ public function testNameCanBeRetrieved() {
+ $this->assertEquals('Reiner Zufall', $this->author->getName());
+ }
+
+ public function testEmailCanBeRetrieved() {
+ $this->assertEquals('reiner@zufall.de', $this->author->getEmail());
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/BundlesElementTest.php b/vendor/phar-io/manifest/tests/xml/BundlesElementTest.php
new file mode 100644
index 0000000..7872795
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/BundlesElementTest.php
@@ -0,0 +1,41 @@
+dom = new DOMDocument();
+ $this->dom->loadXML(' ');
+ $this->bundles = new BundlesElement($this->dom->documentElement);
+ }
+
+ public function testThrowsExceptionWhenGetComponentElementsIsCalledButNodesAreMissing() {
+ $this->expectException(ManifestElementException::class);
+ $this->bundles->getComponentElements();
+ }
+
+ public function testGetComponentElementsReturnsComponentElementCollection() {
+ $this->addComponent();
+ $this->assertInstanceOf(
+ ComponentElementCollection::class, $this->bundles->getComponentElements()
+ );
+ }
+
+ private function addComponent() {
+ $this->dom->documentElement->appendChild(
+ $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'component')
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/xml/ComponentElementCollectionTest.php b/vendor/phar-io/manifest/tests/xml/ComponentElementCollectionTest.php
new file mode 100644
index 0000000..9fe2378
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/ComponentElementCollectionTest.php
@@ -0,0 +1,18 @@
+loadXML(' ');
+ $collection = new ComponentElementCollection($dom->childNodes);
+
+ foreach($collection as $componentElement) {
+ $this->assertInstanceOf(ComponentElement::class, $componentElement);
+ }
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/ComponentElementTest.php b/vendor/phar-io/manifest/tests/xml/ComponentElementTest.php
new file mode 100644
index 0000000..1996585
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/ComponentElementTest.php
@@ -0,0 +1,25 @@
+loadXML(' ');
+ $this->component = new ComponentElement($dom->documentElement);
+ }
+
+ public function testNameCanBeRetrieved() {
+ $this->assertEquals('phar-io/phive', $this->component->getName());
+ }
+
+ public function testEmailCanBeRetrieved() {
+ $this->assertEquals('0.6.0', $this->component->getVersion());
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/ContainsElementTest.php b/vendor/phar-io/manifest/tests/xml/ContainsElementTest.php
new file mode 100644
index 0000000..ed08600
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/ContainsElementTest.php
@@ -0,0 +1,63 @@
+loadXML(' ');
+ $this->domElement = $dom->documentElement;
+ $this->contains = new ContainsElement($this->domElement);
+ }
+
+ public function testVersionCanBeRetrieved() {
+ $this->assertEquals('5.6.5', $this->contains->getVersion());
+ }
+
+ public function testThrowsExceptionWhenVersionAttributeIsMissing() {
+ $this->domElement->removeAttribute('version');
+ $this->expectException(ManifestElementException::class);
+ $this->contains->getVersion();
+ }
+
+ public function testNameCanBeRetrieved() {
+ $this->assertEquals('phpunit/phpunit', $this->contains->getName());
+ }
+
+ public function testThrowsExceptionWhenNameAttributeIsMissing() {
+ $this->domElement->removeAttribute('name');
+ $this->expectException(ManifestElementException::class);
+ $this->contains->getName();
+ }
+
+ public function testTypeCanBeRetrieved() {
+ $this->assertEquals('application', $this->contains->getType());
+ }
+
+ public function testThrowsExceptionWhenTypeAttributeIsMissing() {
+ $this->domElement->removeAttribute('type');
+ $this->expectException(ManifestElementException::class);
+ $this->contains->getType();
+ }
+
+ public function testGetExtensionElementReturnsExtensionElement() {
+ $this->domElement->appendChild(
+ $this->domElement->ownerDocument->createElementNS('https://phar.io/xml/manifest/1.0', 'extension')
+ );
+ $this->assertInstanceOf(ExtensionElement::class, $this->contains->getExtensionElement());
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/CopyrightElementTest.php b/vendor/phar-io/manifest/tests/xml/CopyrightElementTest.php
new file mode 100644
index 0000000..c74a2ce
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/CopyrightElementTest.php
@@ -0,0 +1,52 @@
+dom = new DOMDocument();
+ $this->dom->loadXML(' ');
+ $this->copyright = new CopyrightElement($this->dom->documentElement);
+ }
+
+ public function testThrowsExceptionWhenGetAuthroElementsIsCalledButNodesAreMissing() {
+ $this->expectException(ManifestElementException::class);
+ $this->copyright->getAuthorElements();
+ }
+
+ public function testThrowsExceptionWhenGetLicenseElementIsCalledButNodeIsMissing() {
+ $this->expectException(ManifestElementException::class);
+ $this->copyright->getLicenseElement();
+ }
+
+ public function testGetAuthorElementsReturnsAuthorElementCollection() {
+ $this->dom->documentElement->appendChild(
+ $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'author')
+ );
+ $this->assertInstanceOf(
+ AuthorElementCollection::class, $this->copyright->getAuthorElements()
+ );
+ }
+
+ public function testGetLicenseElementReturnsLicenseElement() {
+ $this->dom->documentElement->appendChild(
+ $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'license')
+ );
+ $this->assertInstanceOf(
+ LicenseElement::class, $this->copyright->getLicenseElement()
+ );
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/ExtElementCollectionTest.php b/vendor/phar-io/manifest/tests/xml/ExtElementCollectionTest.php
new file mode 100644
index 0000000..7a456d2
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/ExtElementCollectionTest.php
@@ -0,0 +1,19 @@
+loadXML(' ');
+ $collection = new ExtElementCollection($dom->childNodes);
+
+ foreach($collection as $position => $extElement) {
+ $this->assertInstanceOf(ExtElement::class, $extElement);
+ $this->assertEquals(0, $position);
+ }
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/ExtElementTest.php b/vendor/phar-io/manifest/tests/xml/ExtElementTest.php
new file mode 100644
index 0000000..db6ecbc
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/ExtElementTest.php
@@ -0,0 +1,21 @@
+loadXML(' ');
+ $this->ext = new ExtElement($dom->documentElement);
+ }
+
+ public function testNameCanBeRetrieved() {
+ $this->assertEquals('dom', $this->ext->getName());
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/ExtensionElementTest.php b/vendor/phar-io/manifest/tests/xml/ExtensionElementTest.php
new file mode 100644
index 0000000..58965d8
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/ExtensionElementTest.php
@@ -0,0 +1,25 @@
+loadXML(' ');
+ $this->extension = new ExtensionElement($dom->documentElement);
+ }
+
+ public function testNForCanBeRetrieved() {
+ $this->assertEquals('phar-io/phive', $this->extension->getFor());
+ }
+
+ public function testCompatibleVersionConstraintCanBeRetrieved() {
+ $this->assertEquals('~0.6', $this->extension->getCompatible());
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/LicenseElementTest.php b/vendor/phar-io/manifest/tests/xml/LicenseElementTest.php
new file mode 100644
index 0000000..5b1ffcb
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/LicenseElementTest.php
@@ -0,0 +1,25 @@
+loadXML(' ');
+ $this->license = new LicenseElement($dom->documentElement);
+ }
+
+ public function testTypeCanBeRetrieved() {
+ $this->assertEquals('BSD-3', $this->license->getType());
+ }
+
+ public function testUrlCanBeRetrieved() {
+ $this->assertEquals('https://some.tld/LICENSE', $this->license->getUrl());
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/ManifestDocumentTest.php b/vendor/phar-io/manifest/tests/xml/ManifestDocumentTest.php
new file mode 100644
index 0000000..3dd59bf
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/ManifestDocumentTest.php
@@ -0,0 +1,110 @@
+expectException(ManifestDocumentException::class);
+ ManifestDocument::fromFile('/does/not/exist');
+ }
+
+ public function testCanBeCreatedFromFile() {
+ $this->assertInstanceOf(
+ ManifestDocument::class,
+ ManifestDocument::fromFile(__DIR__ . '/../_fixture/phpunit-5.6.5.xml')
+ );
+ }
+
+ public function testCaneBeConstructedFromString() {
+ $content = file_get_contents(__DIR__ . '/../_fixture/phpunit-5.6.5.xml');
+ $this->assertInstanceOf(
+ ManifestDocument::class,
+ ManifestDocument::fromString($content)
+ );
+ }
+
+ public function testThrowsExceptionOnInvalidXML() {
+ $this->expectException(ManifestDocumentLoadingException::class);
+ ManifestDocument::fromString('');
+ }
+
+ public function testLoadingDocumentWithWrongRootNameThrowsException() {
+ $this->expectException(ManifestDocumentException::class);
+ ManifestDocument::fromString(' ');
+ }
+
+ public function testLoadingDocumentWithWrongNamespaceThrowsException() {
+ $this->expectException(ManifestDocumentException::class);
+ ManifestDocument::fromString(' ');
+ }
+
+ public function testContainsElementCanBeRetrieved() {
+ $this->assertInstanceOf(
+ ContainsElement::class,
+ $this->loadFixture()->getContainsElement()
+ );
+ }
+
+ public function testRequiresElementCanBeRetrieved() {
+ $this->assertInstanceOf(
+ RequiresElement::class,
+ $this->loadFixture()->getRequiresElement()
+ );
+ }
+
+ public function testCopyrightElementCanBeRetrieved() {
+ $this->assertInstanceOf(
+ CopyrightElement::class,
+ $this->loadFixture()->getCopyrightElement()
+ );
+ }
+
+ public function testBundlesElementCanBeRetrieved() {
+ $this->assertInstanceOf(
+ BundlesElement::class,
+ $this->loadFixture()->getBundlesElement()
+ );
+ }
+
+ public function testThrowsExceptionWhenContainsIsMissing() {
+ $this->expectException(ManifestDocumentException::class);
+ $this->loadEmptyFixture()->getContainsElement();
+ }
+
+ public function testThrowsExceptionWhenCopyirhgtIsMissing() {
+ $this->expectException(ManifestDocumentException::class);
+ $this->loadEmptyFixture()->getCopyrightElement();
+ }
+
+ public function testThrowsExceptionWhenRequiresIsMissing() {
+ $this->expectException(ManifestDocumentException::class);
+ $this->loadEmptyFixture()->getRequiresElement();
+ }
+
+ public function testThrowsExceptionWhenBundlesIsMissing() {
+ $this->expectException(ManifestDocumentException::class);
+ $this->loadEmptyFixture()->getBundlesElement();
+ }
+
+ public function testHasBundlesReturnsTrueWhenBundlesNodeIsPresent() {
+ $this->assertTrue(
+ $this->loadFixture()->hasBundlesElement()
+ );
+ }
+
+ public function testHasBundlesReturnsFalseWhenBundlesNoNodeIsPresent() {
+ $this->assertFalse(
+ $this->loadEmptyFixture()->hasBundlesElement()
+ );
+ }
+
+ private function loadFixture() {
+ return ManifestDocument::fromFile(__DIR__ . '/../_fixture/phpunit-5.6.5.xml');
+ }
+
+ private function loadEmptyFixture() {
+ return ManifestDocument::fromString(
+ ' '
+ );
+ }
+}
diff --git a/vendor/phar-io/manifest/tests/xml/PhpElementTest.php b/vendor/phar-io/manifest/tests/xml/PhpElementTest.php
new file mode 100644
index 0000000..62dd359
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/PhpElementTest.php
@@ -0,0 +1,48 @@
+dom = new DOMDocument();
+ $this->dom->loadXML(' ');
+ $this->php = new PhpElement($this->dom->documentElement);
+ }
+
+ public function testVersionConstraintCanBeRetrieved() {
+ $this->assertEquals('^5.6 || ^7.0', $this->php->getVersion());
+ }
+
+ public function testHasExtElementsReturnsFalseWhenNoExtensionsAreRequired() {
+ $this->assertFalse($this->php->hasExtElements());
+ }
+
+ public function testHasExtElementsReturnsTrueWhenExtensionsAreRequired() {
+ $this->addExtElement();
+ $this->assertTrue($this->php->hasExtElements());
+ }
+
+ public function testGetExtElementsReturnsExtElementCollection() {
+ $this->addExtElement();
+ $this->assertInstanceOf(ExtElementCollection::class, $this->php->getExtElements());
+ }
+
+ private function addExtElement() {
+ $this->dom->documentElement->appendChild(
+ $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'ext')
+ );
+ }
+
+}
diff --git a/vendor/phar-io/manifest/tests/xml/RequiresElementTest.php b/vendor/phar-io/manifest/tests/xml/RequiresElementTest.php
new file mode 100644
index 0000000..35ddc82
--- /dev/null
+++ b/vendor/phar-io/manifest/tests/xml/RequiresElementTest.php
@@ -0,0 +1,37 @@
+dom = new DOMDocument();
+ $this->dom->loadXML(' ');
+ $this->requires = new RequiresElement($this->dom->documentElement);
+ }
+
+ public function testThrowsExceptionWhenGetPhpElementIsCalledButElementIsMissing() {
+ $this->expectException(ManifestElementException::class);
+ $this->requires->getPHPElement();
+ }
+
+ public function testHasExtElementsReturnsTrueWhenExtensionsAreRequired() {
+ $this->dom->documentElement->appendChild(
+ $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'php')
+ );
+
+ $this->assertInstanceOf(PhpElement::class, $this->requires->getPHPElement());
+ }
+
+}
diff --git a/vendor/phar-io/version/.gitignore b/vendor/phar-io/version/.gitignore
new file mode 100644
index 0000000..1c8f2e6
--- /dev/null
+++ b/vendor/phar-io/version/.gitignore
@@ -0,0 +1,7 @@
+/.idea
+/.php_cs.cache
+/composer.lock
+/src/autoload.php
+/tools
+/vendor
+
diff --git a/vendor/phar-io/version/.php_cs b/vendor/phar-io/version/.php_cs
new file mode 100644
index 0000000..159d6a3
--- /dev/null
+++ b/vendor/phar-io/version/.php_cs
@@ -0,0 +1,67 @@
+files()
+ ->in('src')
+ ->in('tests')
+ ->name('*.php');
+
+return Symfony\CS\Config\Config::create()
+ ->setUsingCache(true)
+ ->level(\Symfony\CS\FixerInterface::NONE_LEVEL)
+ ->fixers(
+ array(
+ 'align_double_arrow',
+ 'align_equals',
+ 'concat_with_spaces',
+ 'duplicate_semicolon',
+ 'elseif',
+ 'empty_return',
+ 'encoding',
+ 'eof_ending',
+ 'extra_empty_lines',
+ 'function_call_space',
+ 'function_declaration',
+ 'indentation',
+ 'join_function',
+ 'line_after_namespace',
+ 'linefeed',
+ 'list_commas',
+ 'lowercase_constants',
+ 'lowercase_keywords',
+ 'method_argument_space',
+ 'multiple_use',
+ 'namespace_no_leading_whitespace',
+ 'no_blank_lines_after_class_opening',
+ 'no_empty_lines_after_phpdocs',
+ 'parenthesis',
+ 'php_closing_tag',
+ 'phpdoc_indent',
+ 'phpdoc_no_access',
+ 'phpdoc_no_empty_return',
+ 'phpdoc_no_package',
+ 'phpdoc_params',
+ 'phpdoc_scalar',
+ 'phpdoc_separation',
+ 'phpdoc_to_comment',
+ 'phpdoc_trim',
+ 'phpdoc_types',
+ 'phpdoc_var_without_name',
+ 'remove_lines_between_uses',
+ 'return',
+ 'self_accessor',
+ 'short_array_syntax',
+ 'short_tag',
+ 'single_line_after_imports',
+ 'single_quote',
+ 'spaces_before_semicolon',
+ 'spaces_cast',
+ 'ternary_spaces',
+ 'trailing_spaces',
+ 'trim_array_spaces',
+ 'unused_use',
+ 'visibility',
+ 'whitespacy_lines'
+ )
+ )
+ ->finder($finder);
+
diff --git a/vendor/phar-io/version/.travis.yml b/vendor/phar-io/version/.travis.yml
new file mode 100644
index 0000000..b4be10f
--- /dev/null
+++ b/vendor/phar-io/version/.travis.yml
@@ -0,0 +1,33 @@
+os:
+- linux
+
+language: php
+
+before_install:
+ - wget https://phar.io/releases/phive.phar
+ - wget https://phar.io/releases/phive.phar.asc
+ - gpg --keyserver hkps.pool.sks-keyservers.net --recv-keys 0x9B2D5D79
+ - gpg --verify phive.phar.asc phive.phar
+ - chmod +x phive.phar
+ - sudo mv phive.phar /usr/bin/phive
+
+install:
+ - ant setup
+
+script: ./tools/phpunit
+
+php:
+ - 5.6
+ - 7.0
+ - 7.1
+ - 7.0snapshot
+ - 7.1snapshot
+ - master
+
+matrix:
+ allow_failures:
+ - php: master
+ fast_finish: true
+
+notifications:
+ email: false
diff --git a/vendor/phar-io/version/CHANGELOG.md b/vendor/phar-io/version/CHANGELOG.md
new file mode 100644
index 0000000..ab9df36
--- /dev/null
+++ b/vendor/phar-io/version/CHANGELOG.md
@@ -0,0 +1,44 @@
+# Changelog
+
+All notable changes to phar-io/version are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [2.0.1] - 08.07.2018
+
+### Fixed
+
+- Versions without a pre-release suffix are now always considered greater
+than versions without a pre-release suffix. Example: `3.0.0 > 3.0.0-alpha.1`
+
+## [2.0.0] - 23.06.2018
+
+Changes to public API:
+
+- `PreReleaseSuffix::construct()`: optional parameter `$number` removed
+- `PreReleaseSuffix::isGreaterThan()`: introduced
+- `Version::hasPreReleaseSuffix()`: introduced
+
+### Added
+
+- [#11](https://github.com/phar-io/version/issues/11): Added support for pre-release version suffixes. Supported values are:
+ - `dev`
+ - `beta` (also abbreviated form `b`)
+ - `rc`
+ - `alpha` (also abbreviated form `a`)
+ - `patch` (also abbreviated form `p`)
+
+ All values can be followed by a number, e.g. `beta3`.
+
+ When comparing versions, the pre-release suffix is taken into account. Example:
+`1.5.0 > 1.5.0-beta1 > 1.5.0-alpha3 > 1.5.0-alpha2 > 1.5.0-dev11`
+
+### Changed
+
+- reorganized the source directories
+
+### Fixed
+
+- [#10](https://github.com/phar-io/version/issues/10): Version numbers containing
+a numeric suffix as seen in Debian packages are now supported.
+
+[2.0.1]: https://github.com/phar-io/version/compare/2.0.0...2.0.1
+[2.0.0]: https://github.com/phar-io/version/compare/1.0.1...2.0.0
diff --git a/vendor/phar-io/version/LICENSE b/vendor/phar-io/version/LICENSE
new file mode 100644
index 0000000..359dbc5
--- /dev/null
+++ b/vendor/phar-io/version/LICENSE
@@ -0,0 +1,31 @@
+phar-io/version
+
+Copyright (c) 2016-2017 Arne Blankerts , Sebastian Heuer and contributors
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of Arne Blankerts nor the names of contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/vendor/phar-io/version/README.md b/vendor/phar-io/version/README.md
new file mode 100644
index 0000000..76e6e98
--- /dev/null
+++ b/vendor/phar-io/version/README.md
@@ -0,0 +1,61 @@
+# Version
+
+Library for handling version information and constraints
+
+[![Build Status](https://travis-ci.org/phar-io/version.svg?branch=master)](https://travis-ci.org/phar-io/version)
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+ composer require phar-io/version
+
+If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:
+
+ composer require --dev phar-io/version
+
+## Version constraints
+
+A Version constraint describes a range of versions or a discrete version number. The format of version numbers follows the schema of [semantic versioning](http://semver.org): `..`. A constraint might contain an operator that describes the range.
+
+Beside the typical mathematical operators like `<=`, `>=`, there are two special operators:
+
+*Caret operator*: `^1.0`
+can be written as `>=1.0.0 <2.0.0` and read as »every Version within major version `1`«.
+
+*Tilde operator*: `~1.0.0`
+can be written as `>=1.0.0 <1.1.0` and read as »every version within minor version `1.1`. The behavior of tilde operator depends on whether a patch level version is provided or not. If no patch level is provided, tilde operator behaves like the caret operator: `~1.0` is identical to `^1.0`.
+
+## Usage examples
+
+Parsing version constraints and check discrete versions for compliance:
+
+```php
+
+use PharIo\Version\Version;
+use PharIo\Version\VersionConstraintParser;
+
+$parser = new VersionConstraintParser();
+$caret_constraint = $parser->parse( '^7.0' );
+
+$caret_constraint->complies( new Version( '7.0.17' ) ); // true
+$caret_constraint->complies( new Version( '7.1.0' ) ); // true
+$caret_constraint->complies( new Version( '6.4.34' ) ); // false
+
+$tilde_constraint = $parser->parse( '~1.1.0' );
+
+$tilde_constraint->complies( new Version( '1.1.4' ) ); // true
+$tilde_constraint->complies( new Version( '1.2.0' ) ); // false
+```
+
+As of version 2.0.0, pre-release labels are supported and taken into account when comparing versions:
+
+```php
+
+$leftVersion = new PharIo\Version\Version('3.0.0-alpha.1');
+$rightVersion = new PharIo\Version\Version('3.0.0-alpha.2');
+
+$leftVersion->isGreaterThan($rightVersion); // false
+$rightVersion->isGreaterThan($leftVersion); // true
+
+```
diff --git a/vendor/phar-io/version/build.xml b/vendor/phar-io/version/build.xml
new file mode 100644
index 0000000..943c957
--- /dev/null
+++ b/vendor/phar-io/version/build.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phar-io/version/composer.json b/vendor/phar-io/version/composer.json
new file mode 100644
index 0000000..891e8b1
--- /dev/null
+++ b/vendor/phar-io/version/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "phar-io/version",
+ "description": "Library for handling version information and constraints",
+ "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"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/phar-io/version/issues"
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ }
+}
+
diff --git a/vendor/phar-io/version/phive.xml b/vendor/phar-io/version/phive.xml
new file mode 100644
index 0000000..0c3bc6f
--- /dev/null
+++ b/vendor/phar-io/version/phive.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/vendor/phar-io/version/phpunit.xml b/vendor/phar-io/version/phpunit.xml
new file mode 100644
index 0000000..c21ffbc
--- /dev/null
+++ b/vendor/phar-io/version/phpunit.xml
@@ -0,0 +1,19 @@
+
+
+
+ tests
+
+
+
+
+ src
+
+
+
diff --git a/vendor/phar-io/version/src/PreReleaseSuffix.php b/vendor/phar-io/version/src/PreReleaseSuffix.php
new file mode 100644
index 0000000..e936c0e
--- /dev/null
+++ b/vendor/phar-io/version/src/PreReleaseSuffix.php
@@ -0,0 +1,95 @@
+ 0,
+ 'a' => 1,
+ 'alpha' => 1,
+ 'b' => 2,
+ 'beta' => 2,
+ 'rc' => 3,
+ 'p' => 4,
+ 'patch' => 4,
+ ];
+
+ /**
+ * @var string
+ */
+ private $value;
+
+ /**
+ * @var int
+ */
+ private $valueScore;
+
+ /**
+ * @var int
+ */
+ private $number = 0;
+
+ /**
+ * @param string $value
+ */
+ public function __construct($value) {
+ $this->parseValue($value);
+ }
+
+ /**
+ * @return string
+ */
+ public function getValue() {
+ return $this->value;
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getNumber() {
+ return $this->number;
+ }
+
+ /**
+ * @param PreReleaseSuffix $suffix
+ *
+ * @return bool
+ */
+ public function isGreaterThan(PreReleaseSuffix $suffix) {
+ if ($this->valueScore > $suffix->valueScore) {
+ return true;
+ }
+
+ if ($this->valueScore < $suffix->valueScore) {
+ return false;
+ }
+
+ return $this->getNumber() > $suffix->getNumber();
+ }
+
+ /**
+ * @param $value
+ *
+ * @return int
+ */
+ private function mapValueToScore($value) {
+ if (array_key_exists($value, $this->valueScoreMap)) {
+ return $this->valueScoreMap[$value];
+ }
+
+ return 0;
+ }
+
+ private function parseValue($value) {
+ $regex = '/-?(dev|beta|b|rc|alpha|a|patch|p)\.?(\d*).*$/i';
+ if (preg_match($regex, $value, $matches) !== 1) {
+ throw new InvalidPreReleaseSuffixException(sprintf('Invalid label %s', $value));
+ }
+
+ $this->value = $matches[1];
+ if (isset($matches[2])) {
+ $this->number = (int)$matches[2];
+ }
+ $this->valueScore = $this->mapValueToScore($this->value);
+ }
+}
diff --git a/vendor/phar-io/version/src/Version.php b/vendor/phar-io/version/src/Version.php
new file mode 100644
index 0000000..73e1b98
--- /dev/null
+++ b/vendor/phar-io/version/src/Version.php
@@ -0,0 +1,175 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class Version {
+ /**
+ * @var VersionNumber
+ */
+ private $major;
+
+ /**
+ * @var VersionNumber
+ */
+ private $minor;
+
+ /**
+ * @var VersionNumber
+ */
+ private $patch;
+
+ /**
+ * @var PreReleaseSuffix
+ */
+ private $preReleaseSuffix;
+
+ /**
+ * @var string
+ */
+ private $versionString = '';
+
+ /**
+ * @param string $versionString
+ */
+ public function __construct($versionString) {
+ $this->ensureVersionStringIsValid($versionString);
+
+ $this->versionString = $versionString;
+ }
+
+ /**
+ * @return PreReleaseSuffix
+ */
+ public function getPreReleaseSuffix() {
+ return $this->preReleaseSuffix;
+ }
+
+ /**
+ * @return string
+ */
+ public function getVersionString() {
+ return $this->versionString;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasPreReleaseSuffix() {
+ return $this->preReleaseSuffix !== null;
+ }
+
+ /**
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function isGreaterThan(Version $version) {
+ if ($version->getMajor()->getValue() > $this->getMajor()->getValue()) {
+ return false;
+ }
+
+ if ($version->getMajor()->getValue() < $this->getMajor()->getValue()) {
+ return true;
+ }
+
+ if ($version->getMinor()->getValue() > $this->getMinor()->getValue()) {
+ return false;
+ }
+
+ if ($version->getMinor()->getValue() < $this->getMinor()->getValue()) {
+ return true;
+ }
+
+ if ($version->getPatch()->getValue() > $this->getPatch()->getValue()) {
+ return false;
+ }
+
+ if ($version->getPatch()->getValue() < $this->getPatch()->getValue()) {
+ return true;
+ }
+
+ if (!$version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) {
+ return false;
+ }
+
+ if ($version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) {
+ return true;
+ }
+
+ if (!$version->hasPreReleaseSuffix() && $this->hasPreReleaseSuffix()) {
+ return false;
+ }
+
+ return $this->getPreReleaseSuffix()->isGreaterThan($version->getPreReleaseSuffix());
+ }
+
+ /**
+ * @return VersionNumber
+ */
+ public function getMajor() {
+ return $this->major;
+ }
+
+ /**
+ * @return VersionNumber
+ */
+ public function getMinor() {
+ return $this->minor;
+ }
+
+ /**
+ * @return VersionNumber
+ */
+ public function getPatch() {
+ return $this->patch;
+ }
+
+ /**
+ * @param array $matches
+ */
+ private function parseVersion(array $matches) {
+ $this->major = new VersionNumber($matches['Major']);
+ $this->minor = new VersionNumber($matches['Minor']);
+ $this->patch = isset($matches['Patch']) ? new VersionNumber($matches['Patch']) : new VersionNumber(null);
+
+ if (isset($matches['PreReleaseSuffix'])) {
+ $this->preReleaseSuffix = new PreReleaseSuffix($matches['PreReleaseSuffix']);
+ }
+ }
+
+ /**
+ * @param string $version
+ *
+ * @throws InvalidVersionException
+ */
+ private function ensureVersionStringIsValid($version) {
+ $regex = '/^v?
+ (?(0|(?:[1-9][0-9]*)))
+ \\.
+ (?(0|(?:[1-9][0-9]*)))
+ (\\.
+ (?(0|(?:[1-9][0-9]*)))
+ )?
+ (?:
+ -
+ (?(?:(dev|beta|b|RC|alpha|a|patch|p)\.?\d*))
+ )?
+ $/x';
+
+ if (preg_match($regex, $version, $matches) !== 1) {
+ throw new InvalidVersionException(
+ sprintf("Version string '%s' does not follow SemVer semantics", $version)
+ );
+ }
+
+ $this->parseVersion($matches);
+ }
+}
diff --git a/vendor/phar-io/version/src/VersionConstraintParser.php b/vendor/phar-io/version/src/VersionConstraintParser.php
new file mode 100644
index 0000000..ed46843
--- /dev/null
+++ b/vendor/phar-io/version/src/VersionConstraintParser.php
@@ -0,0 +1,122 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class VersionConstraintParser {
+ /**
+ * @param string $value
+ *
+ * @return VersionConstraint
+ *
+ * @throws UnsupportedVersionConstraintException
+ */
+ public function parse($value) {
+
+ if (strpos($value, '||') !== false) {
+ return $this->handleOrGroup($value);
+ }
+
+ if (!preg_match('/^[\^~\*]?[\d.\*]+(?:-.*)?$/', $value)) {
+ throw new UnsupportedVersionConstraintException(
+ sprintf('Version constraint %s is not supported.', $value)
+ );
+ }
+
+ switch ($value[0]) {
+ case '~':
+ return $this->handleTildeOperator($value);
+ case '^':
+ return $this->handleCaretOperator($value);
+ }
+
+ $version = new VersionConstraintValue($value);
+
+ if ($version->getMajor()->isAny()) {
+ return new AnyVersionConstraint();
+ }
+
+ if ($version->getMinor()->isAny()) {
+ return new SpecificMajorVersionConstraint(
+ $version->getVersionString(),
+ $version->getMajor()->getValue()
+ );
+ }
+
+ if ($version->getPatch()->isAny()) {
+ return new SpecificMajorAndMinorVersionConstraint(
+ $version->getVersionString(),
+ $version->getMajor()->getValue(),
+ $version->getMinor()->getValue()
+ );
+ }
+
+ return new ExactVersionConstraint($version->getVersionString());
+ }
+
+ /**
+ * @param $value
+ *
+ * @return OrVersionConstraintGroup
+ */
+ private function handleOrGroup($value) {
+ $constraints = [];
+
+ foreach (explode('||', $value) as $groupSegment) {
+ $constraints[] = $this->parse(trim($groupSegment));
+ }
+
+ return new OrVersionConstraintGroup($value, $constraints);
+ }
+
+ /**
+ * @param string $value
+ *
+ * @return AndVersionConstraintGroup
+ */
+ private function handleTildeOperator($value) {
+ $version = new Version(substr($value, 1));
+ $constraints = [
+ new GreaterThanOrEqualToVersionConstraint($value, $version)
+ ];
+
+ if ($version->getPatch()->isAny()) {
+ $constraints[] = new SpecificMajorVersionConstraint(
+ $value,
+ $version->getMajor()->getValue()
+ );
+ } else {
+ $constraints[] = new SpecificMajorAndMinorVersionConstraint(
+ $value,
+ $version->getMajor()->getValue(),
+ $version->getMinor()->getValue()
+ );
+ }
+
+ return new AndVersionConstraintGroup($value, $constraints);
+ }
+
+ /**
+ * @param string $value
+ *
+ * @return AndVersionConstraintGroup
+ */
+ private function handleCaretOperator($value) {
+ $version = new Version(substr($value, 1));
+
+ return new AndVersionConstraintGroup(
+ $value,
+ [
+ new GreaterThanOrEqualToVersionConstraint($value, $version),
+ new SpecificMajorVersionConstraint($value, $version->getMajor()->getValue())
+ ]
+ );
+ }
+}
diff --git a/vendor/phar-io/version/src/VersionConstraintValue.php b/vendor/phar-io/version/src/VersionConstraintValue.php
new file mode 100644
index 0000000..8c975b8
--- /dev/null
+++ b/vendor/phar-io/version/src/VersionConstraintValue.php
@@ -0,0 +1,123 @@
+versionString = $versionString;
+
+ $this->parseVersion($versionString);
+ }
+
+ /**
+ * @return string
+ */
+ public function getLabel() {
+ return $this->label;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBuildMetaData() {
+ return $this->buildMetaData;
+ }
+
+ /**
+ * @return string
+ */
+ public function getVersionString() {
+ return $this->versionString;
+ }
+
+ /**
+ * @return VersionNumber
+ */
+ public function getMajor() {
+ return $this->major;
+ }
+
+ /**
+ * @return VersionNumber
+ */
+ public function getMinor() {
+ return $this->minor;
+ }
+
+ /**
+ * @return VersionNumber
+ */
+ public function getPatch() {
+ return $this->patch;
+ }
+
+ /**
+ * @param $versionString
+ */
+ private function parseVersion($versionString) {
+ $this->extractBuildMetaData($versionString);
+ $this->extractLabel($versionString);
+
+ $versionSegments = explode('.', $versionString);
+ $this->major = new VersionNumber($versionSegments[0]);
+
+ $minorValue = isset($versionSegments[1]) ? $versionSegments[1] : null;
+ $patchValue = isset($versionSegments[2]) ? $versionSegments[2] : null;
+
+ $this->minor = new VersionNumber($minorValue);
+ $this->patch = new VersionNumber($patchValue);
+ }
+
+ /**
+ * @param string $versionString
+ */
+ private function extractBuildMetaData(&$versionString) {
+ if (preg_match('/\+(.*)/', $versionString, $matches) == 1) {
+ $this->buildMetaData = $matches[1];
+ $versionString = str_replace($matches[0], '', $versionString);
+ }
+ }
+
+ /**
+ * @param string $versionString
+ */
+ private function extractLabel(&$versionString) {
+ if (preg_match('/\-(.*)/', $versionString, $matches) == 1) {
+ $this->label = $matches[1];
+ $versionString = str_replace($matches[0], '', $versionString);
+ }
+ }
+}
diff --git a/vendor/phar-io/version/src/VersionNumber.php b/vendor/phar-io/version/src/VersionNumber.php
new file mode 100644
index 0000000..ab512ed
--- /dev/null
+++ b/vendor/phar-io/version/src/VersionNumber.php
@@ -0,0 +1,41 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class VersionNumber {
+ /**
+ * @var int
+ */
+ private $value;
+
+ /**
+ * @param mixed $value
+ */
+ public function __construct($value) {
+ if (is_numeric($value)) {
+ $this->value = $value;
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ public function isAny() {
+ return $this->value === null;
+ }
+
+ /**
+ * @return int
+ */
+ public function getValue() {
+ return $this->value;
+ }
+}
diff --git a/vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php b/vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php
new file mode 100644
index 0000000..b732dbc
--- /dev/null
+++ b/vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php
@@ -0,0 +1,32 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+abstract class AbstractVersionConstraint implements VersionConstraint {
+ /**
+ * @var string
+ */
+ private $originalValue = '';
+
+ /**
+ * @param string $originalValue
+ */
+ public function __construct($originalValue) {
+ $this->originalValue = $originalValue;
+ }
+
+ /**
+ * @return string
+ */
+ public function asString() {
+ return $this->originalValue;
+ }
+}
diff --git a/vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php b/vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php
new file mode 100644
index 0000000..d9efeef
--- /dev/null
+++ b/vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php
@@ -0,0 +1,43 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class AndVersionConstraintGroup extends AbstractVersionConstraint {
+ /**
+ * @var VersionConstraint[]
+ */
+ private $constraints = [];
+
+ /**
+ * @param string $originalValue
+ * @param VersionConstraint[] $constraints
+ */
+ public function __construct($originalValue, array $constraints) {
+ parent::__construct($originalValue);
+
+ $this->constraints = $constraints;
+ }
+
+ /**
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function complies(Version $version) {
+ foreach ($this->constraints as $constraint) {
+ if (!$constraint->complies($version)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/phar-io/version/src/constraints/AnyVersionConstraint.php b/vendor/phar-io/version/src/constraints/AnyVersionConstraint.php
new file mode 100644
index 0000000..13ca2ef
--- /dev/null
+++ b/vendor/phar-io/version/src/constraints/AnyVersionConstraint.php
@@ -0,0 +1,29 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class AnyVersionConstraint implements VersionConstraint {
+ /**
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function complies(Version $version) {
+ return true;
+ }
+
+ /**
+ * @return string
+ */
+ public function asString() {
+ return '*';
+ }
+}
diff --git a/vendor/phar-io/version/src/constraints/ExactVersionConstraint.php b/vendor/phar-io/version/src/constraints/ExactVersionConstraint.php
new file mode 100644
index 0000000..b214117
--- /dev/null
+++ b/vendor/phar-io/version/src/constraints/ExactVersionConstraint.php
@@ -0,0 +1,22 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class ExactVersionConstraint extends AbstractVersionConstraint {
+ /**
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function complies(Version $version) {
+ return $this->asString() == $version->getVersionString();
+ }
+}
diff --git a/vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php b/vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php
new file mode 100644
index 0000000..47039a8
--- /dev/null
+++ b/vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php
@@ -0,0 +1,38 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class GreaterThanOrEqualToVersionConstraint extends AbstractVersionConstraint {
+ /**
+ * @var Version
+ */
+ private $minimalVersion;
+
+ /**
+ * @param string $originalValue
+ * @param Version $minimalVersion
+ */
+ public function __construct($originalValue, Version $minimalVersion) {
+ parent::__construct($originalValue);
+
+ $this->minimalVersion = $minimalVersion;
+ }
+
+ /**
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function complies(Version $version) {
+ return $version->getVersionString() == $this->minimalVersion->getVersionString()
+ || $version->isGreaterThan($this->minimalVersion);
+ }
+}
diff --git a/vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php b/vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php
new file mode 100644
index 0000000..274407f
--- /dev/null
+++ b/vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php
@@ -0,0 +1,43 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class OrVersionConstraintGroup extends AbstractVersionConstraint {
+ /**
+ * @var VersionConstraint[]
+ */
+ private $constraints = [];
+
+ /**
+ * @param string $originalValue
+ * @param VersionConstraint[] $constraints
+ */
+ public function __construct($originalValue, array $constraints) {
+ parent::__construct($originalValue);
+
+ $this->constraints = $constraints;
+ }
+
+ /**
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function complies(Version $version) {
+ foreach ($this->constraints as $constraint) {
+ if ($constraint->complies($version)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php b/vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php
new file mode 100644
index 0000000..3d58905
--- /dev/null
+++ b/vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php
@@ -0,0 +1,48 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class SpecificMajorAndMinorVersionConstraint extends AbstractVersionConstraint {
+ /**
+ * @var int
+ */
+ private $major = 0;
+
+ /**
+ * @var int
+ */
+ private $minor = 0;
+
+ /**
+ * @param string $originalValue
+ * @param int $major
+ * @param int $minor
+ */
+ public function __construct($originalValue, $major, $minor) {
+ parent::__construct($originalValue);
+
+ $this->major = $major;
+ $this->minor = $minor;
+ }
+
+ /**
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function complies(Version $version) {
+ if ($version->getMajor()->getValue() != $this->major) {
+ return false;
+ }
+
+ return $version->getMinor()->getValue() == $this->minor;
+ }
+}
diff --git a/vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php b/vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php
new file mode 100644
index 0000000..bbac47b
--- /dev/null
+++ b/vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php
@@ -0,0 +1,37 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+class SpecificMajorVersionConstraint extends AbstractVersionConstraint {
+ /**
+ * @var int
+ */
+ private $major = 0;
+
+ /**
+ * @param string $originalValue
+ * @param int $major
+ */
+ public function __construct($originalValue, $major) {
+ parent::__construct($originalValue);
+
+ $this->major = $major;
+ }
+
+ /**
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function complies(Version $version) {
+ return $version->getMajor()->getValue() == $this->major;
+ }
+}
diff --git a/vendor/phar-io/version/src/constraints/VersionConstraint.php b/vendor/phar-io/version/src/constraints/VersionConstraint.php
new file mode 100644
index 0000000..9558163
--- /dev/null
+++ b/vendor/phar-io/version/src/constraints/VersionConstraint.php
@@ -0,0 +1,26 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+interface VersionConstraint {
+ /**
+ * @param Version $version
+ *
+ * @return bool
+ */
+ public function complies(Version $version);
+
+ /**
+ * @return string
+ */
+ public function asString();
+
+}
diff --git a/vendor/phar-io/version/src/exceptions/Exception.php b/vendor/phar-io/version/src/exceptions/Exception.php
new file mode 100644
index 0000000..b99e4dd
--- /dev/null
+++ b/vendor/phar-io/version/src/exceptions/Exception.php
@@ -0,0 +1,14 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+interface Exception {
+}
diff --git a/vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php b/vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php
new file mode 100644
index 0000000..225fe71
--- /dev/null
+++ b/vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php
@@ -0,0 +1,7 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+final class UnsupportedVersionConstraintException extends \RuntimeException implements Exception {
+}
diff --git a/vendor/phar-io/version/tests/Integration/VersionConstraintParserTest.php b/vendor/phar-io/version/tests/Integration/VersionConstraintParserTest.php
new file mode 100644
index 0000000..f3e1ba8
--- /dev/null
+++ b/vendor/phar-io/version/tests/Integration/VersionConstraintParserTest.php
@@ -0,0 +1,146 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\VersionConstraintParser
+ */
+class VersionConstraintParserTest extends TestCase {
+ /**
+ * @dataProvider versionStringProvider
+ *
+ * @param string $versionString
+ * @param VersionConstraint $expectedConstraint
+ */
+ public function testReturnsExpectedConstraint($versionString, VersionConstraint $expectedConstraint) {
+ $parser = new VersionConstraintParser;
+
+ $this->assertEquals($expectedConstraint, $parser->parse($versionString));
+ }
+
+ /**
+ * @dataProvider unsupportedVersionStringProvider
+ *
+ * @param string $versionString
+ */
+ public function testThrowsExceptionIfVersionStringIsNotSupported($versionString) {
+ $parser = new VersionConstraintParser;
+
+ $this->expectException(UnsupportedVersionConstraintException::class);
+
+ $parser->parse($versionString);
+ }
+
+ /**
+ * @return array
+ */
+ public function versionStringProvider() {
+ return [
+ ['1.0.2', new ExactVersionConstraint('1.0.2')],
+ [
+ '~4.6',
+ new AndVersionConstraintGroup(
+ '~4.6',
+ [
+ new GreaterThanOrEqualToVersionConstraint('~4.6', new Version('4.6')),
+ new SpecificMajorVersionConstraint('~4.6', 4)
+ ]
+ )
+ ],
+ [
+ '~4.6.2',
+ new AndVersionConstraintGroup(
+ '~4.6.2',
+ [
+ new GreaterThanOrEqualToVersionConstraint('~4.6.2', new Version('4.6.2')),
+ new SpecificMajorAndMinorVersionConstraint('~4.6.2', 4, 6)
+ ]
+ )
+ ],
+ [
+ '^2.6.1',
+ new AndVersionConstraintGroup(
+ '^2.6.1',
+ [
+ new GreaterThanOrEqualToVersionConstraint('^2.6.1', new Version('2.6.1')),
+ new SpecificMajorVersionConstraint('^2.6.1', 2)
+ ]
+ )
+ ],
+ ['5.1.*', new SpecificMajorAndMinorVersionConstraint('5.1.*', 5, 1)],
+ ['5.*', new SpecificMajorVersionConstraint('5.*', 5)],
+ ['*', new AnyVersionConstraint()],
+ [
+ '1.0.2 || 1.0.5',
+ new OrVersionConstraintGroup(
+ '1.0.2 || 1.0.5',
+ [
+ new ExactVersionConstraint('1.0.2'),
+ new ExactVersionConstraint('1.0.5')
+ ]
+ )
+ ],
+ [
+ '^5.6 || ^7.0',
+ new OrVersionConstraintGroup(
+ '^5.6 || ^7.0',
+ [
+ new AndVersionConstraintGroup(
+ '^5.6', [
+ new GreaterThanOrEqualToVersionConstraint('^5.6', new Version('5.6')),
+ new SpecificMajorVersionConstraint('^5.6', 5)
+ ]
+ ),
+ new AndVersionConstraintGroup(
+ '^7.0', [
+ new GreaterThanOrEqualToVersionConstraint('^7.0', new Version('7.0')),
+ new SpecificMajorVersionConstraint('^7.0', 7)
+ ]
+ )
+ ]
+ )
+ ],
+ ['7.0.28-1', new ExactVersionConstraint('7.0.28-1')],
+ [
+ '^3.0.0-alpha1',
+ new AndVersionConstraintGroup(
+ '^3.0.0-alpha1',
+ [
+ new GreaterThanOrEqualToVersionConstraint('^3.0.0-alpha1', new Version('3.0.0-alpha1')),
+ new SpecificMajorVersionConstraint('^3.0.0-alpha1', 3)
+ ]
+ )
+ ],
+ [
+ '^3.0.0-alpha.1',
+ new AndVersionConstraintGroup(
+ '^3.0.0-alpha.1',
+ [
+ new GreaterThanOrEqualToVersionConstraint('^3.0.0-alpha.1', new Version('3.0.0-alpha.1')),
+ new SpecificMajorVersionConstraint('^3.0.0-alpha.1', 3)
+ ]
+ )
+ ]
+ ];
+ }
+
+ public function unsupportedVersionStringProvider() {
+ return [
+ ['foo'],
+ ['+1.0.2'],
+ ['>=2.0'],
+ ['^5.6 || >= 7.0'],
+ ['2.0 || foo']
+ ];
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/AbstractVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/AbstractVersionConstraintTest.php
new file mode 100644
index 0000000..c618566
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/AbstractVersionConstraintTest.php
@@ -0,0 +1,25 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\AbstractVersionConstraint
+ */
+class AbstractVersionConstraintTest extends TestCase {
+ public function testAsString() {
+ /** @var AbstractVersionConstraint|\PHPUnit_Framework_MockObject_MockObject $constraint */
+ $constraint = $this->getMockForAbstractClass(AbstractVersionConstraint::class, ['foo']);
+
+ $this->assertSame('foo', $constraint->asString());
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/AndVersionConstraintGroupTest.php b/vendor/phar-io/version/tests/Unit/AndVersionConstraintGroupTest.php
new file mode 100644
index 0000000..c2c5ec0
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/AndVersionConstraintGroupTest.php
@@ -0,0 +1,52 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\AndVersionConstraintGroup
+ */
+class AndVersionConstraintGroupTest extends TestCase {
+ public function testReturnsFalseIfOneConstraintReturnsFalse() {
+ $firstConstraint = $this->createMock(VersionConstraint::class);
+ $secondConstraint = $this->createMock(VersionConstraint::class);
+
+ $firstConstraint->expects($this->once())
+ ->method('complies')
+ ->will($this->returnValue(true));
+
+ $secondConstraint->expects($this->once())
+ ->method('complies')
+ ->will($this->returnValue(false));
+
+ $group = new AndVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]);
+
+ $this->assertFalse($group->complies(new Version('1.0.0')));
+ }
+
+ public function testReturnsTrueIfAllConstraintsReturnsTrue() {
+ $firstConstraint = $this->createMock(VersionConstraint::class);
+ $secondConstraint = $this->createMock(VersionConstraint::class);
+
+ $firstConstraint->expects($this->once())
+ ->method('complies')
+ ->will($this->returnValue(true));
+
+ $secondConstraint->expects($this->once())
+ ->method('complies')
+ ->will($this->returnValue(true));
+
+ $group = new AndVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]);
+
+ $this->assertTrue($group->complies(new Version('1.0.0')));
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/AnyVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/AnyVersionConstraintTest.php
new file mode 100644
index 0000000..6883099
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/AnyVersionConstraintTest.php
@@ -0,0 +1,41 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\AnyVersionConstraint
+ */
+class AnyVersionConstraintTest extends TestCase {
+ public function versionProvider() {
+ return [
+ [new Version('1.0.2')],
+ [new Version('4.8')],
+ [new Version('0.1.1-dev')]
+ ];
+ }
+
+ /**
+ * @dataProvider versionProvider
+ *
+ * @param Version $version
+ */
+ public function testReturnsTrue(Version $version) {
+ $constraint = new AnyVersionConstraint;
+
+ $this->assertTrue($constraint->complies($version));
+ }
+
+ public function testAsString() {
+ $this->assertSame('*', (new AnyVersionConstraint())->asString());
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/ExactVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/ExactVersionConstraintTest.php
new file mode 100644
index 0000000..ebba024
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/ExactVersionConstraintTest.php
@@ -0,0 +1,58 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\ExactVersionConstraint
+ */
+class ExactVersionConstraintTest extends TestCase {
+ public function compliantVersionProvider() {
+ return [
+ ['1.0.2', new Version('1.0.2')],
+ ['4.8.9', new Version('4.8.9')],
+ ['4.8', new Version('4.8')],
+ ];
+ }
+
+ public function nonCompliantVersionProvider() {
+ return [
+ ['1.0.2', new Version('1.0.3')],
+ ['4.8.9', new Version('4.7.9')],
+ ['4.8', new Version('4.8.5')],
+ ];
+ }
+
+ /**
+ * @dataProvider compliantVersionProvider
+ *
+ * @param string $constraintValue
+ * @param Version $version
+ */
+ public function testReturnsTrueForCompliantVersion($constraintValue, Version $version) {
+ $constraint = new ExactVersionConstraint($constraintValue);
+
+ $this->assertTrue($constraint->complies($version));
+ }
+
+ /**
+ * @dataProvider nonCompliantVersionProvider
+ *
+ * @param string $constraintValue
+ * @param Version $version
+ */
+ public function testReturnsFalseForNonCompliantVersion($constraintValue, Version $version) {
+ $constraint = new ExactVersionConstraint($constraintValue);
+
+ $this->assertFalse($constraint->complies($version));
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/GreaterThanOrEqualToVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/GreaterThanOrEqualToVersionConstraintTest.php
new file mode 100644
index 0000000..3cbb11d
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/GreaterThanOrEqualToVersionConstraintTest.php
@@ -0,0 +1,47 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\GreaterThanOrEqualToVersionConstraint
+ */
+class GreaterThanOrEqualToVersionConstraintTest extends TestCase {
+ public function versionProvider() {
+ return [
+ // compliant versions
+ [new Version('1.0.2'), new Version('1.0.2'), true],
+ [new Version('1.0.2'), new Version('1.0.3'), true],
+ [new Version('1.0.2'), new Version('1.1.1'), true],
+ [new Version('1.0.2'), new Version('2.0.0'), true],
+ [new Version('1.0.2'), new Version('1.0.3'), true],
+ // non-compliant versions
+ [new Version('1.0.2'), new Version('1.0.1'), false],
+ [new Version('1.9.8'), new Version('0.9.9'), false],
+ [new Version('2.3.1'), new Version('2.2.3'), false],
+ [new Version('3.0.2'), new Version('2.9.9'), false],
+ ];
+ }
+
+ /**
+ * @dataProvider versionProvider
+ *
+ * @param Version $constraintVersion
+ * @param Version $version
+ * @param bool $expectedResult
+ */
+ public function testReturnsTrueForCompliantVersions(Version $constraintVersion, Version $version, $expectedResult) {
+ $constraint = new GreaterThanOrEqualToVersionConstraint('foo', $constraintVersion);
+
+ $this->assertSame($expectedResult, $constraint->complies($version));
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/OrVersionConstraintGroupTest.php b/vendor/phar-io/version/tests/Unit/OrVersionConstraintGroupTest.php
new file mode 100644
index 0000000..088d557
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/OrVersionConstraintGroupTest.php
@@ -0,0 +1,65 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\OrVersionConstraintGroup
+ */
+class OrVersionConstraintGroupTest extends TestCase {
+ public function testReturnsTrueIfOneConstraintReturnsFalse() {
+ $firstConstraint = $this->createMock(VersionConstraint::class);
+ $secondConstraint = $this->createMock(VersionConstraint::class);
+
+ $firstConstraint->expects($this->once())
+ ->method('complies')
+ ->will($this->returnValue(false));
+
+ $secondConstraint->expects($this->once())
+ ->method('complies')
+ ->will($this->returnValue(true));
+
+ $group = new OrVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]);
+
+ $this->assertTrue($group->complies(new Version('1.0.0')));
+ }
+
+ public function testReturnsTrueIfAllConstraintsReturnsTrue() {
+ $firstConstraint = $this->createMock(VersionConstraint::class);
+ $secondConstraint = $this->createMock(VersionConstraint::class);
+
+ $firstConstraint->expects($this->once())
+ ->method('complies')
+ ->will($this->returnValue(true));
+
+ $group = new OrVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]);
+
+ $this->assertTrue($group->complies(new Version('1.0.0')));
+ }
+
+ public function testReturnsFalseIfAllConstraintsReturnsFalse() {
+ $firstConstraint = $this->createMock(VersionConstraint::class);
+ $secondConstraint = $this->createMock(VersionConstraint::class);
+
+ $firstConstraint->expects($this->once())
+ ->method('complies')
+ ->will($this->returnValue(false));
+
+ $secondConstraint->expects($this->once())
+ ->method('complies')
+ ->will($this->returnValue(false));
+
+ $group = new OrVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]);
+
+ $this->assertFalse($group->complies(new Version('1.0.0')));
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/PreReleaseSuffixTest.php b/vendor/phar-io/version/tests/Unit/PreReleaseSuffixTest.php
new file mode 100644
index 0000000..e09a66d
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/PreReleaseSuffixTest.php
@@ -0,0 +1,46 @@
+assertSame($expectedResult, $leftSuffix->isGreaterThan($rightSuffix));
+ }
+
+ public function greaterThanProvider() {
+ return [
+ ['alpha1', 'alpha2', false],
+ ['alpha2', 'alpha1', true],
+ ['beta1', 'alpha3', true],
+ ['b1', 'alpha3', true],
+ ['b1', 'a3', true],
+ ['dev1', 'alpha2', false],
+ ['dev1', 'alpha2', false],
+ ['alpha2', 'dev5', true],
+ ['rc1', 'beta2', true],
+ ['patch5', 'rc7', true],
+ ['alpha1', 'alpha.2', false],
+ ['alpha.3', 'alpha2', true],
+ ['alpha.3', 'alpha.2', true],
+ ];
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/SpecificMajorAndMinorVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/SpecificMajorAndMinorVersionConstraintTest.php
new file mode 100644
index 0000000..6025889
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/SpecificMajorAndMinorVersionConstraintTest.php
@@ -0,0 +1,45 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\SpecificMajorAndMinorVersionConstraint
+ */
+class SpecificMajorAndMinorVersionConstraintTest extends TestCase {
+ public function versionProvider() {
+ return [
+ // compliant versions
+ [1, 0, new Version('1.0.2'), true],
+ [1, 0, new Version('1.0.3'), true],
+ [1, 1, new Version('1.1.1'), true],
+ // non-compliant versions
+ [2, 9, new Version('0.9.9'), false],
+ [3, 2, new Version('2.2.3'), false],
+ [2, 8, new Version('2.9.9'), false],
+ ];
+ }
+
+ /**
+ * @dataProvider versionProvider
+ *
+ * @param int $major
+ * @param int $minor
+ * @param Version $version
+ * @param bool $expectedResult
+ */
+ public function testReturnsTrueForCompliantVersions($major, $minor, Version $version, $expectedResult) {
+ $constraint = new SpecificMajorAndMinorVersionConstraint('foo', $major, $minor);
+
+ $this->assertSame($expectedResult, $constraint->complies($version));
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/SpecificMajorVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/SpecificMajorVersionConstraintTest.php
new file mode 100644
index 0000000..6dc3b71
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/SpecificMajorVersionConstraintTest.php
@@ -0,0 +1,44 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\SpecificMajorVersionConstraint
+ */
+class SpecificMajorVersionConstraintTest extends TestCase {
+ public function versionProvider() {
+ return [
+ // compliant versions
+ [1, new Version('1.0.2'), true],
+ [1, new Version('1.0.3'), true],
+ [1, new Version('1.1.1'), true],
+ // non-compliant versions
+ [2, new Version('0.9.9'), false],
+ [3, new Version('2.2.3'), false],
+ [3, new Version('2.9.9'), false],
+ ];
+ }
+
+ /**
+ * @dataProvider versionProvider
+ *
+ * @param int $major
+ * @param Version $version
+ * @param bool $expectedResult
+ */
+ public function testReturnsTrueForCompliantVersions($major, Version $version, $expectedResult) {
+ $constraint = new SpecificMajorVersionConstraint('foo', $major);
+
+ $this->assertSame($expectedResult, $constraint->complies($version));
+ }
+}
diff --git a/vendor/phar-io/version/tests/Unit/VersionTest.php b/vendor/phar-io/version/tests/Unit/VersionTest.php
new file mode 100644
index 0000000..6b4897a
--- /dev/null
+++ b/vendor/phar-io/version/tests/Unit/VersionTest.php
@@ -0,0 +1,113 @@
+, Sebastian Heuer , Sebastian Bergmann
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PharIo\Version;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \PharIo\Version\Version
+ */
+class VersionTest extends TestCase {
+ /**
+ * @dataProvider versionProvider
+ *
+ * @param string $versionString
+ * @param string $expectedMajor
+ * @param string $expectedMinor
+ * @param string $expectedPatch
+ * @param string $expectedPreReleaseValue
+ * @param int $expectedReleaseCount
+ */
+ public function testParsesVersionNumbers(
+ $versionString,
+ $expectedMajor,
+ $expectedMinor,
+ $expectedPatch,
+ $expectedPreReleaseValue = '',
+ $expectedReleaseCount = 0
+ ) {
+ $version = new Version($versionString);
+
+ $this->assertSame($expectedMajor, $version->getMajor()->getValue());
+ $this->assertSame($expectedMinor, $version->getMinor()->getValue());
+ $this->assertSame($expectedPatch, $version->getPatch()->getValue());
+ if ($expectedPreReleaseValue !== '') {
+ $this->assertSame($expectedPreReleaseValue, $version->getPreReleaseSuffix()->getValue());
+ }
+ if ($expectedReleaseCount !== 0) {
+ $this->assertSame($expectedReleaseCount, $version->getPreReleaseSuffix()->getNumber());
+ }
+
+ $this->assertSame($versionString, $version->getVersionString());
+ }
+
+ public function versionProvider() {
+ return [
+ ['0.0.1', '0', '0', '1'],
+ ['0.1.2', '0', '1', '2'],
+ ['1.0.0-alpha', '1', '0', '0', 'alpha'],
+ ['3.4.12-dev3', '3', '4', '12', 'dev', 3],
+ ];
+ }
+
+ /**
+ * @dataProvider versionGreaterThanProvider
+ *
+ * @param Version $versionA
+ * @param Version $versionB
+ * @param bool $expectedResult
+ */
+ public function testIsGreaterThan(Version $versionA, Version $versionB, $expectedResult) {
+ $this->assertSame($expectedResult, $versionA->isGreaterThan($versionB));
+ }
+
+ /**
+ * @return array
+ */
+ public function versionGreaterThanProvider() {
+ return [
+ [new Version('1.0.0'), new Version('1.0.1'), false],
+ [new Version('1.0.1'), new Version('1.0.0'), true],
+ [new Version('1.1.0'), new Version('1.0.1'), true],
+ [new Version('1.1.0'), new Version('2.0.1'), false],
+ [new Version('1.1.0'), new Version('1.1.0'), false],
+ [new Version('2.5.8'), new Version('1.6.8'), true],
+ [new Version('2.5.8'), new Version('2.6.8'), false],
+ [new Version('2.5.8'), new Version('3.1.2'), false],
+ [new Version('3.0.0-alpha1'), new Version('3.0.0-alpha2'), false],
+ [new Version('3.0.0-alpha2'), new Version('3.0.0-alpha1'), true],
+ [new Version('3.0.0-alpha.1'), new Version('3.0.0'), false],
+ [new Version('3.0.0'), new Version('3.0.0-alpha.1'), true],
+ ];
+ }
+
+ /**
+ * @dataProvider invalidVersionStringProvider
+ *
+ * @param string $versionString
+ */
+ public function testThrowsExceptionIfVersionStringDoesNotFollowSemVer($versionString) {
+ $this->expectException(InvalidVersionException::class);
+ new Version($versionString);
+ }
+
+ /**
+ * @return array
+ */
+ public function invalidVersionStringProvider() {
+ return [
+ ['foo'],
+ ['0.0.1-dev+ABC', '0', '0', '1', 'dev', 'ABC'],
+ ['1.0.0-x.7.z.92', '1', '0', '0', 'x.7.z.92']
+ ];
+ }
+
+}
diff --git a/vendor/phpdocumentor/reflection-common/.travis.yml b/vendor/phpdocumentor/reflection-common/.travis.yml
new file mode 100644
index 0000000..958ecf8
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/.travis.yml
@@ -0,0 +1,35 @@
+language: php
+php:
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+ - hhvm
+ - nightly
+
+matrix:
+ allow_failures:
+ - php:
+ - hhvm
+ - nightly
+
+cache:
+ directories:
+ - $HOME/.composer/cache
+
+script:
+ - vendor/bin/phpunit --coverage-clover=coverage.clover -v
+ - composer update --no-interaction --prefer-source
+ - vendor/bin/phpunit -v
+
+before_script:
+ - composer install --no-interaction
+
+after_script:
+ - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then wget https://scrutinizer-ci.com/ocular.phar; php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
+
+notifications:
+ irc: "irc.freenode.org#phpdocumentor"
+ email:
+ - me@mikevanriel.com
+ - ashnazg@php.net
diff --git a/vendor/phpdocumentor/reflection-common/LICENSE b/vendor/phpdocumentor/reflection-common/LICENSE
new file mode 100644
index 0000000..ed6926c
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 phpDocumentor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/vendor/phpdocumentor/reflection-common/README.md b/vendor/phpdocumentor/reflection-common/README.md
new file mode 100644
index 0000000..68a80c8
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/README.md
@@ -0,0 +1,2 @@
+# ReflectionCommon
+[![Build Status](https://travis-ci.org/phpDocumentor/ReflectionCommon.svg?branch=master)](https://travis-ci.org/phpDocumentor/ReflectionCommon)
diff --git a/vendor/phpdocumentor/reflection-common/composer.json b/vendor/phpdocumentor/reflection-common/composer.json
new file mode 100644
index 0000000..90eee0f
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "phpdocumentor/reflection-common",
+ "keywords": ["phpdoc", "phpDocumentor", "reflection", "static analysis", "FQSEN"],
+ "homepage": "http://www.phpdoc.org",
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "require": {
+ "php": ">=5.5"
+ },
+ "autoload" : {
+ "psr-4" : {
+ "phpDocumentor\\Reflection\\": ["src"]
+ }
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-common/src/Element.php b/vendor/phpdocumentor/reflection-common/src/Element.php
new file mode 100644
index 0000000..712e30e
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/Element.php
@@ -0,0 +1,32 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+/**
+ * Interface for files processed by the ProjectFactory
+ */
+interface File
+{
+ /**
+ * Returns the content of the file as a string.
+ *
+ * @return string
+ */
+ public function getContents();
+
+ /**
+ * Returns md5 hash of the file.
+ *
+ * @return string
+ */
+ public function md5();
+
+ /**
+ * Returns an relative path to the file.
+ *
+ * @return string
+ */
+ public function path();
+}
diff --git a/vendor/phpdocumentor/reflection-common/src/Fqsen.php b/vendor/phpdocumentor/reflection-common/src/Fqsen.php
new file mode 100644
index 0000000..ce88d03
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/Fqsen.php
@@ -0,0 +1,82 @@
+fqsen = $fqsen;
+
+ if (isset($matches[2])) {
+ $this->name = $matches[2];
+ } else {
+ $matches = explode('\\', $fqsen);
+ $this->name = trim(end($matches), '()');
+ }
+ }
+
+ /**
+ * converts this class to string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->fqsen;
+ }
+
+ /**
+ * Returns the name of the element without path.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-common/src/Location.php b/vendor/phpdocumentor/reflection-common/src/Location.php
new file mode 100644
index 0000000..5760321
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/Location.php
@@ -0,0 +1,57 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+/**
+ * The location where an element occurs within a file.
+ */
+final class Location
+{
+ /** @var int */
+ private $lineNumber = 0;
+
+ /** @var int */
+ private $columnNumber = 0;
+
+ /**
+ * Initializes the location for an element using its line number in the file and optionally the column number.
+ *
+ * @param int $lineNumber
+ * @param int $columnNumber
+ */
+ public function __construct($lineNumber, $columnNumber = 0)
+ {
+ $this->lineNumber = $lineNumber;
+ $this->columnNumber = $columnNumber;
+ }
+
+ /**
+ * Returns the line number that is covered by this location.
+ *
+ * @return integer
+ */
+ public function getLineNumber()
+ {
+ return $this->lineNumber;
+ }
+
+ /**
+ * Returns the column number (character position on a line) for this location object.
+ *
+ * @return integer
+ */
+ public function getColumnNumber()
+ {
+ return $this->columnNumber;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-common/src/Project.php b/vendor/phpdocumentor/reflection-common/src/Project.php
new file mode 100644
index 0000000..3ed1e39
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/Project.php
@@ -0,0 +1,25 @@
+create($docComment);
+```
+
+The `create` method will yield an object of type `\phpDocumentor\Reflection\DocBlock`
+whose methods can be queried:
+
+```php
+// Contains the summary for this DocBlock
+$summary = $docblock->getSummary();
+
+// Contains \phpDocumentor\Reflection\DocBlock\Description object
+$description = $docblock->getDescription();
+
+// You can either cast it to string
+$description = (string) $docblock->getDescription();
+
+// Or use the render method to get a string representation of the Description.
+$description = $docblock->getDescription()->render();
+```
+
+> For more examples it would be best to review the scripts in the [`/examples` folder](/examples).
diff --git a/vendor/phpdocumentor/reflection-docblock/composer.json b/vendor/phpdocumentor/reflection-docblock/composer.json
new file mode 100644
index 0000000..e3dc38a
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "phpdocumentor/reflection-docblock",
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "require": {
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0",
+ "phpdocumentor/type-resolver": "^0.4.0",
+ "webmozart/assert": "^1.0"
+ },
+ "autoload": {
+ "psr-4": {"phpDocumentor\\Reflection\\": ["src/"]}
+ },
+ "autoload-dev": {
+ "psr-4": {"phpDocumentor\\Reflection\\": ["tests/unit"]}
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.4",
+ "doctrine/instantiator": "~1.0.5"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/easy-coding-standard.neon b/vendor/phpdocumentor/reflection-docblock/easy-coding-standard.neon
new file mode 100644
index 0000000..7c2ba6e
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/easy-coding-standard.neon
@@ -0,0 +1,31 @@
+includes:
+ - temp/ecs/config/clean-code.neon
+ - temp/ecs/config/psr2-checkers.neon
+ - temp/ecs/config/spaces.neon
+ - temp/ecs/config/common.neon
+
+checkers:
+ PhpCsFixer\Fixer\Operator\ConcatSpaceFixer:
+ spacing: one
+
+parameters:
+ exclude_checkers:
+ # from temp/ecs/config/common.neon
+ - PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer
+ - PhpCsFixer\Fixer\PhpUnit\PhpUnitStrictFixer
+ - PhpCsFixer\Fixer\ControlStructure\YodaStyleFixer
+ # from temp/ecs/config/spaces.neon
+ - PhpCsFixer\Fixer\Operator\NotOperatorWithSuccessorSpaceFixer
+
+ skip:
+ SlevomatCodingStandard\Sniffs\Classes\UnusedPrivateElementsSniff:
+ # WIP code
+ - src/DocBlock/StandardTagFactory.php
+ PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\EmptyStatementSniff:
+ # WIP code
+ - src/DocBlock/StandardTagFactory.php
+ PHP_CodeSniffer\Standards\Squiz\Sniffs\Classes\ValidClassNameSniff:
+ - src/DocBlock/Tags/Return_.php
+ - src/DocBlock/Tags/Var_.php
+ PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff:
+ - */tests/**
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php
new file mode 100644
index 0000000..46605b7
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php
@@ -0,0 +1,236 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use Webmozart\Assert\Assert;
+
+final class DocBlock
+{
+ /** @var string The opening line for this docblock. */
+ private $summary = '';
+
+ /** @var DocBlock\Description The actual description for this docblock. */
+ private $description = null;
+
+ /** @var Tag[] An array containing all the tags in this docblock; except inline. */
+ private $tags = [];
+
+ /** @var Types\Context Information about the context of this DocBlock. */
+ private $context = null;
+
+ /** @var Location Information about the location of this DocBlock. */
+ private $location = null;
+
+ /** @var bool Is this DocBlock (the start of) a template? */
+ private $isTemplateStart = false;
+
+ /** @var bool Does this DocBlock signify the end of a DocBlock template? */
+ private $isTemplateEnd = false;
+
+ /**
+ * @param string $summary
+ * @param DocBlock\Description $description
+ * @param DocBlock\Tag[] $tags
+ * @param Types\Context $context The context in which the DocBlock occurs.
+ * @param Location $location The location within the file that this DocBlock occurs in.
+ * @param bool $isTemplateStart
+ * @param bool $isTemplateEnd
+ */
+ public function __construct(
+ $summary = '',
+ DocBlock\Description $description = null,
+ array $tags = [],
+ Types\Context $context = null,
+ Location $location = null,
+ $isTemplateStart = false,
+ $isTemplateEnd = false
+ ) {
+ Assert::string($summary);
+ Assert::boolean($isTemplateStart);
+ Assert::boolean($isTemplateEnd);
+ Assert::allIsInstanceOf($tags, Tag::class);
+
+ $this->summary = $summary;
+ $this->description = $description ?: new DocBlock\Description('');
+ foreach ($tags as $tag) {
+ $this->addTag($tag);
+ }
+
+ $this->context = $context;
+ $this->location = $location;
+
+ $this->isTemplateEnd = $isTemplateEnd;
+ $this->isTemplateStart = $isTemplateStart;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSummary()
+ {
+ return $this->summary;
+ }
+
+ /**
+ * @return DocBlock\Description
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Returns the current context.
+ *
+ * @return Types\Context
+ */
+ public function getContext()
+ {
+ return $this->context;
+ }
+
+ /**
+ * Returns the current location.
+ *
+ * @return Location
+ */
+ public function getLocation()
+ {
+ return $this->location;
+ }
+
+ /**
+ * Returns whether this DocBlock is the start of a Template section.
+ *
+ * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker
+ * (`#@+`) that is appended directly after the opening `/**` of a DocBlock.
+ *
+ * An example of such an opening is:
+ *
+ * ```
+ * /**#@+
+ * * My DocBlock
+ * * /
+ * ```
+ *
+ * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all
+ * elements that follow until another DocBlock is found that contains the closing marker (`#@-`).
+ *
+ * @see self::isTemplateEnd() for the check whether a closing marker was provided.
+ *
+ * @return boolean
+ */
+ public function isTemplateStart()
+ {
+ return $this->isTemplateStart;
+ }
+
+ /**
+ * Returns whether this DocBlock is the end of a Template section.
+ *
+ * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality.
+ *
+ * @return boolean
+ */
+ public function isTemplateEnd()
+ {
+ return $this->isTemplateEnd;
+ }
+
+ /**
+ * Returns the tags for this DocBlock.
+ *
+ * @return Tag[]
+ */
+ public function getTags()
+ {
+ return $this->tags;
+ }
+
+ /**
+ * Returns an array of tags matching the given name. If no tags are found
+ * an empty array is returned.
+ *
+ * @param string $name String to search by.
+ *
+ * @return Tag[]
+ */
+ public function getTagsByName($name)
+ {
+ Assert::string($name);
+
+ $result = [];
+
+ /** @var Tag $tag */
+ foreach ($this->getTags() as $tag) {
+ if ($tag->getName() !== $name) {
+ continue;
+ }
+
+ $result[] = $tag;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Checks if a tag of a certain type is present in this DocBlock.
+ *
+ * @param string $name Tag name to check for.
+ *
+ * @return bool
+ */
+ public function hasTag($name)
+ {
+ Assert::string($name);
+
+ /** @var Tag $tag */
+ foreach ($this->getTags() as $tag) {
+ if ($tag->getName() === $name) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Remove a tag from this DocBlock.
+ *
+ * @param Tag $tag The tag to remove.
+ *
+ * @return void
+ */
+ public function removeTag(Tag $tagToRemove)
+ {
+ foreach ($this->tags as $key => $tag) {
+ if ($tag === $tagToRemove) {
+ unset($this->tags[$key]);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Adds a tag to this DocBlock.
+ *
+ * @param Tag $tag The tag to add.
+ *
+ * @return void
+ */
+ private function addTag(Tag $tag)
+ {
+ $this->tags[] = $tag;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php
new file mode 100644
index 0000000..25a79e0
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php
@@ -0,0 +1,114 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter;
+use Webmozart\Assert\Assert;
+
+/**
+ * Object representing to description for a DocBlock.
+ *
+ * A Description object can consist of plain text but can also include tags. A Description Formatter can then combine
+ * a body template with sprintf-style placeholders together with formatted tags in order to reconstitute a complete
+ * description text using the format that you would prefer.
+ *
+ * Because parsing a Description text can be a verbose process this is handled by the {@see DescriptionFactory}. It is
+ * thus recommended to use that to create a Description object, like this:
+ *
+ * $description = $descriptionFactory->create('This is a {@see Description}', $context);
+ *
+ * The description factory will interpret the given body and create a body template and list of tags from them, and pass
+ * that onto the constructor if this class.
+ *
+ * > The $context variable is a class of type {@see \phpDocumentor\Reflection\Types\Context} and contains the namespace
+ * > and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial
+ * > type names and FQSENs.
+ *
+ * If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this:
+ *
+ * $description = new Description(
+ * 'This is a %1$s',
+ * [ new See(new Fqsen('\phpDocumentor\Reflection\DocBlock\Description')) ]
+ * );
+ *
+ * It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object
+ * is mainly responsible for rendering.
+ *
+ * @see DescriptionFactory to create a new Description.
+ * @see Description\Formatter for the formatting of the body and tags.
+ */
+class Description
+{
+ /** @var string */
+ private $bodyTemplate;
+
+ /** @var Tag[] */
+ private $tags;
+
+ /**
+ * Initializes a Description with its body (template) and a listing of the tags used in the body template.
+ *
+ * @param string $bodyTemplate
+ * @param Tag[] $tags
+ */
+ public function __construct($bodyTemplate, array $tags = [])
+ {
+ Assert::string($bodyTemplate);
+
+ $this->bodyTemplate = $bodyTemplate;
+ $this->tags = $tags;
+ }
+
+ /**
+ * Returns the tags for this DocBlock.
+ *
+ * @return Tag[]
+ */
+ public function getTags()
+ {
+ return $this->tags;
+ }
+
+ /**
+ * Renders this description as a string where the provided formatter will format the tags in the expected string
+ * format.
+ *
+ * @param Formatter|null $formatter
+ *
+ * @return string
+ */
+ public function render(Formatter $formatter = null)
+ {
+ if ($formatter === null) {
+ $formatter = new PassthroughFormatter();
+ }
+
+ $tags = [];
+ foreach ($this->tags as $tag) {
+ $tags[] = '{' . $formatter->format($tag) . '}';
+ }
+
+ return vsprintf($this->bodyTemplate, $tags);
+ }
+
+ /**
+ * Returns a plain string representation of this description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render();
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php
new file mode 100644
index 0000000..48f9c21
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php
@@ -0,0 +1,191 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+
+/**
+ * Creates a new Description object given a body of text.
+ *
+ * Descriptions in phpDocumentor are somewhat complex entities as they can contain one or more tags inside their
+ * body that can be replaced with a readable output. The replacing is done by passing a Formatter object to the
+ * Description object's `render` method.
+ *
+ * In addition to the above does a Description support two types of escape sequences:
+ *
+ * 1. `{@}` to escape the `@` character to prevent it from being interpreted as part of a tag, i.e. `{{@}link}`
+ * 2. `{}` to escape the `}` character, this can be used if you want to use the `}` character in the description
+ * of an inline tag.
+ *
+ * If a body consists of multiple lines then this factory will also remove any superfluous whitespace at the beginning
+ * of each line while maintaining any indentation that is used. This will prevent formatting parsers from tripping
+ * over unexpected spaces as can be observed with tag descriptions.
+ */
+class DescriptionFactory
+{
+ /** @var TagFactory */
+ private $tagFactory;
+
+ /**
+ * Initializes this factory with the means to construct (inline) tags.
+ *
+ * @param TagFactory $tagFactory
+ */
+ public function __construct(TagFactory $tagFactory)
+ {
+ $this->tagFactory = $tagFactory;
+ }
+
+ /**
+ * Returns the parsed text of this description.
+ *
+ * @param string $contents
+ * @param TypeContext $context
+ *
+ * @return Description
+ */
+ public function create($contents, TypeContext $context = null)
+ {
+ list($text, $tags) = $this->parse($this->lex($contents), $context);
+
+ return new Description($text, $tags);
+ }
+
+ /**
+ * Strips the contents from superfluous whitespace and splits the description into a series of tokens.
+ *
+ * @param string $contents
+ *
+ * @return string[] A series of tokens of which the description text is composed.
+ */
+ private function lex($contents)
+ {
+ $contents = $this->removeSuperfluousStartingWhitespace($contents);
+
+ // performance optimalization; if there is no inline tag, don't bother splitting it up.
+ if (strpos($contents, '{@') === false) {
+ return [$contents];
+ }
+
+ return preg_split(
+ '/\{
+ # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally.
+ (?!@\})
+ # We want to capture the whole tag line, but without the inline tag delimiters.
+ (\@
+ # Match everything up to the next delimiter.
+ [^{}]*
+ # Nested inline tag content should not be captured, or it will appear in the result separately.
+ (?:
+ # Match nested inline tags.
+ (?:
+ # Because we did not catch the tag delimiters earlier, we must be explicit with them here.
+ # Notice that this also matches "{}", as a way to later introduce it as an escape sequence.
+ \{(?1)?\}
+ |
+ # Make sure we match hanging "{".
+ \{
+ )
+ # Match content after the nested inline tag.
+ [^{}]*
+ )* # If there are more inline tags, match them as well. We use "*" since there may not be any
+ # nested inline tags.
+ )
+ \}/Sux',
+ $contents,
+ null,
+ PREG_SPLIT_DELIM_CAPTURE
+ );
+ }
+
+ /**
+ * Parses the stream of tokens in to a new set of tokens containing Tags.
+ *
+ * @param string[] $tokens
+ * @param TypeContext $context
+ *
+ * @return string[]|Tag[]
+ */
+ private function parse($tokens, TypeContext $context)
+ {
+ $count = count($tokens);
+ $tagCount = 0;
+ $tags = [];
+
+ for ($i = 1; $i < $count; $i += 2) {
+ $tags[] = $this->tagFactory->create($tokens[$i], $context);
+ $tokens[$i] = '%' . ++$tagCount . '$s';
+ }
+
+ //In order to allow "literal" inline tags, the otherwise invalid
+ //sequence "{@}" is changed to "@", and "{}" is changed to "}".
+ //"%" is escaped to "%%" because of vsprintf.
+ //See unit tests for examples.
+ for ($i = 0; $i < $count; $i += 2) {
+ $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]);
+ }
+
+ return [implode('', $tokens), $tags];
+ }
+
+ /**
+ * Removes the superfluous from a multi-line description.
+ *
+ * When a description has more than one line then it can happen that the second and subsequent lines have an
+ * additional indentation. This is commonly in use with tags like this:
+ *
+ * {@}since 1.1.0 This is an example
+ * description where we have an
+ * indentation in the second and
+ * subsequent lines.
+ *
+ * If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent
+ * lines and this may cause rendering issues when, for example, using a Markdown converter.
+ *
+ * @param string $contents
+ *
+ * @return string
+ */
+ private function removeSuperfluousStartingWhitespace($contents)
+ {
+ $lines = explode("\n", $contents);
+
+ // if there is only one line then we don't have lines with superfluous whitespace and
+ // can use the contents as-is
+ if (count($lines) <= 1) {
+ return $contents;
+ }
+
+ // determine how many whitespace characters need to be stripped
+ $startingSpaceCount = 9999999;
+ for ($i = 1; $i < count($lines); $i++) {
+ // lines with a no length do not count as they are not indented at all
+ if (strlen(trim($lines[$i])) === 0) {
+ continue;
+ }
+
+ // determine the number of prefixing spaces by checking the difference in line length before and after
+ // an ltrim
+ $startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i])));
+ }
+
+ // strip the number of spaces from each line
+ if ($startingSpaceCount > 0) {
+ for ($i = 1; $i < count($lines); $i++) {
+ $lines[$i] = substr($lines[$i], $startingSpaceCount);
+ }
+ }
+
+ return implode("\n", $lines);
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php
new file mode 100644
index 0000000..571ed74
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php
@@ -0,0 +1,170 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock\Tags\Example;
+
+/**
+ * Class used to find an example file's location based on a given ExampleDescriptor.
+ */
+class ExampleFinder
+{
+ /** @var string */
+ private $sourceDirectory = '';
+
+ /** @var string[] */
+ private $exampleDirectories = [];
+
+ /**
+ * Attempts to find the example contents for the given descriptor.
+ *
+ * @param Example $example
+ *
+ * @return string
+ */
+ public function find(Example $example)
+ {
+ $filename = $example->getFilePath();
+
+ $file = $this->getExampleFileContents($filename);
+ if (!$file) {
+ return "** File not found : {$filename} **";
+ }
+
+ return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount()));
+ }
+
+ /**
+ * Registers the project's root directory where an 'examples' folder can be expected.
+ *
+ * @param string $directory
+ *
+ * @return void
+ */
+ public function setSourceDirectory($directory = '')
+ {
+ $this->sourceDirectory = $directory;
+ }
+
+ /**
+ * Returns the project's root directory where an 'examples' folder can be expected.
+ *
+ * @return string
+ */
+ public function getSourceDirectory()
+ {
+ return $this->sourceDirectory;
+ }
+
+ /**
+ * Registers a series of directories that may contain examples.
+ *
+ * @param string[] $directories
+ */
+ public function setExampleDirectories(array $directories)
+ {
+ $this->exampleDirectories = $directories;
+ }
+
+ /**
+ * Returns a series of directories that may contain examples.
+ *
+ * @return string[]
+ */
+ public function getExampleDirectories()
+ {
+ return $this->exampleDirectories;
+ }
+
+ /**
+ * Attempts to find the requested example file and returns its contents or null if no file was found.
+ *
+ * This method will try several methods in search of the given example file, the first one it encounters is
+ * returned:
+ *
+ * 1. Iterates through all examples folders for the given filename
+ * 2. Checks the source folder for the given filename
+ * 3. Checks the 'examples' folder in the current working directory for examples
+ * 4. Checks the path relative to the current working directory for the given filename
+ *
+ * @param string $filename
+ *
+ * @return string|null
+ */
+ private function getExampleFileContents($filename)
+ {
+ $normalizedPath = null;
+
+ foreach ($this->exampleDirectories as $directory) {
+ $exampleFileFromConfig = $this->constructExamplePath($directory, $filename);
+ if (is_readable($exampleFileFromConfig)) {
+ $normalizedPath = $exampleFileFromConfig;
+ break;
+ }
+ }
+
+ if (!$normalizedPath) {
+ if (is_readable($this->getExamplePathFromSource($filename))) {
+ $normalizedPath = $this->getExamplePathFromSource($filename);
+ } elseif (is_readable($this->getExamplePathFromExampleDirectory($filename))) {
+ $normalizedPath = $this->getExamplePathFromExampleDirectory($filename);
+ } elseif (is_readable($filename)) {
+ $normalizedPath = $filename;
+ }
+ }
+
+ return $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : null;
+ }
+
+ /**
+ * Get example filepath based on the example directory inside your project.
+ *
+ * @param string $file
+ *
+ * @return string
+ */
+ private function getExamplePathFromExampleDirectory($file)
+ {
+ return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file;
+ }
+
+ /**
+ * Returns a path to the example file in the given directory..
+ *
+ * @param string $directory
+ * @param string $file
+ *
+ * @return string
+ */
+ private function constructExamplePath($directory, $file)
+ {
+ return rtrim($directory, '\\/') . DIRECTORY_SEPARATOR . $file;
+ }
+
+ /**
+ * Get example filepath based on sourcecode.
+ *
+ * @param string $file
+ *
+ * @return string
+ */
+ private function getExamplePathFromSource($file)
+ {
+ return sprintf(
+ '%s%s%s',
+ trim($this->getSourceDirectory(), '\\/'),
+ DIRECTORY_SEPARATOR,
+ trim($file, '"')
+ );
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php
new file mode 100644
index 0000000..0f355f5
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php
@@ -0,0 +1,155 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock;
+use Webmozart\Assert\Assert;
+
+/**
+ * Converts a DocBlock back from an object to a complete DocComment including Asterisks.
+ */
+class Serializer
+{
+ /** @var string The string to indent the comment with. */
+ protected $indentString = ' ';
+
+ /** @var int The number of times the indent string is repeated. */
+ protected $indent = 0;
+
+ /** @var bool Whether to indent the first line with the given indent amount and string. */
+ protected $isFirstLineIndented = true;
+
+ /** @var int|null The max length of a line. */
+ protected $lineLength = null;
+
+ /** @var DocBlock\Tags\Formatter A custom tag formatter. */
+ protected $tagFormatter = null;
+
+ /**
+ * Create a Serializer instance.
+ *
+ * @param int $indent The number of times the indent string is repeated.
+ * @param string $indentString The string to indent the comment with.
+ * @param bool $indentFirstLine Whether to indent the first line.
+ * @param int|null $lineLength The max length of a line or NULL to disable line wrapping.
+ * @param DocBlock\Tags\Formatter $tagFormatter A custom tag formatter, defaults to PassthroughFormatter.
+ */
+ public function __construct($indent = 0, $indentString = ' ', $indentFirstLine = true, $lineLength = null, $tagFormatter = null)
+ {
+ Assert::integer($indent);
+ Assert::string($indentString);
+ Assert::boolean($indentFirstLine);
+ Assert::nullOrInteger($lineLength);
+ Assert::nullOrIsInstanceOf($tagFormatter, 'phpDocumentor\Reflection\DocBlock\Tags\Formatter');
+
+ $this->indent = $indent;
+ $this->indentString = $indentString;
+ $this->isFirstLineIndented = $indentFirstLine;
+ $this->lineLength = $lineLength;
+ $this->tagFormatter = $tagFormatter ?: new DocBlock\Tags\Formatter\PassthroughFormatter();
+ }
+
+ /**
+ * Generate a DocBlock comment.
+ *
+ * @param DocBlock $docblock The DocBlock to serialize.
+ *
+ * @return string The serialized doc block.
+ */
+ public function getDocComment(DocBlock $docblock)
+ {
+ $indent = str_repeat($this->indentString, $this->indent);
+ $firstIndent = $this->isFirstLineIndented ? $indent : '';
+ // 3 === strlen(' * ')
+ $wrapLength = $this->lineLength ? $this->lineLength - strlen($indent) - 3 : null;
+
+ $text = $this->removeTrailingSpaces(
+ $indent,
+ $this->addAsterisksForEachLine(
+ $indent,
+ $this->getSummaryAndDescriptionTextBlock($docblock, $wrapLength)
+ )
+ );
+
+ $comment = "{$firstIndent}/**\n";
+ if ($text) {
+ $comment .= "{$indent} * {$text}\n";
+ $comment .= "{$indent} *\n";
+ }
+
+ $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment);
+ $comment .= $indent . ' */';
+
+ return $comment;
+ }
+
+ /**
+ * @param $indent
+ * @param $text
+ * @return mixed
+ */
+ private function removeTrailingSpaces($indent, $text)
+ {
+ return str_replace("\n{$indent} * \n", "\n{$indent} *\n", $text);
+ }
+
+ /**
+ * @param $indent
+ * @param $text
+ * @return mixed
+ */
+ private function addAsterisksForEachLine($indent, $text)
+ {
+ return str_replace("\n", "\n{$indent} * ", $text);
+ }
+
+ /**
+ * @param DocBlock $docblock
+ * @param $wrapLength
+ * @return string
+ */
+ private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, $wrapLength)
+ {
+ $text = $docblock->getSummary() . ((string)$docblock->getDescription() ? "\n\n" . $docblock->getDescription()
+ : '');
+ if ($wrapLength !== null) {
+ $text = wordwrap($text, $wrapLength);
+ return $text;
+ }
+
+ return $text;
+ }
+
+ /**
+ * @param DocBlock $docblock
+ * @param $wrapLength
+ * @param $indent
+ * @param $comment
+ * @return string
+ */
+ private function addTagBlock(DocBlock $docblock, $wrapLength, $indent, $comment)
+ {
+ foreach ($docblock->getTags() as $tag) {
+ $tagText = $this->tagFormatter->format($tag);
+ if ($wrapLength !== null) {
+ $tagText = wordwrap($tagText, $wrapLength);
+ }
+
+ $tagText = str_replace("\n", "\n{$indent} * ", $tagText);
+
+ $comment .= "{$indent} * {$tagText}\n";
+ }
+
+ return $comment;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php
new file mode 100644
index 0000000..5a8143c
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php
@@ -0,0 +1,319 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod;
+use phpDocumentor\Reflection\DocBlock\Tags\Generic;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Creates a Tag object given the contents of a tag.
+ *
+ * This Factory is capable of determining the appropriate class for a tag and instantiate it using its `create`
+ * factory method. The `create` factory method of a Tag can have a variable number of arguments; this way you can
+ * pass the dependencies that you need to construct a tag object.
+ *
+ * > Important: each parameter in addition to the body variable for the `create` method must default to null, otherwise
+ * > it violates the constraint with the interface; it is recommended to use the {@see Assert::notNull()} method to
+ * > verify that a dependency is actually passed.
+ *
+ * This Factory also features a Service Locator component that is used to pass the right dependencies to the
+ * `create` method of a tag; each dependency should be registered as a service or as a parameter.
+ *
+ * When you want to use a Tag of your own with custom handling you need to call the `registerTagHandler` method, pass
+ * the name of the tag and a Fully Qualified Class Name pointing to a class that implements the Tag interface.
+ */
+final class StandardTagFactory implements TagFactory
+{
+ /** PCRE regular expression matching a tag name. */
+ const REGEX_TAGNAME = '[\w\-\_\\\\]+';
+
+ /**
+ * @var string[] An array with a tag as a key, and an FQCN to a class that handles it as an array value.
+ */
+ private $tagHandlerMappings = [
+ 'author' => '\phpDocumentor\Reflection\DocBlock\Tags\Author',
+ 'covers' => '\phpDocumentor\Reflection\DocBlock\Tags\Covers',
+ 'deprecated' => '\phpDocumentor\Reflection\DocBlock\Tags\Deprecated',
+ // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example',
+ 'link' => '\phpDocumentor\Reflection\DocBlock\Tags\Link',
+ 'method' => '\phpDocumentor\Reflection\DocBlock\Tags\Method',
+ 'param' => '\phpDocumentor\Reflection\DocBlock\Tags\Param',
+ 'property-read' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyRead',
+ 'property' => '\phpDocumentor\Reflection\DocBlock\Tags\Property',
+ 'property-write' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite',
+ 'return' => '\phpDocumentor\Reflection\DocBlock\Tags\Return_',
+ 'see' => '\phpDocumentor\Reflection\DocBlock\Tags\See',
+ 'since' => '\phpDocumentor\Reflection\DocBlock\Tags\Since',
+ 'source' => '\phpDocumentor\Reflection\DocBlock\Tags\Source',
+ 'throw' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws',
+ 'throws' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws',
+ 'uses' => '\phpDocumentor\Reflection\DocBlock\Tags\Uses',
+ 'var' => '\phpDocumentor\Reflection\DocBlock\Tags\Var_',
+ 'version' => '\phpDocumentor\Reflection\DocBlock\Tags\Version'
+ ];
+
+ /**
+ * @var \ReflectionParameter[][] a lazy-loading cache containing parameters for each tagHandler that has been used.
+ */
+ private $tagHandlerParameterCache = [];
+
+ /**
+ * @var FqsenResolver
+ */
+ private $fqsenResolver;
+
+ /**
+ * @var mixed[] an array representing a simple Service Locator where we can store parameters and
+ * services that can be inserted into the Factory Methods of Tag Handlers.
+ */
+ private $serviceLocator = [];
+
+ /**
+ * Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers.
+ *
+ * If no tag handlers are provided than the default list in the {@see self::$tagHandlerMappings} property
+ * is used.
+ *
+ * @param FqsenResolver $fqsenResolver
+ * @param string[] $tagHandlers
+ *
+ * @see self::registerTagHandler() to add a new tag handler to the existing default list.
+ */
+ public function __construct(FqsenResolver $fqsenResolver, array $tagHandlers = null)
+ {
+ $this->fqsenResolver = $fqsenResolver;
+ if ($tagHandlers !== null) {
+ $this->tagHandlerMappings = $tagHandlers;
+ }
+
+ $this->addService($fqsenResolver, FqsenResolver::class);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function create($tagLine, TypeContext $context = null)
+ {
+ if (! $context) {
+ $context = new TypeContext('');
+ }
+
+ list($tagName, $tagBody) = $this->extractTagParts($tagLine);
+
+ if ($tagBody !== '' && $tagBody[0] === '[') {
+ throw new \InvalidArgumentException(
+ 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors'
+ );
+ }
+
+ return $this->createTag($tagBody, $tagName, $context);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function addParameter($name, $value)
+ {
+ $this->serviceLocator[$name] = $value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function addService($service, $alias = null)
+ {
+ $this->serviceLocator[$alias ?: get_class($service)] = $service;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function registerTagHandler($tagName, $handler)
+ {
+ Assert::stringNotEmpty($tagName);
+ Assert::stringNotEmpty($handler);
+ Assert::classExists($handler);
+ Assert::implementsInterface($handler, StaticMethod::class);
+
+ if (strpos($tagName, '\\') && $tagName[0] !== '\\') {
+ throw new \InvalidArgumentException(
+ 'A namespaced tag must have a leading backslash as it must be fully qualified'
+ );
+ }
+
+ $this->tagHandlerMappings[$tagName] = $handler;
+ }
+
+ /**
+ * Extracts all components for a tag.
+ *
+ * @param string $tagLine
+ *
+ * @return string[]
+ */
+ private function extractTagParts($tagLine)
+ {
+ $matches = [];
+ if (! preg_match('/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)/us', $tagLine, $matches)) {
+ throw new \InvalidArgumentException(
+ 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors'
+ );
+ }
+
+ if (count($matches) < 3) {
+ $matches[] = '';
+ }
+
+ return array_slice($matches, 1);
+ }
+
+ /**
+ * Creates a new tag object with the given name and body or returns null if the tag name was recognized but the
+ * body was invalid.
+ *
+ * @param string $body
+ * @param string $name
+ * @param TypeContext $context
+ *
+ * @return Tag|null
+ */
+ private function createTag($body, $name, TypeContext $context)
+ {
+ $handlerClassName = $this->findHandlerClassName($name, $context);
+ $arguments = $this->getArgumentsForParametersFromWiring(
+ $this->fetchParametersForHandlerFactoryMethod($handlerClassName),
+ $this->getServiceLocatorWithDynamicParameters($context, $name, $body)
+ );
+
+ return call_user_func_array([$handlerClassName, 'create'], $arguments);
+ }
+
+ /**
+ * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`).
+ *
+ * @param string $tagName
+ * @param TypeContext $context
+ *
+ * @return string
+ */
+ private function findHandlerClassName($tagName, TypeContext $context)
+ {
+ $handlerClassName = Generic::class;
+ if (isset($this->tagHandlerMappings[$tagName])) {
+ $handlerClassName = $this->tagHandlerMappings[$tagName];
+ } elseif ($this->isAnnotation($tagName)) {
+ // TODO: Annotation support is planned for a later stage and as such is disabled for now
+ // $tagName = (string)$this->fqsenResolver->resolve($tagName, $context);
+ // if (isset($this->annotationMappings[$tagName])) {
+ // $handlerClassName = $this->annotationMappings[$tagName];
+ // }
+ }
+
+ return $handlerClassName;
+ }
+
+ /**
+ * Retrieves the arguments that need to be passed to the Factory Method with the given Parameters.
+ *
+ * @param \ReflectionParameter[] $parameters
+ * @param mixed[] $locator
+ *
+ * @return mixed[] A series of values that can be passed to the Factory Method of the tag whose parameters
+ * is provided with this method.
+ */
+ private function getArgumentsForParametersFromWiring($parameters, $locator)
+ {
+ $arguments = [];
+ foreach ($parameters as $index => $parameter) {
+ $typeHint = $parameter->getClass() ? $parameter->getClass()->getName() : null;
+ if (isset($locator[$typeHint])) {
+ $arguments[] = $locator[$typeHint];
+ continue;
+ }
+
+ $parameterName = $parameter->getName();
+ if (isset($locator[$parameterName])) {
+ $arguments[] = $locator[$parameterName];
+ continue;
+ }
+
+ $arguments[] = null;
+ }
+
+ return $arguments;
+ }
+
+ /**
+ * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given
+ * tag handler class name.
+ *
+ * @param string $handlerClassName
+ *
+ * @return \ReflectionParameter[]
+ */
+ private function fetchParametersForHandlerFactoryMethod($handlerClassName)
+ {
+ if (! isset($this->tagHandlerParameterCache[$handlerClassName])) {
+ $methodReflection = new \ReflectionMethod($handlerClassName, 'create');
+ $this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters();
+ }
+
+ return $this->tagHandlerParameterCache[$handlerClassName];
+ }
+
+ /**
+ * Returns a copy of this class' Service Locator with added dynamic parameters, such as the tag's name, body and
+ * Context.
+ *
+ * @param TypeContext $context The Context (namespace and aliasses) that may be passed and is used to resolve FQSENs.
+ * @param string $tagName The name of the tag that may be passed onto the factory method of the Tag class.
+ * @param string $tagBody The body of the tag that may be passed onto the factory method of the Tag class.
+ *
+ * @return mixed[]
+ */
+ private function getServiceLocatorWithDynamicParameters(TypeContext $context, $tagName, $tagBody)
+ {
+ $locator = array_merge(
+ $this->serviceLocator,
+ [
+ 'name' => $tagName,
+ 'body' => $tagBody,
+ TypeContext::class => $context
+ ]
+ );
+
+ return $locator;
+ }
+
+ /**
+ * Returns whether the given tag belongs to an annotation.
+ *
+ * @param string $tagContent
+ *
+ * @todo this method should be populated once we implement Annotation notation support.
+ *
+ * @return bool
+ */
+ private function isAnnotation($tagContent)
+ {
+ // 1. Contains a namespace separator
+ // 2. Contains parenthesis
+ // 3. Is present in a list of known annotations (make the algorithm smart by first checking is the last part
+ // of the annotation class name matches the found tag name
+
+ return false;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php
new file mode 100644
index 0000000..e765367
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php
@@ -0,0 +1,26 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+interface Tag
+{
+ public function getName();
+
+ public static function create($body);
+
+ public function render(Formatter $formatter = null);
+
+ public function __toString();
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php
new file mode 100644
index 0000000..3c1d113
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php
@@ -0,0 +1,93 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+
+interface TagFactory
+{
+ /**
+ * Adds a parameter to the service locator that can be injected in a tag's factory method.
+ *
+ * When calling a tag's "create" method we always check the signature for dependencies to inject. One way is to
+ * typehint a parameter in the signature so that we can use that interface or class name to inject a dependency
+ * (see {@see addService()} for more information on that).
+ *
+ * Another way is to check the name of the argument against the names in the Service Locator. With this method
+ * you can add a variable that will be inserted when a tag's create method is not typehinted and has a matching
+ * name.
+ *
+ * Be aware that there are two reserved names:
+ *
+ * - name, representing the name of the tag.
+ * - body, representing the complete body of the tag.
+ *
+ * These parameters are injected at the last moment and will override any existing parameter with those names.
+ *
+ * @param string $name
+ * @param mixed $value
+ *
+ * @return void
+ */
+ public function addParameter($name, $value);
+
+ /**
+ * Registers a service with the Service Locator using the FQCN of the class or the alias, if provided.
+ *
+ * When calling a tag's "create" method we always check the signature for dependencies to inject. If a parameter
+ * has a typehint then the ServiceLocator is queried to see if a Service is registered for that typehint.
+ *
+ * Because interfaces are regularly used as type-hints this method provides an alias parameter; if the FQCN of the
+ * interface is passed as alias then every time that interface is requested the provided service will be returned.
+ *
+ * @param object $service
+ * @param string $alias
+ *
+ * @return void
+ */
+ public function addService($service);
+
+ /**
+ * Factory method responsible for instantiating the correct sub type.
+ *
+ * @param string $tagLine The text for this tag, including description.
+ * @param TypeContext $context
+ *
+ * @throws \InvalidArgumentException if an invalid tag line was presented.
+ *
+ * @return Tag A new tag object.
+ */
+ public function create($tagLine, TypeContext $context = null);
+
+ /**
+ * Registers a handler for tags.
+ *
+ * If you want to use your own tags then you can use this method to instruct the TagFactory to register the name
+ * of a tag with the FQCN of a 'Tag Handler'. The Tag handler should implement the {@see Tag} interface (and thus
+ * the create method).
+ *
+ * @param string $tagName Name of tag to register a handler for. When registering a namespaced tag, the full
+ * name, along with a prefixing slash MUST be provided.
+ * @param string $handler FQCN of handler.
+ *
+ * @throws \InvalidArgumentException if the tag name is not a string
+ * @throws \InvalidArgumentException if the tag name is namespaced (contains backslashes) but does not start with
+ * a backslash
+ * @throws \InvalidArgumentException if the handler is not a string
+ * @throws \InvalidArgumentException if the handler is not an existing class
+ * @throws \InvalidArgumentException if the handler does not implement the {@see Tag} interface
+ *
+ * @return void
+ */
+ public function registerTagHandler($tagName, $handler);
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php
new file mode 100644
index 0000000..29d7f1d
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php
@@ -0,0 +1,100 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for an {@}author tag in a Docblock.
+ */
+final class Author extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string register that this is the author tag. */
+ protected $name = 'author';
+
+ /** @var string The name of the author */
+ private $authorName = '';
+
+ /** @var string The email of the author */
+ private $authorEmail = '';
+
+ /**
+ * Initializes this tag with the author name and e-mail.
+ *
+ * @param string $authorName
+ * @param string $authorEmail
+ */
+ public function __construct($authorName, $authorEmail)
+ {
+ Assert::string($authorName);
+ Assert::string($authorEmail);
+ if ($authorEmail && !filter_var($authorEmail, FILTER_VALIDATE_EMAIL)) {
+ throw new \InvalidArgumentException('The author tag does not have a valid e-mail address');
+ }
+
+ $this->authorName = $authorName;
+ $this->authorEmail = $authorEmail;
+ }
+
+ /**
+ * Gets the author's name.
+ *
+ * @return string The author's name.
+ */
+ public function getAuthorName()
+ {
+ return $this->authorName;
+ }
+
+ /**
+ * Returns the author's email.
+ *
+ * @return string The author's email.
+ */
+ public function getEmail()
+ {
+ return $this->authorEmail;
+ }
+
+ /**
+ * Returns this tag in string form.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->authorName . (strlen($this->authorEmail) ? ' <' . $this->authorEmail . '>' : '');
+ }
+
+ /**
+ * Attempts to create a new Author object based on †he tag body.
+ *
+ * @param string $body
+ *
+ * @return static
+ */
+ public static function create($body)
+ {
+ Assert::string($body);
+
+ $splitTagContent = preg_match('/^([^\<]*)(?:\<([^\>]*)\>)?$/u', $body, $matches);
+ if (!$splitTagContent) {
+ return null;
+ }
+
+ $authorName = trim($matches[1]);
+ $email = isset($matches[2]) ? trim($matches[2]) : '';
+
+ return new static($authorName, $email);
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php
new file mode 100644
index 0000000..14bb717
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php
@@ -0,0 +1,52 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock;
+use phpDocumentor\Reflection\DocBlock\Description;
+
+/**
+ * Parses a tag definition for a DocBlock.
+ */
+abstract class BaseTag implements DocBlock\Tag
+{
+ /** @var string Name of the tag */
+ protected $name = '';
+
+ /** @var Description|null Description of the tag. */
+ protected $description;
+
+ /**
+ * Gets the name of this tag.
+ *
+ * @return string The name of this tag.
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ public function render(Formatter $formatter = null)
+ {
+ if ($formatter === null) {
+ $formatter = new Formatter\PassthroughFormatter();
+ }
+
+ return $formatter->format($this);
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php
new file mode 100644
index 0000000..8d65403
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php
@@ -0,0 +1,83 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a @covers tag in a Docblock.
+ */
+final class Covers extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'covers';
+
+ /** @var Fqsen */
+ private $refers = null;
+
+ /**
+ * Initializes this tag.
+ *
+ * @param Fqsen $refers
+ * @param Description $description
+ */
+ public function __construct(Fqsen $refers, Description $description = null)
+ {
+ $this->refers = $refers;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ DescriptionFactory $descriptionFactory = null,
+ FqsenResolver $resolver = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::notEmpty($body);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+
+ return new static(
+ $resolver->resolve($parts[0], $context),
+ $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context)
+ );
+ }
+
+ /**
+ * Returns the structural element this tag refers to.
+ *
+ * @return Fqsen
+ */
+ public function getReference()
+ {
+ return $this->refers;
+ }
+
+ /**
+ * Returns a string representation of this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->refers . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php
new file mode 100644
index 0000000..822c305
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php
@@ -0,0 +1,97 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}deprecated tag in a Docblock.
+ */
+final class Deprecated extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'deprecated';
+
+ /**
+ * PCRE regular expression matching a version vector.
+ * Assumes the "x" modifier.
+ */
+ const REGEX_VECTOR = '(?:
+ # Normal release vectors.
+ \d\S*
+ |
+ # VCS version vectors. Per PHPCS, they are expected to
+ # follow the form of the VCS name, followed by ":", followed
+ # by the version vector itself.
+ # By convention, popular VCSes like CVS, SVN and GIT use "$"
+ # around the actual version vector.
+ [^\s\:]+\:\s*\$[^\$]+\$
+ )';
+
+ /** @var string The version vector. */
+ private $version = '';
+
+ public function __construct($version = null, Description $description = null)
+ {
+ Assert::nullOrStringNotEmpty($version);
+
+ $this->version = $version;
+ $this->description = $description;
+ }
+
+ /**
+ * @return static
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::nullOrString($body);
+ if (empty($body)) {
+ return new static();
+ }
+
+ $matches = [];
+ if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) {
+ return new static(
+ null,
+ null !== $descriptionFactory ? $descriptionFactory->create($body, $context) : null
+ );
+ }
+
+ return new static(
+ $matches[1],
+ $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context)
+ );
+ }
+
+ /**
+ * Gets the version section of the tag.
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->version . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php
new file mode 100644
index 0000000..ecb199b
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php
@@ -0,0 +1,176 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}example tag in a Docblock.
+ */
+final class Example extends BaseTag
+{
+ /**
+ * @var string Path to a file to use as an example. May also be an absolute URI.
+ */
+ private $filePath;
+
+ /**
+ * @var bool Whether the file path component represents an URI. This determines how the file portion
+ * appears at {@link getContent()}.
+ */
+ private $isURI = false;
+
+ /**
+ * @var int
+ */
+ private $startingLine;
+
+ /**
+ * @var int
+ */
+ private $lineCount;
+
+ public function __construct($filePath, $isURI, $startingLine, $lineCount, $description)
+ {
+ Assert::notEmpty($filePath);
+ Assert::integer($startingLine);
+ Assert::greaterThanEq($startingLine, 0);
+
+ $this->filePath = $filePath;
+ $this->startingLine = $startingLine;
+ $this->lineCount = $lineCount;
+ $this->name = 'example';
+ if ($description !== null) {
+ $this->description = trim($description);
+ }
+
+ $this->isURI = $isURI;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContent()
+ {
+ if (null === $this->description) {
+ $filePath = '"' . $this->filePath . '"';
+ if ($this->isURI) {
+ $filePath = $this->isUriRelative($this->filePath)
+ ? str_replace('%2F', '/', rawurlencode($this->filePath))
+ :$this->filePath;
+ }
+
+ return trim($filePath . ' ' . parent::getDescription());
+ }
+
+ return $this->description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create($body)
+ {
+ // File component: File path in quotes or File URI / Source information
+ if (! preg_match('/^(?:\"([^\"]+)\"|(\S+))(?:\s+(.*))?$/sux', $body, $matches)) {
+ return null;
+ }
+
+ $filePath = null;
+ $fileUri = null;
+ if ('' !== $matches[1]) {
+ $filePath = $matches[1];
+ } else {
+ $fileUri = $matches[2];
+ }
+
+ $startingLine = 1;
+ $lineCount = null;
+ $description = null;
+
+ if (array_key_exists(3, $matches)) {
+ $description = $matches[3];
+
+ // Starting line / Number of lines / Description
+ if (preg_match('/^([1-9]\d*)(?:\s+((?1))\s*)?(.*)$/sux', $matches[3], $contentMatches)) {
+ $startingLine = (int)$contentMatches[1];
+ if (isset($contentMatches[2]) && $contentMatches[2] !== '') {
+ $lineCount = (int)$contentMatches[2];
+ }
+
+ if (array_key_exists(3, $contentMatches)) {
+ $description = $contentMatches[3];
+ }
+ }
+ }
+
+ return new static(
+ $filePath !== null?$filePath:$fileUri,
+ $fileUri !== null,
+ $startingLine,
+ $lineCount,
+ $description
+ );
+ }
+
+ /**
+ * Returns the file path.
+ *
+ * @return string Path to a file to use as an example.
+ * May also be an absolute URI.
+ */
+ public function getFilePath()
+ {
+ return $this->filePath;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->filePath . ($this->description ? ' ' . $this->description : '');
+ }
+
+ /**
+ * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute).
+ *
+ * @param string $uri
+ *
+ * @return bool
+ */
+ private function isUriRelative($uri)
+ {
+ return false === strpos($uri, ':');
+ }
+
+ /**
+ * @return int
+ */
+ public function getStartingLine()
+ {
+ return $this->startingLine;
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineCount()
+ {
+ return $this->lineCount;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php
new file mode 100644
index 0000000..98aea45
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php
@@ -0,0 +1,18 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+interface StaticMethod
+{
+ public static function create($body);
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php
new file mode 100644
index 0000000..b9ca0b8
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php
@@ -0,0 +1,18 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+interface Strategy
+{
+ public function create($body);
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php
new file mode 100644
index 0000000..64b2c60
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php
@@ -0,0 +1,27 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+
+interface Formatter
+{
+ /**
+ * Formats a tag into a string representation according to a specific format, such as Markdown.
+ *
+ * @param Tag $tag
+ *
+ * @return string
+ */
+ public function format(Tag $tag);
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php
new file mode 100644
index 0000000..ceb40cc
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php
@@ -0,0 +1,47 @@
+
+ * @copyright 2017 Mike van Riel
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+class AlignFormatter implements Formatter
+{
+ /** @var int The maximum tag name length. */
+ protected $maxLen = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param Tag[] $tags All tags that should later be aligned with the formatter.
+ */
+ public function __construct(array $tags)
+ {
+ foreach ($tags as $tag) {
+ $this->maxLen = max($this->maxLen, strlen($tag->getName()));
+ }
+ }
+
+ /**
+ * Formats the given tag to return a simple plain text version.
+ *
+ * @param Tag $tag
+ *
+ * @return string
+ */
+ public function format(Tag $tag)
+ {
+ return '@' . $tag->getName() . str_repeat(' ', $this->maxLen - strlen($tag->getName()) + 1) . (string)$tag;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php
new file mode 100644
index 0000000..4e2c576
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+class PassthroughFormatter implements Formatter
+{
+ /**
+ * Formats the given tag to return a simple plain text version.
+ *
+ * @param Tag $tag
+ *
+ * @return string
+ */
+ public function format(Tag $tag)
+ {
+ return trim('@' . $tag->getName() . ' ' . (string)$tag);
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php
new file mode 100644
index 0000000..e4c53e0
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php
@@ -0,0 +1,91 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Parses a tag definition for a DocBlock.
+ */
+class Generic extends BaseTag implements Factory\StaticMethod
+{
+ /**
+ * Parses a tag and populates the member variables.
+ *
+ * @param string $name Name of the tag.
+ * @param Description $description The contents of the given tag.
+ */
+ public function __construct($name, Description $description = null)
+ {
+ $this->validateTagName($name);
+
+ $this->name = $name;
+ $this->description = $description;
+ }
+
+ /**
+ * Creates a new tag that represents any unknown tag type.
+ *
+ * @param string $body
+ * @param string $name
+ * @param DescriptionFactory $descriptionFactory
+ * @param TypeContext $context
+ *
+ * @return static
+ */
+ public static function create(
+ $body,
+ $name = '',
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::stringNotEmpty($name);
+ Assert::notNull($descriptionFactory);
+
+ $description = $descriptionFactory && $body ? $descriptionFactory->create($body, $context) : null;
+
+ return new static($name, $description);
+ }
+
+ /**
+ * Returns the tag as a serialized string
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->description ? $this->description->render() : '');
+ }
+
+ /**
+ * Validates if the tag name matches the expected format, otherwise throws an exception.
+ *
+ * @param string $name
+ *
+ * @return void
+ */
+ private function validateTagName($name)
+ {
+ if (! preg_match('/^' . StandardTagFactory::REGEX_TAGNAME . '$/u', $name)) {
+ throw new \InvalidArgumentException(
+ 'The tag name "' . $name . '" is not wellformed. Tags may only consist of letters, underscores, '
+ . 'hyphens and backslashes.'
+ );
+ }
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php
new file mode 100644
index 0000000..9c0e367
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php
@@ -0,0 +1,77 @@
+
+ * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a @link tag in a Docblock.
+ */
+final class Link extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'link';
+
+ /** @var string */
+ private $link = '';
+
+ /**
+ * Initializes a link to a URL.
+ *
+ * @param string $link
+ * @param Description $description
+ */
+ public function __construct($link, Description $description = null)
+ {
+ Assert::string($link);
+
+ $this->link = $link;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::string($body);
+ Assert::notNull($descriptionFactory);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+ $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
+
+ return new static($parts[0], $description);
+ }
+
+ /**
+ * Gets the link
+ *
+ * @return string
+ */
+ public function getLink()
+ {
+ return $this->link;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->link . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php
new file mode 100644
index 0000000..7522529
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php
@@ -0,0 +1,242 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use phpDocumentor\Reflection\Types\Void_;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for an {@}method in a Docblock.
+ */
+final class Method extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'method';
+
+ /** @var string */
+ private $methodName = '';
+
+ /** @var string[] */
+ private $arguments = [];
+
+ /** @var bool */
+ private $isStatic = false;
+
+ /** @var Type */
+ private $returnType;
+
+ public function __construct(
+ $methodName,
+ array $arguments = [],
+ Type $returnType = null,
+ $static = false,
+ Description $description = null
+ ) {
+ Assert::stringNotEmpty($methodName);
+ Assert::boolean($static);
+
+ if ($returnType === null) {
+ $returnType = new Void_();
+ }
+
+ $this->methodName = $methodName;
+ $this->arguments = $this->filterArguments($arguments);
+ $this->returnType = $returnType;
+ $this->isStatic = $static;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([ $typeResolver, $descriptionFactory ]);
+
+ // 1. none or more whitespace
+ // 2. optionally the keyword "static" followed by whitespace
+ // 3. optionally a word with underscores followed by whitespace : as
+ // type for the return value
+ // 4. then optionally a word with underscores followed by () and
+ // whitespace : as method name as used by phpDocumentor
+ // 5. then a word with underscores, followed by ( and any character
+ // until a ) and whitespace : as method name with signature
+ // 6. any remaining text : as description
+ if (!preg_match(
+ '/^
+ # Static keyword
+ # Declares a static method ONLY if type is also present
+ (?:
+ (static)
+ \s+
+ )?
+ # Return type
+ (?:
+ (
+ (?:[\w\|_\\\\]*\$this[\w\|_\\\\]*)
+ |
+ (?:
+ (?:[\w\|_\\\\]+)
+ # array notation
+ (?:\[\])*
+ )*
+ )
+ \s+
+ )?
+ # Legacy method name (not captured)
+ (?:
+ [\w_]+\(\)\s+
+ )?
+ # Method name
+ ([\w\|_\\\\]+)
+ # Arguments
+ (?:
+ \(([^\)]*)\)
+ )?
+ \s*
+ # Description
+ (.*)
+ $/sux',
+ $body,
+ $matches
+ )) {
+ return null;
+ }
+
+ list(, $static, $returnType, $methodName, $arguments, $description) = $matches;
+
+ $static = $static === 'static';
+
+ if ($returnType === '') {
+ $returnType = 'void';
+ }
+
+ $returnType = $typeResolver->resolve($returnType, $context);
+ $description = $descriptionFactory->create($description, $context);
+
+ if (is_string($arguments) && strlen($arguments) > 0) {
+ $arguments = explode(',', $arguments);
+ foreach ($arguments as &$argument) {
+ $argument = explode(' ', self::stripRestArg(trim($argument)), 2);
+ if ($argument[0][0] === '$') {
+ $argumentName = substr($argument[0], 1);
+ $argumentType = new Void_();
+ } else {
+ $argumentType = $typeResolver->resolve($argument[0], $context);
+ $argumentName = '';
+ if (isset($argument[1])) {
+ $argument[1] = self::stripRestArg($argument[1]);
+ $argumentName = substr($argument[1], 1);
+ }
+ }
+
+ $argument = [ 'name' => $argumentName, 'type' => $argumentType];
+ }
+ } else {
+ $arguments = [];
+ }
+
+ return new static($methodName, $arguments, $returnType, $static, $description);
+ }
+
+ /**
+ * Retrieves the method name.
+ *
+ * @return string
+ */
+ public function getMethodName()
+ {
+ return $this->methodName;
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ /**
+ * Checks whether the method tag describes a static method or not.
+ *
+ * @return bool TRUE if the method declaration is for a static method, FALSE otherwise.
+ */
+ public function isStatic()
+ {
+ return $this->isStatic;
+ }
+
+ /**
+ * @return Type
+ */
+ public function getReturnType()
+ {
+ return $this->returnType;
+ }
+
+ public function __toString()
+ {
+ $arguments = [];
+ foreach ($this->arguments as $argument) {
+ $arguments[] = $argument['type'] . ' $' . $argument['name'];
+ }
+
+ return trim(($this->isStatic() ? 'static ' : '')
+ . (string)$this->returnType . ' '
+ . $this->methodName
+ . '(' . implode(', ', $arguments) . ')'
+ . ($this->description ? ' ' . $this->description->render() : ''));
+ }
+
+ private function filterArguments($arguments)
+ {
+ foreach ($arguments as &$argument) {
+ if (is_string($argument)) {
+ $argument = [ 'name' => $argument ];
+ }
+
+ if (! isset($argument['type'])) {
+ $argument['type'] = new Void_();
+ }
+
+ $keys = array_keys($argument);
+ sort($keys);
+ if ($keys !== [ 'name', 'type' ]) {
+ throw new \InvalidArgumentException(
+ 'Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, true)
+ );
+ }
+ }
+
+ return $arguments;
+ }
+
+ private static function stripRestArg($argument)
+ {
+ if (strpos($argument, '...') === 0) {
+ $argument = trim(substr($argument, 3));
+ }
+
+ return $argument;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php
new file mode 100644
index 0000000..7d699d8
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php
@@ -0,0 +1,141 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for the {@}param tag in a Docblock.
+ */
+final class Param extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'param';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ private $variableName = '';
+
+ /** @var bool determines whether this is a variadic argument */
+ private $isVariadic = false;
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param bool $isVariadic
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, $isVariadic = false, Description $description = null)
+ {
+ Assert::string($variableName);
+ Assert::boolean($isVariadic);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->isVariadic = $isVariadic;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+ $isVariadic = false;
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$' || substr($parts[0], 0, 4) === '...$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 3) === '...') {
+ $isVariadic = true;
+ $variableName = substr($variableName, 3);
+ }
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $isVariadic, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns whether this tag is variadic.
+ *
+ * @return boolean
+ */
+ public function isVariadic()
+ {
+ return $this->isVariadic;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . ($this->isVariadic() ? '...' : '')
+ . '$' . $this->variableName
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php
new file mode 100644
index 0000000..f0ef7c0
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php
@@ -0,0 +1,118 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}property tag in a Docblock.
+ */
+class Property extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'property';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ protected $variableName = '';
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, Description $description = null)
+ {
+ Assert::string($variableName);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . '$' . $this->variableName
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php
new file mode 100644
index 0000000..e41c0c1
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php
@@ -0,0 +1,118 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}property-read tag in a Docblock.
+ */
+class PropertyRead extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'property-read';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ protected $variableName = '';
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, Description $description = null)
+ {
+ Assert::string($variableName);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . '$' . $this->variableName
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php
new file mode 100644
index 0000000..cfdb0ed
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php
@@ -0,0 +1,118 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}property-write tag in a Docblock.
+ */
+class PropertyWrite extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'property-write';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ protected $variableName = '';
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, Description $description = null)
+ {
+ Assert::string($variableName);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . '$' . $this->variableName
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php
new file mode 100644
index 0000000..dc7b8b6
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php
@@ -0,0 +1,42 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Reference;
+
+use phpDocumentor\Reflection\Fqsen as RealFqsen;
+
+/**
+ * Fqsen reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See}
+ */
+final class Fqsen implements Reference
+{
+ /**
+ * @var RealFqsen
+ */
+ private $fqsen;
+
+ /**
+ * Fqsen constructor.
+ */
+ public function __construct(RealFqsen $fqsen)
+ {
+ $this->fqsen = $fqsen;
+ }
+
+ /**
+ * @return string string representation of the referenced fqsen
+ */
+ public function __toString()
+ {
+ return (string)$this->fqsen;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php
new file mode 100644
index 0000000..a3ffd24
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php
@@ -0,0 +1,21 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Reference;
+
+/**
+ * Interface for references in {@see phpDocumentor\Reflection\DocBlock\Tags\See}
+ */
+interface Reference
+{
+ public function __toString();
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php
new file mode 100644
index 0000000..2671d5e
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php
@@ -0,0 +1,40 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Reference;
+
+use Webmozart\Assert\Assert;
+
+/**
+ * Url reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See}
+ */
+final class Url implements Reference
+{
+ /**
+ * @var string
+ */
+ private $uri;
+
+ /**
+ * Url constructor.
+ */
+ public function __construct($uri)
+ {
+ Assert::stringNotEmpty($uri);
+ $this->uri = $uri;
+ }
+
+ public function __toString()
+ {
+ return $this->uri;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php
new file mode 100644
index 0000000..ca5bda7
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php
@@ -0,0 +1,72 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}return tag in a Docblock.
+ */
+final class Return_ extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'return';
+
+ /** @var Type */
+ private $type;
+
+ public function __construct(Type $type, Description $description = null)
+ {
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+
+ $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context);
+ $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context);
+
+ return new static($type, $description);
+ }
+
+ /**
+ * Returns the type section of the variable.
+ *
+ * @return Type
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ public function __toString()
+ {
+ return $this->type . ' ' . $this->description;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php
new file mode 100644
index 0000000..9e9e723
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php
@@ -0,0 +1,88 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef;
+use phpDocumentor\Reflection\DocBlock\Tags\Reference\Reference;
+use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for an {@}see tag in a Docblock.
+ */
+class See extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'see';
+
+ /** @var Reference */
+ protected $refers = null;
+
+ /**
+ * Initializes this tag.
+ *
+ * @param Reference $refers
+ * @param Description $description
+ */
+ public function __construct(Reference $refers, Description $description = null)
+ {
+ $this->refers = $refers;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ FqsenResolver $resolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::allNotNull([$resolver, $descriptionFactory]);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+ $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
+
+ // https://tools.ietf.org/html/rfc2396#section-3
+ if (preg_match('/\w:\/\/\w/i', $parts[0])) {
+ return new static(new Url($parts[0]), $description);
+ }
+
+ return new static(new FqsenRef($resolver->resolve($parts[0], $context)), $description);
+ }
+
+ /**
+ * Returns the ref of this tag.
+ *
+ * @return Reference
+ */
+ public function getReference()
+ {
+ return $this->refers;
+ }
+
+ /**
+ * Returns a string representation of this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->refers . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php
new file mode 100644
index 0000000..835fb0d
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php
@@ -0,0 +1,94 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}since tag in a Docblock.
+ */
+final class Since extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'since';
+
+ /**
+ * PCRE regular expression matching a version vector.
+ * Assumes the "x" modifier.
+ */
+ const REGEX_VECTOR = '(?:
+ # Normal release vectors.
+ \d\S*
+ |
+ # VCS version vectors. Per PHPCS, they are expected to
+ # follow the form of the VCS name, followed by ":", followed
+ # by the version vector itself.
+ # By convention, popular VCSes like CVS, SVN and GIT use "$"
+ # around the actual version vector.
+ [^\s\:]+\:\s*\$[^\$]+\$
+ )';
+
+ /** @var string The version vector. */
+ private $version = '';
+
+ public function __construct($version = null, Description $description = null)
+ {
+ Assert::nullOrStringNotEmpty($version);
+
+ $this->version = $version;
+ $this->description = $description;
+ }
+
+ /**
+ * @return static
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::nullOrString($body);
+ if (empty($body)) {
+ return new static();
+ }
+
+ $matches = [];
+ if (! preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) {
+ return null;
+ }
+
+ return new static(
+ $matches[1],
+ $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context)
+ );
+ }
+
+ /**
+ * Gets the version section of the tag.
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->version . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php
new file mode 100644
index 0000000..247b1b3
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php
@@ -0,0 +1,97 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}source tag in a Docblock.
+ */
+final class Source extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'source';
+
+ /** @var int The starting line, relative to the structural element's location. */
+ private $startingLine = 1;
+
+ /** @var int|null The number of lines, relative to the starting line. NULL means "to the end". */
+ private $lineCount = null;
+
+ public function __construct($startingLine, $lineCount = null, Description $description = null)
+ {
+ Assert::integerish($startingLine);
+ Assert::nullOrIntegerish($lineCount);
+
+ $this->startingLine = (int)$startingLine;
+ $this->lineCount = $lineCount !== null ? (int)$lineCount : null;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::stringNotEmpty($body);
+ Assert::notNull($descriptionFactory);
+
+ $startingLine = 1;
+ $lineCount = null;
+ $description = null;
+
+ // Starting line / Number of lines / Description
+ if (preg_match('/^([1-9]\d*)\s*(?:((?1))\s+)?(.*)$/sux', $body, $matches)) {
+ $startingLine = (int)$matches[1];
+ if (isset($matches[2]) && $matches[2] !== '') {
+ $lineCount = (int)$matches[2];
+ }
+
+ $description = $matches[3];
+ }
+
+ return new static($startingLine, $lineCount, $descriptionFactory->create($description, $context));
+ }
+
+ /**
+ * Gets the starting line.
+ *
+ * @return int The starting line, relative to the structural element's
+ * location.
+ */
+ public function getStartingLine()
+ {
+ return $this->startingLine;
+ }
+
+ /**
+ * Returns the number of lines.
+ *
+ * @return int|null The number of lines, relative to the starting line. NULL
+ * means "to the end".
+ */
+ public function getLineCount()
+ {
+ return $this->lineCount;
+ }
+
+ public function __toString()
+ {
+ return $this->startingLine
+ . ($this->lineCount !== null ? ' ' . $this->lineCount : '')
+ . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php
new file mode 100644
index 0000000..349e773
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php
@@ -0,0 +1,72 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}throws tag in a Docblock.
+ */
+final class Throws extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'throws';
+
+ /** @var Type */
+ private $type;
+
+ public function __construct(Type $type, Description $description = null)
+ {
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+
+ $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context);
+ $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context);
+
+ return new static($type, $description);
+ }
+
+ /**
+ * Returns the type section of the variable.
+ *
+ * @return Type
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ public function __toString()
+ {
+ return $this->type . ' ' . $this->description;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php
new file mode 100644
index 0000000..00dc3e3
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php
@@ -0,0 +1,83 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}uses tag in a Docblock.
+ */
+final class Uses extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'uses';
+
+ /** @var Fqsen */
+ protected $refers = null;
+
+ /**
+ * Initializes this tag.
+ *
+ * @param Fqsen $refers
+ * @param Description $description
+ */
+ public function __construct(Fqsen $refers, Description $description = null)
+ {
+ $this->refers = $refers;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ FqsenResolver $resolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::allNotNull([$resolver, $descriptionFactory]);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+
+ return new static(
+ $resolver->resolve($parts[0], $context),
+ $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context)
+ );
+ }
+
+ /**
+ * Returns the structural element this tag refers to.
+ *
+ * @return Fqsen
+ */
+ public function getReference()
+ {
+ return $this->refers;
+ }
+
+ /**
+ * Returns a string representation of this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->refers . ' ' . $this->description->render();
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php
new file mode 100644
index 0000000..8907c95
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php
@@ -0,0 +1,118 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}var tag in a Docblock.
+ */
+class Var_ extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'var';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ protected $variableName = '';
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, Description $description = null)
+ {
+ Assert::string($variableName);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . (empty($this->variableName) ? null : ('$' . $this->variableName))
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php
new file mode 100644
index 0000000..7bb0420
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php
@@ -0,0 +1,94 @@
+
+ * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}version tag in a Docblock.
+ */
+final class Version extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'version';
+
+ /**
+ * PCRE regular expression matching a version vector.
+ * Assumes the "x" modifier.
+ */
+ const REGEX_VECTOR = '(?:
+ # Normal release vectors.
+ \d\S*
+ |
+ # VCS version vectors. Per PHPCS, they are expected to
+ # follow the form of the VCS name, followed by ":", followed
+ # by the version vector itself.
+ # By convention, popular VCSes like CVS, SVN and GIT use "$"
+ # around the actual version vector.
+ [^\s\:]+\:\s*\$[^\$]+\$
+ )';
+
+ /** @var string The version vector. */
+ private $version = '';
+
+ public function __construct($version = null, Description $description = null)
+ {
+ Assert::nullOrStringNotEmpty($version);
+
+ $this->version = $version;
+ $this->description = $description;
+ }
+
+ /**
+ * @return static
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::nullOrString($body);
+ if (empty($body)) {
+ return new static();
+ }
+
+ $matches = [];
+ if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) {
+ return null;
+ }
+
+ return new static(
+ $matches[1],
+ $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context)
+ );
+ }
+
+ /**
+ * Gets the version section of the tag.
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->version . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php
new file mode 100644
index 0000000..1bdb8f4
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php
@@ -0,0 +1,277 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\TagFactory;
+use Webmozart\Assert\Assert;
+
+final class DocBlockFactory implements DocBlockFactoryInterface
+{
+ /** @var DocBlock\DescriptionFactory */
+ private $descriptionFactory;
+
+ /** @var DocBlock\TagFactory */
+ private $tagFactory;
+
+ /**
+ * Initializes this factory with the required subcontractors.
+ *
+ * @param DescriptionFactory $descriptionFactory
+ * @param TagFactory $tagFactory
+ */
+ public function __construct(DescriptionFactory $descriptionFactory, TagFactory $tagFactory)
+ {
+ $this->descriptionFactory = $descriptionFactory;
+ $this->tagFactory = $tagFactory;
+ }
+
+ /**
+ * Factory method for easy instantiation.
+ *
+ * @param string[] $additionalTags
+ *
+ * @return DocBlockFactory
+ */
+ public static function createInstance(array $additionalTags = [])
+ {
+ $fqsenResolver = new FqsenResolver();
+ $tagFactory = new StandardTagFactory($fqsenResolver);
+ $descriptionFactory = new DescriptionFactory($tagFactory);
+
+ $tagFactory->addService($descriptionFactory);
+ $tagFactory->addService(new TypeResolver($fqsenResolver));
+
+ $docBlockFactory = new self($descriptionFactory, $tagFactory);
+ foreach ($additionalTags as $tagName => $tagHandler) {
+ $docBlockFactory->registerTagHandler($tagName, $tagHandler);
+ }
+
+ return $docBlockFactory;
+ }
+
+ /**
+ * @param object|string $docblock A string containing the DocBlock to parse or an object supporting the
+ * getDocComment method (such as a ReflectionClass object).
+ * @param Types\Context $context
+ * @param Location $location
+ *
+ * @return DocBlock
+ */
+ public function create($docblock, Types\Context $context = null, Location $location = null)
+ {
+ if (is_object($docblock)) {
+ if (!method_exists($docblock, 'getDocComment')) {
+ $exceptionMessage = 'Invalid object passed; the given object must support the getDocComment method';
+ throw new \InvalidArgumentException($exceptionMessage);
+ }
+
+ $docblock = $docblock->getDocComment();
+ }
+
+ Assert::stringNotEmpty($docblock);
+
+ if ($context === null) {
+ $context = new Types\Context('');
+ }
+
+ $parts = $this->splitDocBlock($this->stripDocComment($docblock));
+ list($templateMarker, $summary, $description, $tags) = $parts;
+
+ return new DocBlock(
+ $summary,
+ $description ? $this->descriptionFactory->create($description, $context) : null,
+ array_filter($this->parseTagBlock($tags, $context), function ($tag) {
+ return $tag instanceof Tag;
+ }),
+ $context,
+ $location,
+ $templateMarker === '#@+',
+ $templateMarker === '#@-'
+ );
+ }
+
+ public function registerTagHandler($tagName, $handler)
+ {
+ $this->tagFactory->registerTagHandler($tagName, $handler);
+ }
+
+ /**
+ * Strips the asterisks from the DocBlock comment.
+ *
+ * @param string $comment String containing the comment text.
+ *
+ * @return string
+ */
+ private function stripDocComment($comment)
+ {
+ $comment = trim(preg_replace('#[ \t]*(?:\/\*\*|\*\/|\*)?[ \t]{0,1}(.*)?#u', '$1', $comment));
+
+ // reg ex above is not able to remove */ from a single line docblock
+ if (substr($comment, -2) === '*/') {
+ $comment = trim(substr($comment, 0, -2));
+ }
+
+ return str_replace(["\r\n", "\r"], "\n", $comment);
+ }
+
+ /**
+ * Splits the DocBlock into a template marker, summary, description and block of tags.
+ *
+ * @param string $comment Comment to split into the sub-parts.
+ *
+ * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split.
+ * @author Mike van Riel for extending the regex with template marker support.
+ *
+ * @return string[] containing the template marker (if any), summary, description and a string containing the tags.
+ */
+ private function splitDocBlock($comment)
+ {
+ // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This
+ // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the
+ // performance impact of running a regular expression
+ if (strpos($comment, '@') === 0) {
+ return ['', '', '', $comment];
+ }
+
+ // clears all extra horizontal whitespace from the line endings to prevent parsing issues
+ $comment = preg_replace('/\h*$/Sum', '', $comment);
+
+ /*
+ * Splits the docblock into a template marker, summary, description and tags section.
+ *
+ * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may
+ * occur after it and will be stripped).
+ * - The short description is started from the first character until a dot is encountered followed by a
+ * newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing
+ * errors). This is optional.
+ * - The long description, any character until a new line is encountered followed by an @ and word
+ * characters (a tag). This is optional.
+ * - Tags; the remaining characters
+ *
+ * Big thanks to RichardJ for contributing this Regular Expression
+ */
+ preg_match(
+ '/
+ \A
+ # 1. Extract the template marker
+ (?:(\#\@\+|\#\@\-)\n?)?
+
+ # 2. Extract the summary
+ (?:
+ (?! @\pL ) # The summary may not start with an @
+ (
+ [^\n.]+
+ (?:
+ (?! \. \n | \n{2} ) # End summary upon a dot followed by newline or two newlines
+ [\n.] (?! [ \t]* @\pL ) # End summary when an @ is found as first character on a new line
+ [^\n.]+ # Include anything else
+ )*
+ \.?
+ )?
+ )
+
+ # 3. Extract the description
+ (?:
+ \s* # Some form of whitespace _must_ precede a description because a summary must be there
+ (?! @\pL ) # The description may not start with an @
+ (
+ [^\n]+
+ (?: \n+
+ (?! [ \t]* @\pL ) # End description when an @ is found as first character on a new line
+ [^\n]+ # Include anything else
+ )*
+ )
+ )?
+
+ # 4. Extract the tags (anything that follows)
+ (\s+ [\s\S]*)? # everything that follows
+ /ux',
+ $comment,
+ $matches
+ );
+ array_shift($matches);
+
+ while (count($matches) < 4) {
+ $matches[] = '';
+ }
+
+ return $matches;
+ }
+
+ /**
+ * Creates the tag objects.
+ *
+ * @param string $tags Tag block to parse.
+ * @param Types\Context $context Context of the parsed Tag
+ *
+ * @return DocBlock\Tag[]
+ */
+ private function parseTagBlock($tags, Types\Context $context)
+ {
+ $tags = $this->filterTagBlock($tags);
+ if (!$tags) {
+ return [];
+ }
+
+ $result = $this->splitTagBlockIntoTagLines($tags);
+ foreach ($result as $key => $tagLine) {
+ $result[$key] = $this->tagFactory->create(trim($tagLine), $context);
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param string $tags
+ *
+ * @return string[]
+ */
+ private function splitTagBlockIntoTagLines($tags)
+ {
+ $result = [];
+ foreach (explode("\n", $tags) as $tag_line) {
+ if (isset($tag_line[0]) && ($tag_line[0] === '@')) {
+ $result[] = $tag_line;
+ } else {
+ $result[count($result) - 1] .= "\n" . $tag_line;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param $tags
+ * @return string
+ */
+ private function filterTagBlock($tags)
+ {
+ $tags = trim($tags);
+ if (!$tags) {
+ return null;
+ }
+
+ if ('@' !== $tags[0]) {
+ // @codeCoverageIgnoreStart
+ // Can't simulate this; this only happens if there is an error with the parsing of the DocBlock that
+ // we didn't foresee.
+ throw new \LogicException('A tag block started with text instead of an at-sign(@): ' . $tags);
+ // @codeCoverageIgnoreEnd
+ }
+
+ return $tags;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php
new file mode 100644
index 0000000..b353342
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php
@@ -0,0 +1,23 @@
+ please note that if you want to pass partial class names that additional steps are necessary, see the
+ > chapter `Resolving partial classes and FQSENs` for more information.
+
+Where the FqsenResolver can resolve:
+
+- Constant expressions (i.e. `@see \MyNamespace\MY_CONSTANT`)
+- Function expressions (i.e. `@see \MyNamespace\myFunction()`)
+- Class expressions (i.e. `@see \MyNamespace\MyClass`)
+- Interface expressions (i.e. `@see \MyNamespace\MyInterface`)
+- Trait expressions (i.e. `@see \MyNamespace\MyTrait`)
+- Class constant expressions (i.e. `@see \MyNamespace\MyClass::MY_CONSTANT`)
+- Property expressions (i.e. `@see \MyNamespace\MyClass::$myProperty`)
+- Method expressions (i.e. `@see \MyNamespace\MyClass::myMethod()`)
+
+## Resolving a type
+
+In order to resolve a type you will have to instantiate the class `\phpDocumentor\Reflection\TypeResolver`
+and call its `resolve` method like this:
+
+```php
+$typeResolver = new \phpDocumentor\Reflection\TypeResolver();
+$type = $typeResolver->resolve('string|integer');
+```
+
+In this example you will receive a Value Object of class `\phpDocumentor\Reflection\Types\Compound` that has two
+elements, one of type `\phpDocumentor\Reflection\Types\String_` and one of type
+`\phpDocumentor\Reflection\Types\Integer`.
+
+The real power of this resolver is in its capability to expand partial class names into fully qualified class names; but
+in order to do that we need an additional `\phpDocumentor\Reflection\Types\Context` class that will inform the resolver
+in which namespace the given expression occurs and which namespace aliases (or imports) apply.
+
+## Resolving an FQSEN
+
+A Fully Qualified Structural Element Name is a reference to another element in your code bases and can be resolved using
+the `\phpDocumentor\Reflection\FqsenResolver` class' `resolve` method, like this:
+
+```php
+$fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver();
+$fqsen = $fqsenResolver->resolve('\phpDocumentor\Reflection\FqsenResolver::resolve()');
+```
+
+In this example we resolve a Fully Qualified Structural Element Name (meaning that it includes the full namespace, class
+name and element name) and receive a Value Object of type `\phpDocumentor\Reflection\Fqsen`.
+
+The real power of this resolver is in its capability to expand partial element names into Fully Qualified Structural
+Element Names; but in order to do that we need an additional `\phpDocumentor\Reflection\Types\Context` class that will
+inform the resolver in which namespace the given expression occurs and which namespace aliases (or imports) apply.
+
+## Resolving partial Classes and Structural Element Names
+
+Perhaps the best feature of this library is that it knows how to resolve partial class names into fully qualified class
+names.
+
+For example, you have this file:
+
+```php
+namespace My\Example;
+
+use phpDocumentor\Reflection\Types;
+
+class Classy
+{
+ /**
+ * @var Types\Context
+ * @see Classy::otherFunction()
+ */
+ public function __construct($context) {}
+
+ public function otherFunction(){}
+}
+```
+
+Suppose that you would want to resolve (and expand) the type in the `@var` tag and the element name in the `@see` tag.
+For the resolvers to know how to expand partial names you have to provide a bit of _Context_ for them by instantiating
+a new class named `\phpDocumentor\Reflection\Types\Context` with the name of the namespace and the aliases that are in
+play.
+
+### Creating a Context
+
+You can do this by manually creating a Context like this:
+
+```php
+$context = new \phpDocumentor\Reflection\Types\Context(
+ '\My\Example',
+ [ 'Types' => '\phpDocumentor\Reflection\Types']
+);
+```
+
+Or by using the `\phpDocumentor\Reflection\Types\ContextFactory` to instantiate a new context based on a Reflector
+object or by providing the namespace that you'd like to extract and the source code of the file in which the given
+type expression occurs.
+
+```php
+$contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory();
+$context = $contextFactory->createFromReflector(new ReflectionMethod('\My\Example\Classy', '__construct'));
+```
+
+or
+
+```php
+$contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory();
+$context = $contextFactory->createForNamespace('\My\Example', file_get_contents('My/Example/Classy.php'));
+```
+
+### Using the Context
+
+After you have obtained a Context it is just a matter of passing it along with the `resolve` method of either Resolver
+class as second argument and the Resolvers will take this into account when resolving partial names.
+
+To obtain the resolved class name for the `@var` tag in the example above you can do:
+
+```php
+$typeResolver = new \phpDocumentor\Reflection\TypeResolver();
+$type = $typeResolver->resolve('Types\Context', $context);
+```
+
+When you do this you will receive an object of class `\phpDocumentor\Reflection\Types\Object_` for which you can call
+the `getFqsen` method to receive a Value Object that represents the complete FQSEN. So that would be
+`phpDocumentor\Reflection\Types\Context`.
+
+> Why is the FQSEN wrapped in another object `Object_`?
+>
+> The resolve method of the TypeResolver only returns object with the interface `Type` and the FQSEN is a common
+> type that does not represent a Type. Also: in some cases a type can represent an "Untyped Object", meaning that it
+> is an object (signified by the `object` keyword) but does not refer to a specific element using an FQSEN.
+
+Another example is on how to resolve the FQSEN of a method as can be seen with the `@see` tag in the example above. To
+resolve that you can do the following:
+
+```php
+$fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver();
+$type = $fqsenResolver->resolve('Classy::otherFunction()', $context);
+```
+
+Because Classy is a Class in the current namespace its FQSEN will have the `My\Example` namespace and by calling the
+`resolve` method of the FQSEN Resolver you will receive an `Fqsen` object that refers to
+`\My\Example\Classy::otherFunction()`.
diff --git a/vendor/phpdocumentor/type-resolver/composer.json b/vendor/phpdocumentor/type-resolver/composer.json
new file mode 100644
index 0000000..82ead15
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/composer.json
@@ -0,0 +1,27 @@
+{
+ "name": "phpdocumentor/type-resolver",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {"name": "Mike van Riel", "email": "me@mikevanriel.com"}
+ ],
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "autoload": {
+ "psr-4": {"phpDocumentor\\Reflection\\": ["src/"]}
+ },
+ "autoload-dev": {
+ "psr-4": {"phpDocumentor\\Reflection\\": ["tests/unit"]}
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.2||^4.8.24",
+ "mockery/mockery": "^0.9.4"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php b/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php
new file mode 100644
index 0000000..9aa6ba3
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php
@@ -0,0 +1,77 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+use phpDocumentor\Reflection\Types\Context;
+
+class FqsenResolver
+{
+ /** @var string Definition of the NAMESPACE operator in PHP */
+ const OPERATOR_NAMESPACE = '\\';
+
+ public function resolve($fqsen, Context $context = null)
+ {
+ if ($context === null) {
+ $context = new Context('');
+ }
+
+ if ($this->isFqsen($fqsen)) {
+ return new Fqsen($fqsen);
+ }
+
+ return $this->resolvePartialStructuralElementName($fqsen, $context);
+ }
+
+ /**
+ * Tests whether the given type is a Fully Qualified Structural Element Name.
+ *
+ * @param string $type
+ *
+ * @return bool
+ */
+ private function isFqsen($type)
+ {
+ return strpos($type, self::OPERATOR_NAMESPACE) === 0;
+ }
+
+ /**
+ * Resolves a partial Structural Element Name (i.e. `Reflection\DocBlock`) to its FQSEN representation
+ * (i.e. `\phpDocumentor\Reflection\DocBlock`) based on the Namespace and aliases mentioned in the Context.
+ *
+ * @param string $type
+ * @param Context $context
+ *
+ * @return Fqsen
+ * @throws \InvalidArgumentException when type is not a valid FQSEN.
+ */
+ private function resolvePartialStructuralElementName($type, Context $context)
+ {
+ $typeParts = explode(self::OPERATOR_NAMESPACE, $type, 2);
+
+ $namespaceAliases = $context->getNamespaceAliases();
+
+ // if the first segment is not an alias; prepend namespace name and return
+ if (!isset($namespaceAliases[$typeParts[0]])) {
+ $namespace = $context->getNamespace();
+ if ('' !== $namespace) {
+ $namespace .= self::OPERATOR_NAMESPACE;
+ }
+
+ return new Fqsen(self::OPERATOR_NAMESPACE . $namespace . $type);
+ }
+
+ $typeParts[0] = $namespaceAliases[$typeParts[0]];
+
+ return new Fqsen(self::OPERATOR_NAMESPACE . implode(self::OPERATOR_NAMESPACE, $typeParts));
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Type.php b/vendor/phpdocumentor/type-resolver/src/Type.php
new file mode 100644
index 0000000..33ca559
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Type.php
@@ -0,0 +1,18 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+interface Type
+{
+ public function __toString();
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/TypeResolver.php b/vendor/phpdocumentor/type-resolver/src/TypeResolver.php
new file mode 100644
index 0000000..08b2a5f
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/TypeResolver.php
@@ -0,0 +1,298 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+use phpDocumentor\Reflection\Types\Array_;
+use phpDocumentor\Reflection\Types\Compound;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\Iterable_;
+use phpDocumentor\Reflection\Types\Nullable;
+use phpDocumentor\Reflection\Types\Object_;
+
+final class TypeResolver
+{
+ /** @var string Definition of the ARRAY operator for types */
+ const OPERATOR_ARRAY = '[]';
+
+ /** @var string Definition of the NAMESPACE operator in PHP */
+ const OPERATOR_NAMESPACE = '\\';
+
+ /** @var string[] List of recognized keywords and unto which Value Object they map */
+ private $keywords = array(
+ 'string' => Types\String_::class,
+ 'int' => Types\Integer::class,
+ 'integer' => Types\Integer::class,
+ 'bool' => Types\Boolean::class,
+ 'boolean' => Types\Boolean::class,
+ 'float' => Types\Float_::class,
+ 'double' => Types\Float_::class,
+ 'object' => Object_::class,
+ 'mixed' => Types\Mixed_::class,
+ 'array' => Array_::class,
+ 'resource' => Types\Resource_::class,
+ 'void' => Types\Void_::class,
+ 'null' => Types\Null_::class,
+ 'scalar' => Types\Scalar::class,
+ 'callback' => Types\Callable_::class,
+ 'callable' => Types\Callable_::class,
+ 'false' => Types\Boolean::class,
+ 'true' => Types\Boolean::class,
+ 'self' => Types\Self_::class,
+ '$this' => Types\This::class,
+ 'static' => Types\Static_::class,
+ 'parent' => Types\Parent_::class,
+ 'iterable' => Iterable_::class,
+ );
+
+ /** @var FqsenResolver */
+ private $fqsenResolver;
+
+ /**
+ * Initializes this TypeResolver with the means to create and resolve Fqsen objects.
+ *
+ * @param FqsenResolver $fqsenResolver
+ */
+ public function __construct(FqsenResolver $fqsenResolver = null)
+ {
+ $this->fqsenResolver = $fqsenResolver ?: new FqsenResolver();
+ }
+
+ /**
+ * Analyzes the given type and returns the FQCN variant.
+ *
+ * When a type is provided this method checks whether it is not a keyword or
+ * Fully Qualified Class Name. If so it will use the given namespace and
+ * aliases to expand the type to a FQCN representation.
+ *
+ * This method only works as expected if the namespace and aliases are set;
+ * no dynamic reflection is being performed here.
+ *
+ * @param string $type The relative or absolute type.
+ * @param Context $context
+ *
+ * @uses Context::getNamespace() to determine with what to prefix the type name.
+ * @uses Context::getNamespaceAliases() to check whether the first part of the relative type name should not be
+ * replaced with another namespace.
+ *
+ * @return Type|null
+ */
+ public function resolve($type, Context $context = null)
+ {
+ if (!is_string($type)) {
+ throw new \InvalidArgumentException(
+ 'Attempted to resolve type but it appeared not to be a string, received: ' . var_export($type, true)
+ );
+ }
+
+ $type = trim($type);
+ if (!$type) {
+ throw new \InvalidArgumentException('Attempted to resolve "' . $type . '" but it appears to be empty');
+ }
+
+ if ($context === null) {
+ $context = new Context('');
+ }
+
+ switch (true) {
+ case $this->isNullableType($type):
+ return $this->resolveNullableType($type, $context);
+ case $this->isKeyword($type):
+ return $this->resolveKeyword($type);
+ case ($this->isCompoundType($type)):
+ return $this->resolveCompoundType($type, $context);
+ case $this->isTypedArray($type):
+ return $this->resolveTypedArray($type, $context);
+ case $this->isFqsen($type):
+ return $this->resolveTypedObject($type);
+ case $this->isPartialStructuralElementName($type):
+ return $this->resolveTypedObject($type, $context);
+ // @codeCoverageIgnoreStart
+ default:
+ // I haven't got the foggiest how the logic would come here but added this as a defense.
+ throw new \RuntimeException(
+ 'Unable to resolve type "' . $type . '", there is no known method to resolve it'
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * Adds a keyword to the list of Keywords and associates it with a specific Value Object.
+ *
+ * @param string $keyword
+ * @param string $typeClassName
+ *
+ * @return void
+ */
+ public function addKeyword($keyword, $typeClassName)
+ {
+ if (!class_exists($typeClassName)) {
+ throw new \InvalidArgumentException(
+ 'The Value Object that needs to be created with a keyword "' . $keyword . '" must be an existing class'
+ . ' but we could not find the class ' . $typeClassName
+ );
+ }
+
+ if (!in_array(Type::class, class_implements($typeClassName))) {
+ throw new \InvalidArgumentException(
+ 'The class "' . $typeClassName . '" must implement the interface "phpDocumentor\Reflection\Type"'
+ );
+ }
+
+ $this->keywords[$keyword] = $typeClassName;
+ }
+
+ /**
+ * Detects whether the given type represents an array.
+ *
+ * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
+ *
+ * @return bool
+ */
+ private function isTypedArray($type)
+ {
+ return substr($type, -2) === self::OPERATOR_ARRAY;
+ }
+
+ /**
+ * Detects whether the given type represents a PHPDoc keyword.
+ *
+ * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
+ *
+ * @return bool
+ */
+ private function isKeyword($type)
+ {
+ return in_array(strtolower($type), array_keys($this->keywords), true);
+ }
+
+ /**
+ * Detects whether the given type represents a relative structural element name.
+ *
+ * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
+ *
+ * @return bool
+ */
+ private function isPartialStructuralElementName($type)
+ {
+ return ($type[0] !== self::OPERATOR_NAMESPACE) && !$this->isKeyword($type);
+ }
+
+ /**
+ * Tests whether the given type is a Fully Qualified Structural Element Name.
+ *
+ * @param string $type
+ *
+ * @return bool
+ */
+ private function isFqsen($type)
+ {
+ return strpos($type, self::OPERATOR_NAMESPACE) === 0;
+ }
+
+ /**
+ * Tests whether the given type is a compound type (i.e. `string|int`).
+ *
+ * @param string $type
+ *
+ * @return bool
+ */
+ private function isCompoundType($type)
+ {
+ return strpos($type, '|') !== false;
+ }
+
+ /**
+ * Test whether the given type is a nullable type (i.e. `?string`)
+ *
+ * @param string $type
+ *
+ * @return bool
+ */
+ private function isNullableType($type)
+ {
+ return $type[0] === '?';
+ }
+
+ /**
+ * Resolves the given typed array string (i.e. `string[]`) into an Array object with the right types set.
+ *
+ * @param string $type
+ * @param Context $context
+ *
+ * @return Array_
+ */
+ private function resolveTypedArray($type, Context $context)
+ {
+ return new Array_($this->resolve(substr($type, 0, -2), $context));
+ }
+
+ /**
+ * Resolves the given keyword (such as `string`) into a Type object representing that keyword.
+ *
+ * @param string $type
+ *
+ * @return Type
+ */
+ private function resolveKeyword($type)
+ {
+ $className = $this->keywords[strtolower($type)];
+
+ return new $className();
+ }
+
+ /**
+ * Resolves the given FQSEN string into an FQSEN object.
+ *
+ * @param string $type
+ * @param Context|null $context
+ *
+ * @return Object_
+ */
+ private function resolveTypedObject($type, Context $context = null)
+ {
+ return new Object_($this->fqsenResolver->resolve($type, $context));
+ }
+
+ /**
+ * Resolves a compound type (i.e. `string|int`) into the appropriate Type objects or FQSEN.
+ *
+ * @param string $type
+ * @param Context $context
+ *
+ * @return Compound
+ */
+ private function resolveCompoundType($type, Context $context)
+ {
+ $types = [];
+
+ foreach (explode('|', $type) as $part) {
+ $types[] = $this->resolve($part, $context);
+ }
+
+ return new Compound($types);
+ }
+
+ /**
+ * Resolve nullable types (i.e. `?string`) into a Nullable type wrapper
+ *
+ * @param string $type
+ * @param Context $context
+ *
+ * @return Nullable
+ */
+ private function resolveNullableType($type, Context $context)
+ {
+ return new Nullable($this->resolve(ltrim($type, '?'), $context));
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Array_.php b/vendor/phpdocumentor/type-resolver/src/Types/Array_.php
new file mode 100644
index 0000000..49b7c6e
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Array_.php
@@ -0,0 +1,86 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Represents an array type as described in the PSR-5, the PHPDoc Standard.
+ *
+ * An array can be represented in two forms:
+ *
+ * 1. Untyped (`array`), where the key and value type is unknown and hence classified as 'Mixed_'.
+ * 2. Types (`string[]`), where the value type is provided by preceding an opening and closing square bracket with a
+ * type name.
+ */
+final class Array_ implements Type
+{
+ /** @var Type */
+ private $valueType;
+
+ /** @var Type */
+ private $keyType;
+
+ /**
+ * Initializes this representation of an array with the given Type or Fqsen.
+ *
+ * @param Type $valueType
+ * @param Type $keyType
+ */
+ public function __construct(Type $valueType = null, Type $keyType = null)
+ {
+ if ($keyType === null) {
+ $keyType = new Compound([ new String_(), new Integer() ]);
+ }
+ if ($valueType === null) {
+ $valueType = new Mixed_();
+ }
+
+ $this->valueType = $valueType;
+ $this->keyType = $keyType;
+ }
+
+ /**
+ * Returns the type for the keys of this array.
+ *
+ * @return Type
+ */
+ public function getKeyType()
+ {
+ return $this->keyType;
+ }
+
+ /**
+ * Returns the value for the keys of this array.
+ *
+ * @return Type
+ */
+ public function getValueType()
+ {
+ return $this->valueType;
+ }
+
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if ($this->valueType instanceof Mixed_) {
+ return 'array';
+ }
+
+ return $this->valueType . '[]';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php b/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php
new file mode 100644
index 0000000..f82b19e
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a Boolean type.
+ */
+final class Boolean implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'bool';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php b/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php
new file mode 100644
index 0000000..68ebfbd
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a Callable type.
+ */
+final class Callable_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'callable';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Compound.php b/vendor/phpdocumentor/type-resolver/src/Types/Compound.php
new file mode 100644
index 0000000..be986c3
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Compound.php
@@ -0,0 +1,93 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use ArrayIterator;
+use IteratorAggregate;
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a Compound Type.
+ *
+ * A Compound Type is not so much a special keyword or object reference but is a series of Types that are separated
+ * using an OR operator (`|`). This combination of types signifies that whatever is associated with this compound type
+ * may contain a value with any of the given types.
+ */
+final class Compound implements Type, IteratorAggregate
+{
+ /** @var Type[] */
+ private $types;
+
+ /**
+ * Initializes a compound type (i.e. `string|int`) and tests if the provided types all implement the Type interface.
+ *
+ * @param Type[] $types
+ * @throws \InvalidArgumentException when types are not all instance of Type
+ */
+ public function __construct(array $types)
+ {
+ foreach ($types as $type) {
+ if (!$type instanceof Type) {
+ throw new \InvalidArgumentException('A compound type can only have other types as elements');
+ }
+ }
+
+ $this->types = $types;
+ }
+
+ /**
+ * Returns the type at the given index.
+ *
+ * @param integer $index
+ *
+ * @return Type|null
+ */
+ public function get($index)
+ {
+ if (!$this->has($index)) {
+ return null;
+ }
+
+ return $this->types[$index];
+ }
+
+ /**
+ * Tests if this compound type has a type with the given index.
+ *
+ * @param integer $index
+ *
+ * @return bool
+ */
+ public function has($index)
+ {
+ return isset($this->types[$index]);
+ }
+
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return implode('|', $this->types);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->types);
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Context.php b/vendor/phpdocumentor/type-resolver/src/Types/Context.php
new file mode 100644
index 0000000..4e9ce5a
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Context.php
@@ -0,0 +1,84 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+/**
+ * Provides information about the Context in which the DocBlock occurs that receives this context.
+ *
+ * A DocBlock does not know of its own accord in which namespace it occurs and which namespace aliases are applicable
+ * for the block of code in which it is in. This information is however necessary to resolve Class names in tags since
+ * you can provide a short form or make use of namespace aliases.
+ *
+ * The phpDocumentor Reflection component knows how to create this class but if you use the DocBlock parser from your
+ * own application it is possible to generate a Context class using the ContextFactory; this will analyze the file in
+ * which an associated class resides for its namespace and imports.
+ *
+ * @see ContextFactory::createFromClassReflector()
+ * @see ContextFactory::createForNamespace()
+ */
+final class Context
+{
+ /** @var string The current namespace. */
+ private $namespace;
+
+ /** @var array List of namespace aliases => Fully Qualified Namespace. */
+ private $namespaceAliases;
+
+ /**
+ * Initializes the new context and normalizes all passed namespaces to be in Qualified Namespace Name (QNN)
+ * format (without a preceding `\`).
+ *
+ * @param string $namespace The namespace where this DocBlock resides in.
+ * @param array $namespaceAliases List of namespace aliases => Fully Qualified Namespace.
+ */
+ public function __construct($namespace, array $namespaceAliases = [])
+ {
+ $this->namespace = ('global' !== $namespace && 'default' !== $namespace)
+ ? trim((string)$namespace, '\\')
+ : '';
+
+ foreach ($namespaceAliases as $alias => $fqnn) {
+ if ($fqnn[0] === '\\') {
+ $fqnn = substr($fqnn, 1);
+ }
+ if ($fqnn[strlen($fqnn) - 1] === '\\') {
+ $fqnn = substr($fqnn, 0, -1);
+ }
+
+ $namespaceAliases[$alias] = $fqnn;
+ }
+
+ $this->namespaceAliases = $namespaceAliases;
+ }
+
+ /**
+ * Returns the Qualified Namespace Name (thus without `\` in front) where the associated element is in.
+ *
+ * @return string
+ */
+ public function getNamespace()
+ {
+ return $this->namespace;
+ }
+
+ /**
+ * Returns a list of Qualified Namespace Names (thus without `\` in front) that are imported, the keys represent
+ * the alias for the imported Namespace.
+ *
+ * @return string[]
+ */
+ public function getNamespaceAliases()
+ {
+ return $this->namespaceAliases;
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php b/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php
new file mode 100644
index 0000000..30936a3
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php
@@ -0,0 +1,210 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+/**
+ * Convenience class to create a Context for DocBlocks when not using the Reflection Component of phpDocumentor.
+ *
+ * For a DocBlock to be able to resolve types that use partial namespace names or rely on namespace imports we need to
+ * provide a bit of context so that the DocBlock can read that and based on it decide how to resolve the types to
+ * Fully Qualified names.
+ *
+ * @see Context for more information.
+ */
+final class ContextFactory
+{
+ /** The literal used at the end of a use statement. */
+ const T_LITERAL_END_OF_USE = ';';
+
+ /** The literal used between sets of use statements */
+ const T_LITERAL_USE_SEPARATOR = ',';
+
+ /**
+ * Build a Context given a Class Reflection.
+ *
+ * @param \Reflector $reflector
+ *
+ * @see Context for more information on Contexts.
+ *
+ * @return Context
+ */
+ public function createFromReflector(\Reflector $reflector)
+ {
+ if (method_exists($reflector, 'getDeclaringClass')) {
+ $reflector = $reflector->getDeclaringClass();
+ }
+
+ $fileName = $reflector->getFileName();
+ $namespace = $reflector->getNamespaceName();
+
+ if (file_exists($fileName)) {
+ return $this->createForNamespace($namespace, file_get_contents($fileName));
+ }
+
+ return new Context($namespace, []);
+ }
+
+ /**
+ * Build a Context for a namespace in the provided file contents.
+ *
+ * @param string $namespace It does not matter if a `\` precedes the namespace name, this method first normalizes.
+ * @param string $fileContents the file's contents to retrieve the aliases from with the given namespace.
+ *
+ * @see Context for more information on Contexts.
+ *
+ * @return Context
+ */
+ public function createForNamespace($namespace, $fileContents)
+ {
+ $namespace = trim($namespace, '\\');
+ $useStatements = [];
+ $currentNamespace = '';
+ $tokens = new \ArrayIterator(token_get_all($fileContents));
+
+ while ($tokens->valid()) {
+ switch ($tokens->current()[0]) {
+ case T_NAMESPACE:
+ $currentNamespace = $this->parseNamespace($tokens);
+ break;
+ case T_CLASS:
+ // Fast-forward the iterator through the class so that any
+ // T_USE tokens found within are skipped - these are not
+ // valid namespace use statements so should be ignored.
+ $braceLevel = 0;
+ $firstBraceFound = false;
+ while ($tokens->valid() && ($braceLevel > 0 || !$firstBraceFound)) {
+ if ($tokens->current() === '{'
+ || $tokens->current()[0] === T_CURLY_OPEN
+ || $tokens->current()[0] === T_DOLLAR_OPEN_CURLY_BRACES) {
+ if (!$firstBraceFound) {
+ $firstBraceFound = true;
+ }
+ $braceLevel++;
+ }
+
+ if ($tokens->current() === '}') {
+ $braceLevel--;
+ }
+ $tokens->next();
+ }
+ break;
+ case T_USE:
+ if ($currentNamespace === $namespace) {
+ $useStatements = array_merge($useStatements, $this->parseUseStatement($tokens));
+ }
+ break;
+ }
+ $tokens->next();
+ }
+
+ return new Context($namespace, $useStatements);
+ }
+
+ /**
+ * Deduce the name from tokens when we are at the T_NAMESPACE token.
+ *
+ * @param \ArrayIterator $tokens
+ *
+ * @return string
+ */
+ private function parseNamespace(\ArrayIterator $tokens)
+ {
+ // skip to the first string or namespace separator
+ $this->skipToNextStringOrNamespaceSeparator($tokens);
+
+ $name = '';
+ while ($tokens->valid() && ($tokens->current()[0] === T_STRING || $tokens->current()[0] === T_NS_SEPARATOR)
+ ) {
+ $name .= $tokens->current()[1];
+ $tokens->next();
+ }
+
+ return $name;
+ }
+
+ /**
+ * Deduce the names of all imports when we are at the T_USE token.
+ *
+ * @param \ArrayIterator $tokens
+ *
+ * @return string[]
+ */
+ private function parseUseStatement(\ArrayIterator $tokens)
+ {
+ $uses = [];
+ $continue = true;
+
+ while ($continue) {
+ $this->skipToNextStringOrNamespaceSeparator($tokens);
+
+ list($alias, $fqnn) = $this->extractUseStatement($tokens);
+ $uses[$alias] = $fqnn;
+ if ($tokens->current()[0] === self::T_LITERAL_END_OF_USE) {
+ $continue = false;
+ }
+ }
+
+ return $uses;
+ }
+
+ /**
+ * Fast-forwards the iterator as longs as we don't encounter a T_STRING or T_NS_SEPARATOR token.
+ *
+ * @param \ArrayIterator $tokens
+ *
+ * @return void
+ */
+ private function skipToNextStringOrNamespaceSeparator(\ArrayIterator $tokens)
+ {
+ while ($tokens->valid() && ($tokens->current()[0] !== T_STRING) && ($tokens->current()[0] !== T_NS_SEPARATOR)) {
+ $tokens->next();
+ }
+ }
+
+ /**
+ * Deduce the namespace name and alias of an import when we are at the T_USE token or have not reached the end of
+ * a USE statement yet.
+ *
+ * @param \ArrayIterator $tokens
+ *
+ * @return string
+ */
+ private function extractUseStatement(\ArrayIterator $tokens)
+ {
+ $result = [''];
+ while ($tokens->valid()
+ && ($tokens->current()[0] !== self::T_LITERAL_USE_SEPARATOR)
+ && ($tokens->current()[0] !== self::T_LITERAL_END_OF_USE)
+ ) {
+ if ($tokens->current()[0] === T_AS) {
+ $result[] = '';
+ }
+ if ($tokens->current()[0] === T_STRING || $tokens->current()[0] === T_NS_SEPARATOR) {
+ $result[count($result) - 1] .= $tokens->current()[1];
+ }
+ $tokens->next();
+ }
+
+ if (count($result) == 1) {
+ $backslashPos = strrpos($result[0], '\\');
+
+ if (false !== $backslashPos) {
+ $result[] = substr($result[0], $backslashPos + 1);
+ } else {
+ $result[] = $result[0];
+ }
+ }
+
+ return array_reverse($result);
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Float_.php b/vendor/phpdocumentor/type-resolver/src/Types/Float_.php
new file mode 100644
index 0000000..e58d896
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Float_.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a Float.
+ */
+final class Float_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'float';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Integer.php b/vendor/phpdocumentor/type-resolver/src/Types/Integer.php
new file mode 100644
index 0000000..be4555e
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Integer.php
@@ -0,0 +1,28 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+final class Integer implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'int';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php b/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php
new file mode 100644
index 0000000..0cbf48f
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing iterable type
+ */
+final class Iterable_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'iterable';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php b/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php
new file mode 100644
index 0000000..c1c165f
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing an unknown, or mixed, type.
+ */
+final class Mixed_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'mixed';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Null_.php b/vendor/phpdocumentor/type-resolver/src/Types/Null_.php
new file mode 100644
index 0000000..203b422
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Null_.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a null value or type.
+ */
+final class Null_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'null';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Nullable.php b/vendor/phpdocumentor/type-resolver/src/Types/Nullable.php
new file mode 100644
index 0000000..3c6d1b1
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Nullable.php
@@ -0,0 +1,56 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a nullable type. The real type is wrapped.
+ */
+final class Nullable implements Type
+{
+ /**
+ * @var Type
+ */
+ private $realType;
+
+ /**
+ * Initialises this nullable type using the real type embedded
+ *
+ * @param Type $realType
+ */
+ public function __construct(Type $realType)
+ {
+ $this->realType = $realType;
+ }
+
+ /**
+ * Provide access to the actual type directly, if needed.
+ *
+ * @return Type
+ */
+ public function getActualType()
+ {
+ return $this->realType;
+ }
+
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '?' . $this->realType->__toString();
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Object_.php b/vendor/phpdocumentor/type-resolver/src/Types/Object_.php
new file mode 100644
index 0000000..389f7c7
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Object_.php
@@ -0,0 +1,71 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing an object.
+ *
+ * An object can be either typed or untyped. When an object is typed it means that it has an identifier, the FQSEN,
+ * pointing to an element in PHP. Object types that are untyped do not refer to a specific class but represent objects
+ * in general.
+ */
+final class Object_ implements Type
+{
+ /** @var Fqsen|null */
+ private $fqsen;
+
+ /**
+ * Initializes this object with an optional FQSEN, if not provided this object is considered 'untyped'.
+ *
+ * @param Fqsen $fqsen
+ * @throws \InvalidArgumentException when provided $fqsen is not a valid type.
+ */
+ public function __construct(Fqsen $fqsen = null)
+ {
+ if (strpos((string)$fqsen, '::') !== false || strpos((string)$fqsen, '()') !== false) {
+ throw new \InvalidArgumentException(
+ 'Object types can only refer to a class, interface or trait but a method, function, constant or '
+ . 'property was received: ' . (string)$fqsen
+ );
+ }
+
+ $this->fqsen = $fqsen;
+ }
+
+ /**
+ * Returns the FQSEN associated with this object.
+ *
+ * @return Fqsen|null
+ */
+ public function getFqsen()
+ {
+ return $this->fqsen;
+ }
+
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if ($this->fqsen) {
+ return (string)$this->fqsen;
+ }
+
+ return 'object';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php b/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php
new file mode 100644
index 0000000..aabdbfb
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php
@@ -0,0 +1,33 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'parent' type.
+ *
+ * Parent, as a Type, represents the parent class of class in which the associated element was defined.
+ */
+final class Parent_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'parent';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Resource_.php b/vendor/phpdocumentor/type-resolver/src/Types/Resource_.php
new file mode 100644
index 0000000..a1b613d
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Resource_.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'resource' Type.
+ */
+final class Resource_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'resource';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php b/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php
new file mode 100644
index 0000000..1e2a660
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'scalar' pseudo-type, which is either a string, integer, float or boolean.
+ */
+final class Scalar implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'scalar';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Self_.php b/vendor/phpdocumentor/type-resolver/src/Types/Self_.php
new file mode 100644
index 0000000..1ba3fc5
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Self_.php
@@ -0,0 +1,33 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'self' type.
+ *
+ * Self, as a Type, represents the class in which the associated element was defined.
+ */
+final class Self_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'self';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Static_.php b/vendor/phpdocumentor/type-resolver/src/Types/Static_.php
new file mode 100644
index 0000000..9eb6729
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Static_.php
@@ -0,0 +1,38 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'static' type.
+ *
+ * Self, as a Type, represents the class in which the associated element was called. This differs from self as self does
+ * not take inheritance into account but static means that the return type is always that of the class of the called
+ * element.
+ *
+ * See the documentation on late static binding in the PHP Documentation for more information on the difference between
+ * static and self.
+ */
+final class Static_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'static';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/String_.php b/vendor/phpdocumentor/type-resolver/src/Types/String_.php
new file mode 100644
index 0000000..8db5968
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/String_.php
@@ -0,0 +1,31 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the type 'string'.
+ */
+final class String_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'string';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/This.php b/vendor/phpdocumentor/type-resolver/src/Types/This.php
new file mode 100644
index 0000000..c098a93
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/This.php
@@ -0,0 +1,34 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the '$this' pseudo-type.
+ *
+ * $this, as a Type, represents the instance of the class associated with the element as it was called. $this is
+ * commonly used when documenting fluent interfaces since it represents that the same object is returned.
+ */
+final class This implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '$this';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Void_.php b/vendor/phpdocumentor/type-resolver/src/Types/Void_.php
new file mode 100644
index 0000000..3d1be27
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Void_.php
@@ -0,0 +1,34 @@
+
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the pseudo-type 'void'.
+ *
+ * Void is generally only used when working with return types as it signifies that the method intentionally does not
+ * return any value.
+ */
+final class Void_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'void';
+ }
+}
diff --git a/vendor/phpspec/prophecy/CHANGES.md b/vendor/phpspec/prophecy/CHANGES.md
new file mode 100644
index 0000000..fddfc41
--- /dev/null
+++ b/vendor/phpspec/prophecy/CHANGES.md
@@ -0,0 +1,213 @@
+1.8.0 / 2018/08/05
+==================
+
+* Support for void return types without explicit will (@crellbar)
+* Clearer error message for unexpected method calls (@meridius)
+* Clearer error message for aggregate exceptions (@meridius)
+* More verbose `shouldBeCalledOnce` expectation (@olvlvl)
+* Ability to double Throwable, or methods that extend it (@ciaranmcnulty)
+* [fixed] Doubling methods where class has additional arguments to interface (@webimpress)
+* [fixed] Doubling methods where arguments are nullable but default is not null (@webimpress)
+* [fixed] Doubling magic methods on parent class (@dsnopek)
+* [fixed] Check method predictions only once (@dontub)
+* [fixed] Argument::containingString throwing error when called with non-string (@dcabrejas)
+
+1.7.6 / 2018/04/18
+==================
+
+* Allow sebastian/comparator ^3.0 (@sebastianbergmann)
+
+1.7.5 / 2018/02/11
+==================
+
+* Support for object return type hints (thanks @greg0ire)
+
+1.7.4 / 2018/02/11
+==================
+
+* Fix issues with PHP 7.2 (thanks @greg0ire)
+* Support object type hints in PHP 7.2 (thanks @@jansvoboda11)
+
+1.7.3 / 2017/11/24
+==================
+
+* Fix SplInfo ClassPatch to work with Symfony 4 (Thanks @gnugat)
+
+1.7.2 / 2017-10-04
+==================
+
+* Reverted "check method predictions only once" due to it breaking Spies
+
+1.7.1 / 2017-10-03
+==================
+
+* Allow PHP5 keywords methods generation on PHP7 (thanks @bycosta)
+* Allow reflection-docblock v4 (thanks @GrahamCampbell)
+* Check method predictions only once (thanks @dontub)
+* Escape file path sent to \SplFileObjectConstructor when running on Windows (thanks @danmartin-epiphany)
+
+1.7.0 / 2017-03-02
+==================
+
+* Add full PHP 7.1 Support (thanks @prolic)
+* Allow `sebastian/comparator ^2.0` (thanks @sebastianbergmann)
+* Allow `sebastian/recursion-context ^3.0` (thanks @sebastianbergmann)
+* Allow `\Error` instances in `ThrowPromise` (thanks @jameshalsall)
+* Support `phpspec/phpspect ^3.2` (thanks @Sam-Burns)
+* Fix failing builds (thanks @Sam-Burns)
+
+1.6.2 / 2016-11-21
+==================
+
+* Added support for detecting @method on interfaces that the class itself implements, or when the stubbed class is an interface itself (thanks @Seldaek)
+* Added support for sebastian/recursion-context 2 (thanks @sebastianbergmann)
+* Added testing on PHP 7.1 on Travis (thanks @danizord)
+* Fixed the usage of the phpunit comparator (thanks @Anyqax)
+
+1.6.1 / 2016-06-07
+==================
+
+ * Ignored empty method names in invalid `@method` phpdoc
+ * Fixed the mocking of SplFileObject
+ * Added compatibility with phpdocumentor/reflection-docblock 3
+
+1.6.0 / 2016-02-15
+==================
+
+ * Add Variadics support (thanks @pamil)
+ * Add ProphecyComparator for comparing objects that need revealing (thanks @jon-acker)
+ * Add ApproximateValueToken (thanks @dantleech)
+ * Add support for 'self' and 'parent' return type (thanks @bendavies)
+ * Add __invoke to allowed reflectable methods list (thanks @ftrrtf)
+ * Updated ExportUtil to reflect the latest changes by Sebastian (thanks @jakari)
+ * Specify the required php version for composer (thanks @jakzal)
+ * Exclude 'args' in the generated backtrace (thanks @oradwell)
+ * Fix code generation for scalar parameters (thanks @trowski)
+ * Fix missing sprintf in InvalidArgumentException __construct call (thanks @emmanuelballery)
+ * Fix phpdoc for magic methods (thanks @Tobion)
+ * Fix PhpDoc for interfaces usage (thanks @ImmRanneft)
+ * Prevent final methods from being manually extended (thanks @kamioftea)
+ * Enhance exception for invalid argument to ThrowPromise (thanks @Tobion)
+
+1.5.0 / 2015-04-27
+==================
+
+ * Add support for PHP7 scalar type hints (thanks @trowski)
+ * Add support for PHP7 return types (thanks @trowski)
+ * Update internal test suite to support PHP7
+
+1.4.1 / 2015-04-27
+==================
+
+ * Fixed bug in closure-based argument tokens (#181)
+
+1.4.0 / 2015-03-27
+==================
+
+ * Fixed errors in return type phpdocs (thanks @sobit)
+ * Fixed stringifying of hash containing one value (thanks @avant1)
+ * Improved clarity of method call expectation exception (thanks @dantleech)
+ * Add ability to specify which argument is returned in willReturnArgument (thanks @coderbyheart)
+ * Add more information to MethodNotFound exceptions (thanks @ciaranmcnulty)
+ * Support for mocking classes with methods that return references (thanks @edsonmedina)
+ * Improved object comparison (thanks @whatthejeff)
+ * Adopted '^' in composer dependencies (thanks @GrahamCampbell)
+ * Fixed non-typehinted arguments being treated as optional (thanks @whatthejeff)
+ * Magic methods are now filtered for keywords (thanks @seagoj)
+ * More readable errors for failure when expecting single calls (thanks @dantleech)
+
+1.3.1 / 2014-11-17
+==================
+
+ * Fix the edge case when failed predictions weren't recorded for `getCheckedPredictions()`
+
+1.3.0 / 2014-11-14
+==================
+
+ * Add a way to get checked predictions with `MethodProphecy::getCheckedPredictions()`
+ * Fix HHVM compatibility
+ * Remove dead code (thanks @stof)
+ * Add support for DirectoryIterators (thanks @shanethehat)
+
+1.2.0 / 2014-07-18
+==================
+
+ * Added support for doubling magic methods documented in the class phpdoc (thanks @armetiz)
+ * Fixed a segfault appearing in some cases (thanks @dmoreaulf)
+ * Fixed the doubling of methods with typehints on non-existent classes (thanks @gquemener)
+ * Added support for internal classes using keywords as method names (thanks @milan)
+ * Added IdenticalValueToken and Argument::is (thanks @florianv)
+ * Removed the usage of scalar typehints in HHVM as HHVM 3 does not support them anymore in PHP code (thanks @whatthejeff)
+
+1.1.2 / 2014-01-24
+==================
+
+ * Spy automatically promotes spied method call to an expected one
+
+1.1.1 / 2014-01-15
+==================
+
+ * Added support for HHVM
+
+1.1.0 / 2014-01-01
+==================
+
+ * Changed the generated class names to use a static counter instead of a random number
+ * Added a clss patch for ReflectionClass::newInstance to make its argument optional consistently (thanks @docteurklein)
+ * Fixed mirroring of classes with typehints on non-existent classes (thanks @docteurklein)
+ * Fixed the support of array callables in CallbackPromise and CallbackPrediction (thanks @ciaranmcnulty)
+ * Added support for properties in ObjectStateToken (thanks @adrienbrault)
+ * Added support for mocking classes with a final constructor (thanks @ciaranmcnulty)
+ * Added ArrayEveryEntryToken and Argument::withEveryEntry() (thanks @adrienbrault)
+ * Added an exception when trying to prophesize on a final method instead of ignoring silently (thanks @docteurklein)
+ * Added StringContainToken and Argument::containingString() (thanks @peterjmit)
+ * Added ``shouldNotHaveBeenCalled`` on the MethodProphecy (thanks @ciaranmcnulty)
+ * Fixed the comparison of objects in ExactValuetoken (thanks @sstok)
+ * Deprecated ``shouldNotBeenCalled`` in favor of ``shouldNotHaveBeenCalled``
+
+1.0.4 / 2013-08-10
+==================
+
+ * Better randomness for generated class names (thanks @sstok)
+ * Add support for interfaces into TypeToken and Argument::type() (thanks @sstok)
+ * Add support for old-style (method name === class name) constructors (thanks @l310 for report)
+
+1.0.3 / 2013-07-04
+==================
+
+ * Support callable typehints (thanks @stof)
+ * Do not attempt to autoload arrays when generating code (thanks @MarcoDeBortoli)
+ * New ArrayEntryToken (thanks @kagux)
+
+1.0.2 / 2013-05-19
+==================
+
+ * Logical `AND` token added (thanks @kagux)
+ * Logical `NOT` token added (thanks @kagux)
+ * Add support for setting custom constructor arguments
+ * Properly stringify hashes
+ * Record calls that throw exceptions
+ * Migrate spec suite to PhpSpec 2.0
+
+1.0.1 / 2013-04-30
+==================
+
+ * Fix broken UnexpectedCallException message
+ * Trim AggregateException message
+
+1.0.0 / 2013-04-29
+==================
+
+ * Improve exception messages
+
+1.0.0-BETA2 / 2013-04-03
+========================
+
+ * Add more debug information to CallTimes and Call prediction exception messages
+ * Fix MethodNotFoundException wrong namespace (thanks @gunnarlium)
+ * Fix some typos in the exception messages (thanks @pborreli)
+
+1.0.0-BETA1 / 2013-03-25
+========================
+
+ * Initial release
diff --git a/vendor/phpspec/prophecy/LICENSE b/vendor/phpspec/prophecy/LICENSE
new file mode 100644
index 0000000..c8b3647
--- /dev/null
+++ b/vendor/phpspec/prophecy/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2013 Konstantin Kudryashov
+ Marcello Duarte
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/phpspec/prophecy/README.md b/vendor/phpspec/prophecy/README.md
new file mode 100644
index 0000000..b190d43
--- /dev/null
+++ b/vendor/phpspec/prophecy/README.md
@@ -0,0 +1,391 @@
+# Prophecy
+
+[![Stable release](https://poser.pugx.org/phpspec/prophecy/version.svg)](https://packagist.org/packages/phpspec/prophecy)
+[![Build Status](https://travis-ci.org/phpspec/prophecy.svg?branch=master)](https://travis-ci.org/phpspec/prophecy)
+
+Prophecy is a highly opinionated yet very powerful and flexible PHP object mocking
+framework. Though initially it was created to fulfil phpspec2 needs, it is flexible
+enough to be used inside any testing framework out there with minimal effort.
+
+## A simple example
+
+```php
+prophet->prophesize('App\Security\Hasher');
+ $user = new App\Entity\User($hasher->reveal());
+
+ $hasher->generateHash($user, 'qwerty')->willReturn('hashed_pass');
+
+ $user->setPassword('qwerty');
+
+ $this->assertEquals('hashed_pass', $user->getPassword());
+ }
+
+ protected function setup()
+ {
+ $this->prophet = new \Prophecy\Prophet;
+ }
+
+ protected function tearDown()
+ {
+ $this->prophet->checkPredictions();
+ }
+}
+```
+
+## Installation
+
+### Prerequisites
+
+Prophecy requires PHP 5.3.3 or greater.
+
+### Setup through composer
+
+First, add Prophecy to the list of dependencies inside your `composer.json`:
+
+```json
+{
+ "require-dev": {
+ "phpspec/prophecy": "~1.0"
+ }
+}
+```
+
+Then simply install it with composer:
+
+```bash
+$> composer install --prefer-dist
+```
+
+You can read more about Composer on its [official webpage](http://getcomposer.org).
+
+## How to use it
+
+First of all, in Prophecy every word has a logical meaning, even the name of the library
+itself (Prophecy). When you start feeling that, you'll become very fluid with this
+tool.
+
+For example, Prophecy has been named that way because it concentrates on describing the future
+behavior of objects with very limited knowledge about them. But as with any other prophecy,
+those object prophecies can't create themselves - there should be a Prophet:
+
+```php
+$prophet = new Prophecy\Prophet;
+```
+
+The Prophet creates prophecies by *prophesizing* them:
+
+```php
+$prophecy = $prophet->prophesize();
+```
+
+The result of the `prophesize()` method call is a new object of class `ObjectProphecy`. Yes,
+that's your specific object prophecy, which describes how your object would behave
+in the near future. But first, you need to specify which object you're talking about,
+right?
+
+```php
+$prophecy->willExtend('stdClass');
+$prophecy->willImplement('SessionHandlerInterface');
+```
+
+There are 2 interesting calls - `willExtend` and `willImplement`. The first one tells
+object prophecy that our object should extend specific class, the second one says that
+it should implement some interface. Obviously, objects in PHP can implement multiple
+interfaces, but extend only one parent class.
+
+### Dummies
+
+Ok, now we have our object prophecy. What can we do with it? First of all, we can get
+our object *dummy* by revealing its prophecy:
+
+```php
+$dummy = $prophecy->reveal();
+```
+
+The `$dummy` variable now holds a special dummy object. Dummy objects are objects that extend
+and/or implement preset classes/interfaces by overriding all their public methods. The key
+point about dummies is that they do not hold any logic - they just do nothing. Any method
+of the dummy will always return `null` and the dummy will never throw any exceptions.
+Dummy is your friend if you don't care about the actual behavior of this double and just need
+a token object to satisfy a method typehint.
+
+You need to understand one thing - a dummy is not a prophecy. Your object prophecy is still
+assigned to `$prophecy` variable and in order to manipulate with your expectations, you
+should work with it. `$dummy` is a dummy - a simple php object that tries to fulfil your
+prophecy.
+
+### Stubs
+
+Ok, now we know how to create basic prophecies and reveal dummies from them. That's
+awesome if we don't care about our _doubles_ (objects that reflect originals)
+interactions. If we do, we need to use *stubs* or *mocks*.
+
+A stub is an object double, which doesn't have any expectations about the object behavior,
+but when put in specific environment, behaves in specific way. Ok, I know, it's cryptic,
+but bear with me for a minute. Simply put, a stub is a dummy, which depending on the called
+method signature does different things (has logic). To create stubs in Prophecy:
+
+```php
+$prophecy->read('123')->willReturn('value');
+```
+
+Oh wow. We've just made an arbitrary call on the object prophecy? Yes, we did. And this
+call returned us a new object instance of class `MethodProphecy`. Yep, that's a specific
+method with arguments prophecy. Method prophecies give you the ability to create method
+promises or predictions. We'll talk about method predictions later in the _Mocks_ section.
+
+#### Promises
+
+Promises are logical blocks, that represent your fictional methods in prophecy terms
+and they are handled by the `MethodProphecy::will(PromiseInterface $promise)` method.
+As a matter of fact, the call that we made earlier (`willReturn('value')`) is a simple
+shortcut to:
+
+```php
+$prophecy->read('123')->will(new Prophecy\Promise\ReturnPromise(array('value')));
+```
+
+This promise will cause any call to our double's `read()` method with exactly one
+argument - `'123'` to always return `'value'`. But that's only for this
+promise, there's plenty others you can use:
+
+- `ReturnPromise` or `->willReturn(1)` - returns a value from a method call
+- `ReturnArgumentPromise` or `->willReturnArgument($index)` - returns the nth method argument from call
+- `ThrowPromise` or `->willThrow($exception)` - causes the method to throw specific exception
+- `CallbackPromise` or `->will($callback)` - gives you a quick way to define your own custom logic
+
+Keep in mind, that you can always add even more promises by implementing
+`Prophecy\Promise\PromiseInterface`.
+
+#### Method prophecies idempotency
+
+Prophecy enforces same method prophecies and, as a consequence, same promises and
+predictions for the same method calls with the same arguments. This means:
+
+```php
+$methodProphecy1 = $prophecy->read('123');
+$methodProphecy2 = $prophecy->read('123');
+$methodProphecy3 = $prophecy->read('321');
+
+$methodProphecy1 === $methodProphecy2;
+$methodProphecy1 !== $methodProphecy3;
+```
+
+That's interesting, right? Now you might ask me how would you define more complex
+behaviors where some method call changes behavior of others. In PHPUnit or Mockery
+you do that by predicting how many times your method will be called. In Prophecy,
+you'll use promises for that:
+
+```php
+$user->getName()->willReturn(null);
+
+// For PHP 5.4
+$user->setName('everzet')->will(function () {
+ $this->getName()->willReturn('everzet');
+});
+
+// For PHP 5.3
+$user->setName('everzet')->will(function ($args, $user) {
+ $user->getName()->willReturn('everzet');
+});
+
+// Or
+$user->setName('everzet')->will(function ($args) use ($user) {
+ $user->getName()->willReturn('everzet');
+});
+```
+
+And now it doesn't matter how many times or in which order your methods are called.
+What matters is their behaviors and how well you faked it.
+
+#### Arguments wildcarding
+
+The previous example is awesome (at least I hope it is for you), but that's not
+optimal enough. We hardcoded `'everzet'` in our expectation. Isn't there a better
+way? In fact there is, but it involves understanding what this `'everzet'`
+actually is.
+
+You see, even if method arguments used during method prophecy creation look
+like simple method arguments, in reality they are not. They are argument token
+wildcards. As a matter of fact, `->setName('everzet')` looks like a simple call just
+because Prophecy automatically transforms it under the hood into:
+
+```php
+$user->setName(new Prophecy\Argument\Token\ExactValueToken('everzet'));
+```
+
+Those argument tokens are simple PHP classes, that implement
+`Prophecy\Argument\Token\TokenInterface` and tell Prophecy how to compare real arguments
+with your expectations. And yes, those classnames are damn big. That's why there's a
+shortcut class `Prophecy\Argument`, which you can use to create tokens like that:
+
+```php
+use Prophecy\Argument;
+
+$user->setName(Argument::exact('everzet'));
+```
+
+`ExactValueToken` is not very useful in our case as it forced us to hardcode the username.
+That's why Prophecy comes bundled with a bunch of other tokens:
+
+- `IdenticalValueToken` or `Argument::is($value)` - checks that the argument is identical to a specific value
+- `ExactValueToken` or `Argument::exact($value)` - checks that the argument matches a specific value
+- `TypeToken` or `Argument::type($typeOrClass)` - checks that the argument matches a specific type or
+ classname
+- `ObjectStateToken` or `Argument::which($method, $value)` - checks that the argument method returns
+ a specific value
+- `CallbackToken` or `Argument::that(callback)` - checks that the argument matches a custom callback
+- `AnyValueToken` or `Argument::any()` - matches any argument
+- `AnyValuesToken` or `Argument::cetera()` - matches any arguments to the rest of the signature
+- `StringContainsToken` or `Argument::containingString($value)` - checks that the argument contains a specific string value
+
+And you can add even more by implementing `TokenInterface` with your own custom classes.
+
+So, let's refactor our initial `{set,get}Name()` logic with argument tokens:
+
+```php
+use Prophecy\Argument;
+
+$user->getName()->willReturn(null);
+
+// For PHP 5.4
+$user->setName(Argument::type('string'))->will(function ($args) {
+ $this->getName()->willReturn($args[0]);
+});
+
+// For PHP 5.3
+$user->setName(Argument::type('string'))->will(function ($args, $user) {
+ $user->getName()->willReturn($args[0]);
+});
+
+// Or
+$user->setName(Argument::type('string'))->will(function ($args) use ($user) {
+ $user->getName()->willReturn($args[0]);
+});
+```
+
+That's it. Now our `{set,get}Name()` prophecy will work with any string argument provided to it.
+We've just described how our stub object should behave, even though the original object could have
+no behavior whatsoever.
+
+One last bit about arguments now. You might ask, what happens in case of:
+
+```php
+use Prophecy\Argument;
+
+$user->getName()->willReturn(null);
+
+// For PHP 5.4
+$user->setName(Argument::type('string'))->will(function ($args) {
+ $this->getName()->willReturn($args[0]);
+});
+
+// For PHP 5.3
+$user->setName(Argument::type('string'))->will(function ($args, $user) {
+ $user->getName()->willReturn($args[0]);
+});
+
+// Or
+$user->setName(Argument::type('string'))->will(function ($args) use ($user) {
+ $user->getName()->willReturn($args[0]);
+});
+
+$user->setName(Argument::any())->will(function () {
+});
+```
+
+Nothing. Your stub will continue behaving the way it did before. That's because of how
+arguments wildcarding works. Every argument token type has a different score level, which
+wildcard then uses to calculate the final arguments match score and use the method prophecy
+promise that has the highest score. In this case, `Argument::type()` in case of success
+scores `5` and `Argument::any()` scores `3`. So the type token wins, as does the first
+`setName()` method prophecy and its promise. The simple rule of thumb - more precise token
+always wins.
+
+#### Getting stub objects
+
+Ok, now we know how to define our prophecy method promises, let's get our stub from
+it:
+
+```php
+$stub = $prophecy->reveal();
+```
+
+As you might see, the only difference between how we get dummies and stubs is that with
+stubs we describe every object conversation instead of just agreeing with `null` returns
+(object being *dummy*). As a matter of fact, after you define your first promise
+(method call), Prophecy will force you to define all the communications - it throws
+the `UnexpectedCallException` for any call you didn't describe with object prophecy before
+calling it on a stub.
+
+### Mocks
+
+Now we know how to define doubles without behavior (dummies) and doubles with behavior, but
+no expectations (stubs). What's left is doubles for which we have some expectations. These
+are called mocks and in Prophecy they look almost exactly the same as stubs, except that
+they define *predictions* instead of *promises* on method prophecies:
+
+```php
+$entityManager->flush()->shouldBeCalled();
+```
+
+#### Predictions
+
+The `shouldBeCalled()` method here assigns `CallPrediction` to our method prophecy.
+Predictions are a delayed behavior check for your prophecies. You see, during the entire lifetime
+of your doubles, Prophecy records every single call you're making against it inside your
+code. After that, Prophecy can use this collected information to check if it matches defined
+predictions. You can assign predictions to method prophecies using the
+`MethodProphecy::should(PredictionInterface $prediction)` method. As a matter of fact,
+the `shouldBeCalled()` method we used earlier is just a shortcut to:
+
+```php
+$entityManager->flush()->should(new Prophecy\Prediction\CallPrediction());
+```
+
+It checks if your method of interest (that matches both the method name and the arguments wildcard)
+was called 1 or more times. If the prediction failed then it throws an exception. When does this
+check happen? Whenever you call `checkPredictions()` on the main Prophet object:
+
+```php
+$prophet->checkPredictions();
+```
+
+In PHPUnit, you would want to put this call into the `tearDown()` method. If no predictions
+are defined, it would do nothing. So it won't harm to call it after every test.
+
+There are plenty more predictions you can play with:
+
+- `CallPrediction` or `shouldBeCalled()` - checks that the method has been called 1 or more times
+- `NoCallsPrediction` or `shouldNotBeCalled()` - checks that the method has not been called
+- `CallTimesPrediction` or `shouldBeCalledTimes($count)` - checks that the method has been called
+ `$count` times
+- `CallbackPrediction` or `should($callback)` - checks the method against your own custom callback
+
+Of course, you can always create your own custom prediction any time by implementing
+`PredictionInterface`.
+
+### Spies
+
+The last bit of awesomeness in Prophecy is out-of-the-box spies support. As I said in the previous
+section, Prophecy records every call made during the double's entire lifetime. This means
+you don't need to record predictions in order to check them. You can also do it
+manually by using the `MethodProphecy::shouldHave(PredictionInterface $prediction)` method:
+
+```php
+$em = $prophet->prophesize('Doctrine\ORM\EntityManager');
+
+$controller->createUser($em->reveal());
+
+$em->flush()->shouldHaveBeenCalled();
+```
+
+Such manipulation with doubles is called spying. And with Prophecy it just works.
diff --git a/vendor/phpspec/prophecy/composer.json b/vendor/phpspec/prophecy/composer.json
new file mode 100644
index 0000000..816f147
--- /dev/null
+++ b/vendor/phpspec/prophecy/composer.json
@@ -0,0 +1,50 @@
+{
+ "name": "phpspec/prophecy",
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "keywords": ["Mock", "Stub", "Dummy", "Double", "Fake", "Spy"],
+ "homepage": "https://github.com/phpspec/prophecy",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
+ }
+ ],
+
+ "require": {
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "sebastian/comparator": "^1.1|^2.0|^3.0",
+ "doctrine/instantiator": "^1.0.2",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ },
+
+ "require-dev": {
+ "phpspec/phpspec": "^2.5|^3.2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+ },
+
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+
+ "autoload-dev": {
+ "psr-4": {
+ "Fixtures\\Prophecy\\": "fixtures"
+ }
+ },
+
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.8.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument.php b/vendor/phpspec/prophecy/src/Prophecy/Argument.php
new file mode 100644
index 0000000..fde6aa9
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument.php
@@ -0,0 +1,212 @@
+
+ * Marcello Duarte
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy;
+
+use Prophecy\Argument\Token;
+
+/**
+ * Argument tokens shortcuts.
+ *
+ * @author Konstantin Kudryashov
+ */
+class Argument
+{
+ /**
+ * Checks that argument is exact value or object.
+ *
+ * @param mixed $value
+ *
+ * @return Token\ExactValueToken
+ */
+ public static function exact($value)
+ {
+ return new Token\ExactValueToken($value);
+ }
+
+ /**
+ * Checks that argument is of specific type or instance of specific class.
+ *
+ * @param string $type Type name (`integer`, `string`) or full class name
+ *
+ * @return Token\TypeToken
+ */
+ public static function type($type)
+ {
+ return new Token\TypeToken($type);
+ }
+
+ /**
+ * Checks that argument object has specific state.
+ *
+ * @param string $methodName
+ * @param mixed $value
+ *
+ * @return Token\ObjectStateToken
+ */
+ public static function which($methodName, $value)
+ {
+ return new Token\ObjectStateToken($methodName, $value);
+ }
+
+ /**
+ * Checks that argument matches provided callback.
+ *
+ * @param callable $callback
+ *
+ * @return Token\CallbackToken
+ */
+ public static function that($callback)
+ {
+ return new Token\CallbackToken($callback);
+ }
+
+ /**
+ * Matches any single value.
+ *
+ * @return Token\AnyValueToken
+ */
+ public static function any()
+ {
+ return new Token\AnyValueToken;
+ }
+
+ /**
+ * Matches all values to the rest of the signature.
+ *
+ * @return Token\AnyValuesToken
+ */
+ public static function cetera()
+ {
+ return new Token\AnyValuesToken;
+ }
+
+ /**
+ * Checks that argument matches all tokens
+ *
+ * @param mixed ... a list of tokens
+ *
+ * @return Token\LogicalAndToken
+ */
+ public static function allOf()
+ {
+ return new Token\LogicalAndToken(func_get_args());
+ }
+
+ /**
+ * Checks that argument array or countable object has exact number of elements.
+ *
+ * @param integer $value array elements count
+ *
+ * @return Token\ArrayCountToken
+ */
+ public static function size($value)
+ {
+ return new Token\ArrayCountToken($value);
+ }
+
+ /**
+ * Checks that argument array contains (key, value) pair
+ *
+ * @param mixed $key exact value or token
+ * @param mixed $value exact value or token
+ *
+ * @return Token\ArrayEntryToken
+ */
+ public static function withEntry($key, $value)
+ {
+ return new Token\ArrayEntryToken($key, $value);
+ }
+
+ /**
+ * Checks that arguments array entries all match value
+ *
+ * @param mixed $value
+ *
+ * @return Token\ArrayEveryEntryToken
+ */
+ public static function withEveryEntry($value)
+ {
+ return new Token\ArrayEveryEntryToken($value);
+ }
+
+ /**
+ * Checks that argument array contains value
+ *
+ * @param mixed $value
+ *
+ * @return Token\ArrayEntryToken
+ */
+ public static function containing($value)
+ {
+ return new Token\ArrayEntryToken(self::any(), $value);
+ }
+
+ /**
+ * Checks that argument array has key
+ *
+ * @param mixed $key exact value or token
+ *
+ * @return Token\ArrayEntryToken
+ */
+ public static function withKey($key)
+ {
+ return new Token\ArrayEntryToken($key, self::any());
+ }
+
+ /**
+ * Checks that argument does not match the value|token.
+ *
+ * @param mixed $value either exact value or argument token
+ *
+ * @return Token\LogicalNotToken
+ */
+ public static function not($value)
+ {
+ return new Token\LogicalNotToken($value);
+ }
+
+ /**
+ * @param string $value
+ *
+ * @return Token\StringContainsToken
+ */
+ public static function containingString($value)
+ {
+ return new Token\StringContainsToken($value);
+ }
+
+ /**
+ * Checks that argument is identical value.
+ *
+ * @param mixed $value
+ *
+ * @return Token\IdenticalValueToken
+ */
+ public static function is($value)
+ {
+ return new Token\IdenticalValueToken($value);
+ }
+
+ /**
+ * Check that argument is same value when rounding to the
+ * given precision.
+ *
+ * @param float $value
+ * @param float $precision
+ *
+ * @return Token\ApproximateValueToken
+ */
+ public static function approximate($value, $precision = 0)
+ {
+ return new Token\ApproximateValueToken($value, $precision);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php
new file mode 100644
index 0000000..a088f21
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php
@@ -0,0 +1,101 @@
+
+ * Marcello Duarte
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument;
+
+/**
+ * Arguments wildcarding.
+ *
+ * @author Konstantin Kudryashov
+ */
+class ArgumentsWildcard
+{
+ /**
+ * @var Token\TokenInterface[]
+ */
+ private $tokens = array();
+ private $string;
+
+ /**
+ * Initializes wildcard.
+ *
+ * @param array $arguments Array of argument tokens or values
+ */
+ public function __construct(array $arguments)
+ {
+ foreach ($arguments as $argument) {
+ if (!$argument instanceof Token\TokenInterface) {
+ $argument = new Token\ExactValueToken($argument);
+ }
+
+ $this->tokens[] = $argument;
+ }
+ }
+
+ /**
+ * Calculates wildcard match score for provided arguments.
+ *
+ * @param array $arguments
+ *
+ * @return false|int False OR integer score (higher - better)
+ */
+ public function scoreArguments(array $arguments)
+ {
+ if (0 == count($arguments) && 0 == count($this->tokens)) {
+ return 1;
+ }
+
+ $arguments = array_values($arguments);
+ $totalScore = 0;
+ foreach ($this->tokens as $i => $token) {
+ $argument = isset($arguments[$i]) ? $arguments[$i] : null;
+ if (1 >= $score = $token->scoreArgument($argument)) {
+ return false;
+ }
+
+ $totalScore += $score;
+
+ if (true === $token->isLast()) {
+ return $totalScore;
+ }
+ }
+
+ if (count($arguments) > count($this->tokens)) {
+ return false;
+ }
+
+ return $totalScore;
+ }
+
+ /**
+ * Returns string representation for wildcard.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if (null === $this->string) {
+ $this->string = implode(', ', array_map(function ($token) {
+ return (string) $token;
+ }, $this->tokens));
+ }
+
+ return $this->string;
+ }
+
+ /**
+ * @return array
+ */
+ public function getTokens()
+ {
+ return $this->tokens;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php
new file mode 100644
index 0000000..5098811
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php
@@ -0,0 +1,52 @@
+
+ * Marcello Duarte
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Any single value token.
+ *
+ * @author Konstantin Kudryashov
+ */
+class AnyValueToken implements TokenInterface
+{
+ /**
+ * Always scores 3 for any argument.
+ *
+ * @param $argument
+ *
+ * @return int
+ */
+ public function scoreArgument($argument)
+ {
+ return 3;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '*';
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php
new file mode 100644
index 0000000..f76b17b
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php
@@ -0,0 +1,52 @@
+
+ * Marcello Duarte
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Any values token.
+ *
+ * @author Konstantin Kudryashov
+ */
+class AnyValuesToken implements TokenInterface
+{
+ /**
+ * Always scores 2 for any argument.
+ *
+ * @param $argument
+ *
+ * @return int
+ */
+ public function scoreArgument($argument)
+ {
+ return 2;
+ }
+
+ /**
+ * Returns true to stop wildcard from processing other tokens.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return true;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '* [, ...]';
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php
new file mode 100644
index 0000000..d4918b1
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php
@@ -0,0 +1,55 @@
+
+ * Marcello Duarte
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Approximate value token
+ *
+ * @author Daniel Leech
+ */
+class ApproximateValueToken implements TokenInterface
+{
+ private $value;
+ private $precision;
+
+ public function __construct($value, $precision = 0)
+ {
+ $this->value = $value;
+ $this->precision = $precision;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function scoreArgument($argument)
+ {
+ return round($argument, $this->precision) === round($this->value, $this->precision) ? 10 : false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('≅%s', round($this->value, $this->precision));
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php
new file mode 100644
index 0000000..96b4bef
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php
@@ -0,0 +1,86 @@
+
+ * Marcello Duarte
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Array elements count token.
+ *
+ * @author Boris Mikhaylov
+ */
+
+class ArrayCountToken implements TokenInterface
+{
+ private $count;
+
+ /**
+ * @param integer $value
+ */
+ public function __construct($value)
+ {
+ $this->count = $value;
+ }
+
+ /**
+ * Scores 6 when argument has preset number of elements.
+ *
+ * @param $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ return $this->isCountable($argument) && $this->hasProperCount($argument) ? 6 : false;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return boolean
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('count(%s)', $this->count);
+ }
+
+ /**
+ * Returns true if object is either array or instance of \Countable
+ *
+ * @param $argument
+ * @return bool
+ */
+ private function isCountable($argument)
+ {
+ return (is_array($argument) || $argument instanceof \Countable);
+ }
+
+ /**
+ * Returns true if $argument has expected number of elements
+ *
+ * @param array|\Countable $argument
+ *
+ * @return bool
+ */
+ private function hasProperCount($argument)
+ {
+ return $this->count === count($argument);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php
new file mode 100644
index 0000000..0305fc7
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php
@@ -0,0 +1,143 @@
+
+ * Marcello Duarte
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+use Prophecy\Exception\InvalidArgumentException;
+
+/**
+ * Array entry token.
+ *
+ * @author Boris Mikhaylov
+ */
+class ArrayEntryToken implements TokenInterface
+{
+ /** @var \Prophecy\Argument\Token\TokenInterface */
+ private $key;
+ /** @var \Prophecy\Argument\Token\TokenInterface */
+ private $value;
+
+ /**
+ * @param mixed $key exact value or token
+ * @param mixed $value exact value or token
+ */
+ public function __construct($key, $value)
+ {
+ $this->key = $this->wrapIntoExactValueToken($key);
+ $this->value = $this->wrapIntoExactValueToken($value);
+ }
+
+ /**
+ * Scores half of combined scores from key and value tokens for same entry. Capped at 8.
+ * If argument implements \ArrayAccess without \Traversable, then key token is restricted to ExactValueToken.
+ *
+ * @param array|\ArrayAccess|\Traversable $argument
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ if ($argument instanceof \Traversable) {
+ $argument = iterator_to_array($argument);
+ }
+
+ if ($argument instanceof \ArrayAccess) {
+ $argument = $this->convertArrayAccessToEntry($argument);
+ }
+
+ if (!is_array($argument) || empty($argument)) {
+ return false;
+ }
+
+ $keyScores = array_map(array($this->key,'scoreArgument'), array_keys($argument));
+ $valueScores = array_map(array($this->value,'scoreArgument'), $argument);
+ $scoreEntry = function ($value, $key) {
+ return $value && $key ? min(8, ($key + $value) / 2) : false;
+ };
+
+ return max(array_map($scoreEntry, $valueScores, $keyScores));
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return boolean
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('[..., %s => %s, ...]', $this->key, $this->value);
+ }
+
+ /**
+ * Returns key
+ *
+ * @return TokenInterface
+ */
+ public function getKey()
+ {
+ return $this->key;
+ }
+
+ /**
+ * Returns value
+ *
+ * @return TokenInterface
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Wraps non token $value into ExactValueToken
+ *
+ * @param $value
+ * @return TokenInterface
+ */
+ private function wrapIntoExactValueToken($value)
+ {
+ return $value instanceof TokenInterface ? $value : new ExactValueToken($value);
+ }
+
+ /**
+ * Converts instance of \ArrayAccess to key => value array entry
+ *
+ * @param \ArrayAccess $object
+ *
+ * @return array|null
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ private function convertArrayAccessToEntry(\ArrayAccess $object)
+ {
+ if (!$this->key instanceof ExactValueToken) {
+ throw new InvalidArgumentException(sprintf(
+ 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL.
+ 'But you used `%s`.',
+ $this->key
+ ));
+ }
+
+ $key = $this->key->getValue();
+
+ return $object->offsetExists($key) ? array($key => $object[$key]) : array();
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php
new file mode 100644
index 0000000..5d41fa4
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php
@@ -0,0 +1,82 @@
+
+ * Marcello Duarte
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Array every entry token.
+ *
+ * @author Adrien Brault