From: Jeff Veit Date: Thu, 22 Jun 2017 05:56:47 +0000 (+0100) Subject: Yaffs site version 1.1 X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=commitdiff_plain;h=eba34333e3c89f208d2f72fa91351ad019a71583 Yaffs site version 1.1 --- diff --git a/.gitignore b/.gitignore index d0cc4284b..f718388f0 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ web/sites/simpletest .sass-cache/* web/themes/custom/yaffs/.sass-cache +web/console/cache/* diff --git a/composer.lock b/composer.lock index 4ff289981..eec1b9562 100644 --- a/composer.lock +++ b/composer.lock @@ -124,16 +124,16 @@ }, { "name": "caxy/php-htmldiff", - "version": "v0.1.4", + "version": "v0.1.5", "source": { "type": "git", "url": "https://github.com/caxy/php-htmldiff.git", - "reference": "9b115a83d49c636d6bae8ffce15b0e1962cb2ed7" + "reference": "d7540c9938c860f2cb7083f72ba24c45f51d57bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/caxy/php-htmldiff/zipball/9b115a83d49c636d6bae8ffce15b0e1962cb2ed7", - "reference": "9b115a83d49c636d6bae8ffce15b0e1962cb2ed7", + "url": "https://api.github.com/repos/caxy/php-htmldiff/zipball/d7540c9938c860f2cb7083f72ba24c45f51d57bc", + "reference": "d7540c9938c860f2cb7083f72ba24c45f51d57bc", "shasum": "" }, "require": { @@ -176,7 +176,7 @@ "diff", "html" ], - "time": "2017-05-02T21:16:54+00:00" + "time": "2017-06-12T17:35:44+00:00" }, { "name": "cebe/markdown", @@ -240,16 +240,16 @@ }, { "name": "composer/installers", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "d78064c68299743e0161004f2de3a0204e33b804" + "reference": "79ad876c7498c0bbfe7eed065b8651c93bfd6045" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/d78064c68299743e0161004f2de3a0204e33b804", - "reference": "d78064c68299743e0161004f2de3a0204e33b804", + "url": "https://api.github.com/repos/composer/installers/zipball/79ad876c7498c0bbfe7eed065b8651c93bfd6045", + "reference": "79ad876c7498c0bbfe7eed065b8651c93bfd6045", "shasum": "" }, "require": { @@ -291,12 +291,16 @@ "keywords": [ "Craft", "Dolibarr", + "Eliasis", "Hurad", "ImageCMS", + "Kanboard", "MODX Evo", "Mautic", + "Maya", "OXID", "Plentymarkets", + "Porto", "RadPHP", "SMF", "Thelia", @@ -319,9 +323,11 @@ "fuelphp", "grav", "installer", + "itop", "joomla", "kohana", "laravel", + "lavalite", "lithium", "magento", "mako", @@ -336,6 +342,7 @@ "roundcube", "shopware", "silverstripe", + "sydes", "symfony", "typo3", "wordpress", @@ -343,7 +350,7 @@ "zend", "zikula" ], - "time": "2016-08-13T20:53:52+00:00" + "time": "2017-04-24T06:37:16+00:00" }, { "name": "composer/semver", @@ -461,16 +468,16 @@ }, { "name": "consolidation/output-formatters", - "version": "3.1.8", + "version": "3.1.10", "source": { "type": "git", "url": "https://github.com/consolidation/output-formatters.git", - "reference": "0b50ba1134d581fd55376f3e21508dab009ced47" + "reference": "3872f19517bfc9da0e14c9e5b6fe0f8c7439ea3a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/0b50ba1134d581fd55376f3e21508dab009ced47", - "reference": "0b50ba1134d581fd55376f3e21508dab009ced47", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/3872f19517bfc9da0e14c9e5b6fe0f8c7439ea3a", + "reference": "3872f19517bfc9da0e14c9e5b6fe0f8c7439ea3a", "shasum": "" }, "require": { @@ -487,7 +494,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { @@ -506,7 +513,7 @@ } ], "description": "Format text by applying transformations provided by plug-in formatters.", - "time": "2017-03-01T20:54:45+00:00" + "time": "2017-06-06T19:08:54+00:00" }, { "name": "cweagans/composer-patches", @@ -896,28 +903,29 @@ }, { "name": "doctrine/collections", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", - "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "doctrine/coding-standard": "~0.1@dev", + "phpunit/phpunit": "^5.7" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { @@ -958,7 +966,7 @@ "collections", "iterator" ], - "time": "2015-04-14T22:21:58+00:00" + "time": "2017-01-03T10:49:41+00:00" }, { "name": "doctrine/common", @@ -1156,16 +1164,16 @@ }, { "name": "drupal-composer/drupal-scaffold", - "version": "2.2.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/drupal-composer/drupal-scaffold.git", - "reference": "3ad465ac853c2e52e6a808f5529859917662c256" + "reference": "1374e1031b98beb502abea3854f361304965c628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal-composer/drupal-scaffold/zipball/3ad465ac853c2e52e6a808f5529859917662c256", - "reference": "3ad465ac853c2e52e6a808f5529859917662c256", + "url": "https://api.github.com/repos/drupal-composer/drupal-scaffold/zipball/1374e1031b98beb502abea3854f361304965c628", + "reference": "1374e1031b98beb502abea3854f361304965c628", "shasum": "" }, "require": { @@ -1193,7 +1201,7 @@ "GPL-2.0+" ], "description": "Composer Plugin for updating the Drupal scaffold files when using drupal/core", - "time": "2016-11-05T10:46:44+00:00" + "time": "2017-05-05T21:26:28+00:00" }, { "name": "drupal/admin_toolbar", @@ -1437,17 +1445,17 @@ }, { "name": "drupal/blazy", - "version": "1.0.0-rc1", + "version": "1.0.0-rc2", "source": { "type": "git", "url": "https://git.drupal.org/project/blazy", - "reference": "8.x-1.0-rc1" + "reference": "8.x-1.0-rc2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/blazy-8.x-1.0-rc1.zip", - "reference": "8.x-1.0-rc1", - "shasum": "0502916f2cb5b6237f13e5216e12063b8d56ce42" + "url": "https://ftp.drupal.org/files/projects/blazy-8.x-1.0-rc2.zip", + "reference": null, + "shasum": "242f3022b039c6fd3b98f6ce1955d295119b4b5a" }, "require": { "drupal/core": "*" @@ -1458,8 +1466,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-rc1", - "datestamp": "1485193983" + "version": "8.x-1.0-rc2", + "datestamp": "1495745283" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -1758,24 +1766,24 @@ }, { "name": "drupal/console", - "version": "1.0.0-rc16", + "version": "1.0.0-rc21", "source": { "type": "git", "url": "https://github.com/hechoendrupal/drupal-console.git", - "reference": "955b057042635a5dc935799228ec7bbddf2c0cc2" + "reference": "e01db040db734b2f8b30921ababc53ce51d01896" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console/zipball/955b057042635a5dc935799228ec7bbddf2c0cc2", - "reference": "955b057042635a5dc935799228ec7bbddf2c0cc2", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console/zipball/e01db040db734b2f8b30921ababc53ce51d01896", + "reference": "e01db040db734b2f8b30921ababc53ce51d01896", "shasum": "" }, "require": { "alchemy/zippy": "0.4.3", "composer/installers": "~1.0", "doctrine/annotations": "1.2.*", - "doctrine/collections": "1.3.0", - "drupal/console-core": "1.0.0-rc16", + "doctrine/collections": "~1.3", + "drupal/console-core": "1.0.0-rc21", "drupal/console-extend-plugin": "~0", "gabordemooij/redbean": "~4.3", "guzzlehttp/guzzle": "~6.1", @@ -1832,25 +1840,25 @@ "drupal", "symfony" ], - "time": "2017-02-09T18:54:29+00:00" + "time": "2017-06-07T16:21:12+00:00" }, { "name": "drupal/console-core", - "version": "1.0.0-rc16", + "version": "1.0.0-rc21", "source": { "type": "git", "url": "https://github.com/hechoendrupal/drupal-console-core.git", - "reference": "42690f652b3a61d7d15fe9b785b946f3eb9227bf" + "reference": "a473a27292110e5f50e0ae8df36d38449ce55903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-core/zipball/42690f652b3a61d7d15fe9b785b946f3eb9227bf", - "reference": "42690f652b3a61d7d15fe9b785b946f3eb9227bf", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-core/zipball/a473a27292110e5f50e0ae8df36d38449ce55903", + "reference": "a473a27292110e5f50e0ae8df36d38449ce55903", "shasum": "" }, "require": { "dflydev/dot-access-configuration": "1.0.1", - "drupal/console-en": "1.0.0-rc16", + "drupal/console-en": "1.0.0-rc21", "php": "^5.5.9 || ^7.0", "stecman/symfony-console-completion": "~0.7", "symfony/config": ">=2.7 <3.0", @@ -1864,12 +1872,11 @@ "symfony/translation": ">=2.7 <3.0", "symfony/yaml": ">=2.7 <3.0", "twig/twig": "^1.23.1", - "webflo/drupal-finder": "0.*" + "webflo/drupal-finder": "^0.3.0" }, "type": "project", "autoload": { "files": [ - "src/constants.php", "src/functions.php" ], "psr-4": { @@ -1913,20 +1920,20 @@ "drupal", "symfony" ], - "time": "2017-02-09T18:22:32+00:00" + "time": "2017-06-07T15:57:23+00:00" }, { "name": "drupal/console-en", - "version": "1.0.0-rc16", + "version": "1.0.0-rc21", "source": { "type": "git", "url": "https://github.com/hechoendrupal/drupal-console-en.git", - "reference": "32c1e4c31500ba4ccd5e68bd74977fd6258c3e37" + "reference": "b6f563b8760c3b19aad22dd213a9cfba2f2c75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-en/zipball/32c1e4c31500ba4ccd5e68bd74977fd6258c3e37", - "reference": "32c1e4c31500ba4ccd5e68bd74977fd6258c3e37", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-en/zipball/b6f563b8760c3b19aad22dd213a9cfba2f2c75d0", + "reference": "b6f563b8760c3b19aad22dd213a9cfba2f2c75d0", "shasum": "" }, "type": "drupal-console-language", @@ -1967,20 +1974,20 @@ "drupal", "symfony" ], - "time": "2017-02-09T16:02:27+00:00" + "time": "2017-05-20T23:29:05+00:00" }, { "name": "drupal/console-extend-plugin", - "version": "0.4.0", + "version": "0.8.0", "source": { "type": "git", "url": "https://github.com/hechoendrupal/drupal-console-extend-plugin.git", - "reference": "df2396782960335d18a8e5eb6ab630a37ca5f493" + "reference": "d69ffe413259781c4257ab42bd79c9da9042e87e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-extend-plugin/zipball/df2396782960335d18a8e5eb6ab630a37ca5f493", - "reference": "df2396782960335d18a8e5eb6ab630a37ca5f493", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-extend-plugin/zipball/d69ffe413259781c4257ab42bd79c9da9042e87e", + "reference": "d69ffe413259781c4257ab42bd79c9da9042e87e", "shasum": "" }, "require": { @@ -2008,7 +2015,7 @@ } ], "description": "Drupal Console Extend Plugin", - "time": "2017-02-14T08:38:49+00:00" + "time": "2017-06-08T16:06:59+00:00" }, { "name": "drupal/core", @@ -2497,17 +2504,17 @@ }, { "name": "drupal/dropzonejs", - "version": "1.0.0-alpha6", + "version": "1.0.0-alpha7", "source": { "type": "git", "url": "https://git.drupal.org/project/dropzonejs", - "reference": "8.x-1.0-alpha6" + "reference": "8.x-1.0-alpha7" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/dropzonejs-8.x-1.0-alpha6.zip", - "reference": "8.x-1.0-alpha6", - "shasum": "7cc19398eed42b584c06e442f57c4da64b4c4bbb" + "url": "https://ftp.drupal.org/files/projects/dropzonejs-8.x-1.0-alpha7.zip", + "reference": null, + "shasum": "62fc6d46cee1d5fa9885bab3e65b3638172311f6" }, "require": { "drupal/core": "*" @@ -2524,8 +2531,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-alpha6", - "datestamp": "1490199183" + "version": "8.x-1.0-alpha7", + "datestamp": "1495200183" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -2580,7 +2587,7 @@ }, { "name": "drupal/dropzonejs_eb_widget", - "version": "1.0.0-alpha6", + "version": "1.0.0-alpha7", "require": { "drupal/core": "*", "drupal/dropzonejs": "self.version", @@ -2592,8 +2599,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-alpha6", - "datestamp": "1490199183" + "version": "8.x-1.0-alpha7", + "datestamp": "1495200183" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -2858,17 +2865,17 @@ }, { "name": "drupal/entity_browser", - "version": "1.0.0-rc2", + "version": "1.0.0", "source": { "type": "git", "url": "https://git.drupal.org/project/entity_browser", - "reference": "8.x-1.0-rc2" + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/entity_browser-8.x-1.0-rc2.zip", - "reference": "8.x-1.0-rc2", - "shasum": "7954668b9134a8ec2dac2604c482d6521e43ee91" + "url": "https://ftp.drupal.org/files/projects/entity_browser-8.x-1.0.zip", + "reference": null, + "shasum": "6bd7bbcda1eebacc3685e9edaad2ad29b525b2ad" }, "require": { "drupal/core": "~8.0" @@ -2887,8 +2894,8 @@ "dev-8.x-1.x": "8.1.x-dev" }, "drupal": { - "version": "8.x-1.0-rc2", - "datestamp": "1487581984" + "version": "8.x-1.0", + "datestamp": "1492678144" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -2938,7 +2945,7 @@ }, { "name": "drupal/entity_browser_entity_form", - "version": "1.0.0-rc2", + "version": "1.0.0", "require": { "drupal/core": "~8.0", "drupal/entity_browser": "self.version", @@ -2950,8 +2957,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-rc2", - "datestamp": "1487581984" + "version": "8.x-1.0", + "datestamp": "1492678144" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -3061,17 +3068,17 @@ }, { "name": "drupal/entity_reference_revisions", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://git.drupal.org/project/entity_reference_revisions", - "reference": "8.x-1.2" + "reference": "8.x-1.3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/entity_reference_revisions-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "15261a4237cc2a743522a7bd81e9f34e01d12843" + "url": "https://ftp.drupal.org/files/projects/entity_reference_revisions-8.x-1.3.zip", + "reference": null, + "shasum": "78aebb58efbbfcbb2faa40a1afc0830312b32631" }, "require": { "drupal/core": "~8.0" @@ -3085,8 +3092,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1485790085" + "version": "8.x-1.3", + "datestamp": "1495814284" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -3587,17 +3594,17 @@ }, { "name": "drupal/image_widget_crop", - "version": "1.5.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://git.drupal.org/project/image_widget_crop", - "reference": "8.x-1.5" + "reference": "8.x-2.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/image_widget_crop-8.x-1.5.zip", - "reference": "8.x-1.5", - "shasum": "1f0a3de727d22a675c8be2e7af49ea22592d9d19" + "url": "https://ftp.drupal.org/files/projects/image_widget_crop-8.x-2.0.zip", + "reference": null, + "shasum": "2c8e13e0c73d95a3f8dde5392da2ef20c3d17faa" }, "require": { "drupal/core": "*", @@ -3605,19 +3612,22 @@ }, "require-dev": { "drupal/crop": "*", + "drupal/ctools": "3.x-dev", + "drupal/entity_browser": "1.x-dev", "drupal/file_entity": "*", + "drupal/imce": "1.x-dev", "drupal/inline_entity_form": "*", "drupal/media_entity": "*", - "drupal/media_entity_image": "*" + "drupal/media_entity_image": "1.x-dev" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-2.x": "2.x-dev" }, "drupal": { - "version": "8.x-1.5", - "datestamp": "1491393484" + "version": "8.x-2.0", + "datestamp": "1492618444" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -4423,22 +4433,21 @@ }, { "name": "drupal/media_entity_instagram", - "version": "1.2.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://git.drupal.org/project/media_entity_instagram", - "reference": "8.x-1.2" + "reference": "8.x-1.4" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/media_entity_instagram-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "1183314bbfed2dfeaeabdc7e970521b394c5e337" + "url": "https://ftp.drupal.org/files/projects/media_entity_instagram-8.x-1.4.zip", + "reference": null, + "shasum": "2b69b90417f3c458b4db3ba890813c313d381f0e" }, "require": { "drupal/core": "~8.0", - "drupal/media_entity": "*", - "php-instagram-api/php-instagram-api": "dev-master" + "drupal/media_entity": "*" }, "type": "drupal-module", "extra": { @@ -4446,8 +4455,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1470169139" + "version": "8.x-1.4", + "datestamp": "1495556283" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -4463,6 +4472,10 @@ "name": "Primsi", "homepage": "https://www.drupal.org/user/282629" }, + { + "name": "chr.fritsch", + "homepage": "https://www.drupal.org/user/2103716" + }, { "name": "designesse", "homepage": "https://www.drupal.org/user/854012" @@ -4472,7 +4485,7 @@ "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Provides a media entity instagram.", + "description": "Media entity Instagram provider.", "homepage": "https://www.drupal.org/project/media_entity_instagram", "support": { "source": "http://cgit.drupalcode.org/media_entity_instagram" @@ -4581,17 +4594,17 @@ }, { "name": "drupal/memcache", - "version": "2.0.0-alpha2", + "version": "2.0.0-alpha3", "source": { "type": "git", "url": "https://git.drupal.org/project/memcache", - "reference": "8.x-2.0-alpha2" + "reference": "8.x-2.0-alpha3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/memcache-8.x-2.0-alpha2.zip", - "reference": "8.x-2.0-alpha2", - "shasum": "dedad417e274e06a064e282135ce2f05b2c2c6ba" + "url": "https://ftp.drupal.org/files/projects/memcache-8.x-2.0-alpha3.zip", + "reference": null, + "shasum": "21db65a220e2a71227fa7a88f4033559fec5c9ff" }, "require": { "drupal/core": "~8.0" @@ -4602,8 +4615,8 @@ "dev-2.x": "2.x-dev" }, "drupal": { - "version": "8.x-2.0-alpha2", - "datestamp": "1473758939" + "version": "8.x-2.0-alpha3", + "datestamp": "1492523944" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -4633,24 +4646,25 @@ } ], "description": "High performance integration with memcache.", - "homepage": "https://www.drupal.org/project/memcache", + "homepage": "http://drupal.org/project/memcache", "support": { - "source": "http://cgit.drupalcode.org/memcache" + "source": "http://cgit.drupalcode.org/memcache", + "issues": "https://www.drupal.org/project/issues/memcache" } }, { "name": "drupal/metatag", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://git.drupal.org/project/metatag", - "reference": "8.x-1.0" + "reference": "8.x-1.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/metatag-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "604e45e89c19f5a8960b6a8ae3d80500d4328e6b" + "url": "https://ftp.drupal.org/files/projects/metatag-8.x-1.1.zip", + "reference": null, + "shasum": "bb9b608879e2f7d8086a0e6606286086f5009d71" }, "require": { "drupal/core": "*", @@ -4666,8 +4680,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1485902197" + "version": "8.x-1.1", + "datestamp": "1496428672" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -4698,20 +4712,20 @@ }, { "name": "drupal/migrate_plus", - "version": "3.0.0-beta1", + "version": "4.0.0-beta1", "source": { "type": "git", "url": "https://git.drupal.org/project/migrate_plus", - "reference": "8.x-3.0-beta1" + "reference": "8.x-4.0-beta1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/migrate_plus-8.x-3.0-beta1.zip", - "reference": "8.x-3.0-beta1", - "shasum": "7bae5c758a432053863b7b19c94fc1b829debf00" + "url": "https://ftp.drupal.org/files/projects/migrate_plus-8.x-4.0-beta1.zip", + "reference": null, + "shasum": "e64bac006e3ef9ae697b0f2c4b3744af0524e208" }, "require": { - "drupal/core": "^8.2" + "drupal/core": "^8.3" }, "require-dev": { "drupal/migrate_example_advanced_setup": "*", @@ -4723,11 +4737,11 @@ "type": "drupal-module", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev" + "dev-4.x": "4.x-dev" }, "drupal": { - "version": "8.x-3.0-beta1", - "datestamp": "1476307739" + "version": "8.x-4.0-beta1", + "datestamp": "1494450185" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -4739,6 +4753,10 @@ "name": "Mike Ryan", "homepage": "https://www.drupal.org/u/mikeryan", "role": "Maintainer" + }, + { + "name": "mikeryan", + "homepage": "https://www.drupal.org/user/4420" } ], "description": "Enhancements to core migration support.", @@ -4988,7 +5006,7 @@ "source": { "type": "git", "url": "https://git.drupal.org/project/pathologic", - "reference": "e0473546e51cbeaa3acb34e3208a0c503ca85613" + "reference": "4f9f3fdcf1e0b224c4d8650e383a769f40abf9bf" }, "require": { "drupal/core": "*" @@ -5000,7 +5018,7 @@ }, "drupal": { "version": "8.x-1.x-dev", - "datestamp": "1446842039" + "datestamp": "1494720785" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -5022,7 +5040,7 @@ "support": { "source": "http://cgit.drupalcode.org/pathologic" }, - "time": "2015-11-06 20:32:35" + "time": "2017-05-14 00:18:53" }, { "name": "drupal/permissions_by_term", @@ -5235,8 +5253,7 @@ "homepage": "https://www.drupal.org/project/security_review", "support": { "source": "http://cgit.drupalcode.org/security_review" - }, - "time": "2016-10-20 15:43:48" + } }, { "name": "drupal/simple_sitemap", @@ -5292,17 +5309,17 @@ }, { "name": "drupal/slick", - "version": "1.0.0-rc3", + "version": "1.0.0", "source": { "type": "git", "url": "https://git.drupal.org/project/slick", - "reference": "8.x-1.0-rc3" + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/slick-8.x-1.0-rc3.zip", - "reference": "8.x-1.0-rc3", - "shasum": "e47be5189e3d03e2824a6ecfd41f14c45eea9a55" + "url": "https://ftp.drupal.org/files/projects/slick-8.x-1.0.zip", + "reference": null, + "shasum": "14ae69943a07749163ed13900dcd0a6809c54ebd" }, "require": { "drupal/blazy": "~1.0", @@ -5314,8 +5331,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-rc3", - "datestamp": "1490295783" + "version": "8.x-1.0", + "datestamp": "1495746183" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -5346,17 +5363,17 @@ }, { "name": "drupal/slick_media", - "version": "1.0.0-rc1", + "version": "1.0.0", "source": { "type": "git", "url": "https://git.drupal.org/project/slick_media", - "reference": "8.x-1.0-rc1" + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/slick_media-8.x-1.0-rc1.zip", - "reference": "8.x-1.0-rc1", - "shasum": "061addb670bc7af541b90880aac1c78da7c96812" + "url": "https://ftp.drupal.org/files/projects/slick_media-8.x-1.0.zip", + "reference": null, + "shasum": "b85a9899c53ca2f59f7cdbba044e2f58ae71e092" }, "require": { "drupal/core": "~8.0", @@ -5370,8 +5387,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-rc1", - "datestamp": "1485194885" + "version": "8.x-1.0", + "datestamp": "1495747983" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -5392,20 +5409,21 @@ }, { "name": "drupal/superfish", - "version": "1.0.0-rc6", + "version": "1.1.0", "source": { "type": "git", "url": "https://git.drupal.org/project/superfish", - "reference": "8.x-1.0-rc6" + "reference": "8.x-1.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/superfish-8.x-1.0-rc6.zip", - "reference": "8.x-1.0-rc6", - "shasum": "0e9ca0b25eef5cb6c0beaab233b3062a51e87699" + "url": "https://ftp.drupal.org/files/projects/superfish-8.x-1.1.zip", + "reference": null, + "shasum": "f5e9e547d1d38588a963b22105dec1deb1e55010" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "~8.0", + "mehrpadin/superfish": "~2.0" }, "type": "drupal-module", "extra": { @@ -5413,8 +5431,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-rc6", - "datestamp": "1486319283" + "version": "8.x-1.1", + "datestamp": "1496335443" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -5722,17 +5740,17 @@ }, { "name": "drupal/video_embed_field", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://git.drupal.org/project/video_embed_field", - "reference": "8.x-1.4" + "reference": "8.x-1.5" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/video_embed_field-8.x-1.4.zip", - "reference": "8.x-1.4", - "shasum": "7bf93a52e2e8d639b4dbefd65f0ee2b170d73f43" + "url": "https://ftp.drupal.org/files/projects/video_embed_field-8.x-1.5.zip", + "reference": null, + "shasum": "f54d470ef7f863604e51e6ae98cd40ef25de5f79" }, "require": { "drupal/core": "*" @@ -5749,7 +5767,7 @@ }, "drupal": { "version": "8.x-1.x", - "datestamp": "1484253183", + "datestamp": "1493246342", "package": "Field types" } }, @@ -5779,7 +5797,7 @@ }, { "name": "drupal/video_embed_media", - "version": "1.4.0", + "version": "1.5.0", "require": { "drupal/core": "~8.0", "drupal/media_entity": "*", @@ -5791,8 +5809,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.4", - "datestamp": "1484253183" + "version": "8.x-1.5", + "datestamp": "1493246342" } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -6020,16 +6038,16 @@ }, { "name": "drush/drush", - "version": "8.1.10", + "version": "8.1.12", "source": { "type": "git", "url": "https://github.com/drush-ops/drush.git", - "reference": "2192496b80aa9cdb0581a2d308623f950f747e94" + "reference": "a1d3ab0f1d9ce01556d70015906caaed723f7ba7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drush-ops/drush/zipball/2192496b80aa9cdb0581a2d308623f950f747e94", - "reference": "2192496b80aa9cdb0581a2d308623f950f747e94", + "url": "https://api.github.com/repos/drush-ops/drush/zipball/a1d3ab0f1d9ce01556d70015906caaed723f7ba7", + "reference": "a1d3ab0f1d9ce01556d70015906caaed723f7ba7", "shasum": "" }, "require": { @@ -6121,7 +6139,7 @@ ], "description": "Drush is a command line shell and scripting interface for Drupal, a veritable Swiss Army knife designed to make life easier for those of us who spend some of our working hours hacking away at the command prompt.", "homepage": "http://www.drush.org", - "time": "2017-02-23T20:46:12+00:00" + "time": "2017-06-05T22:51:34+00:00" }, { "name": "easyrdf/easyrdf", @@ -6275,16 +6293,16 @@ }, { "name": "ezyang/htmlpurifier", - "version": "v4.9.2", + "version": "v4.9.3", "source": { "type": "git", "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "6d50e5282afdfdfc3e0ff6d192aff56c5629b3d4" + "reference": "95e1bae3182efc0f3422896a3236e991049dac69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/6d50e5282afdfdfc3e0ff6d192aff56c5629b3d4", - "reference": "6d50e5282afdfdfc3e0ff6d192aff56c5629b3d4", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/95e1bae3182efc0f3422896a3236e991049dac69", + "reference": "95e1bae3182efc0f3422896a3236e991049dac69", "shasum": "" }, "require": { @@ -6318,20 +6336,20 @@ "keywords": [ "html" ], - "time": "2017-03-13T06:30:53+00:00" + "time": "2017-06-03T02:28:16+00:00" }, { "name": "gabordemooij/redbean", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/gabordemooij/redbean.git", - "reference": "1c7ec69850e9f7966ff7feb87b01d8f43a9753d3" + "reference": "d0944d7f966d7f45a0d973981fe3f64aff0050f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/gabordemooij/redbean/zipball/1c7ec69850e9f7966ff7feb87b01d8f43a9753d3", - "reference": "1c7ec69850e9f7966ff7feb87b01d8f43a9753d3", + "url": "https://api.github.com/repos/gabordemooij/redbean/zipball/d0944d7f966d7f45a0d973981fe3f64aff0050f0", + "reference": "d0944d7f966d7f45a0d973981fe3f64aff0050f0", "shasum": "" }, "require": { @@ -6359,7 +6377,7 @@ "keywords": [ "orm" ], - "time": "2016-10-03T21:25:17+00:00" + "time": "2017-03-07T22:26:54+00:00" }, { "name": "geedmo/yamm3", @@ -6663,16 +6681,16 @@ }, { "name": "j7mbo/twitter-api-php", - "version": "1.0.5", + "version": "1.0.6", "source": { "type": "git", "url": "https://github.com/J7mbo/twitter-api-php.git", - "reference": "a89ce3e294484aad7ae13dbabe45fb3928024ef8" + "reference": "443d22c53d621b3cc6b7e0c56daa60c5ada033f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/J7mbo/twitter-api-php/zipball/a89ce3e294484aad7ae13dbabe45fb3928024ef8", - "reference": "a89ce3e294484aad7ae13dbabe45fb3928024ef8", + "url": "https://api.github.com/repos/J7mbo/twitter-api-php/zipball/443d22c53d621b3cc6b7e0c56daa60c5ada033f7", + "reference": "443d22c53d621b3cc6b7e0c56daa60c5ada033f7", "shasum": "" }, "require": { @@ -6688,7 +6706,7 @@ } }, "autoload": { - "files": [ + "classmap": [ "TwitterAPIExchange.php" ] }, @@ -6709,7 +6727,7 @@ "php", "twitter" ], - "time": "2015-08-03T21:35:18+00:00" + "time": "2017-05-08T12:10:56+00:00" }, { "name": "jakub-onderka/php-console-color", @@ -6865,19 +6883,19 @@ }, { "name": "mehrpadin/superfish", - "version": "2.0", + "version": "2.1", "source": { "type": "git", "url": "https://github.com/mehrpadin/Superfish-for-Drupal.git", - "reference": "af9cb4ef91062a9ab1847595516a73bddf4cde6d" + "reference": "80a0a484b727e9fbe6b0ee609f80e10e5e158683" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mehrpadin/Superfish-for-Drupal/zipball/af9cb4ef91062a9ab1847595516a73bddf4cde6d", - "reference": "af9cb4ef91062a9ab1847595516a73bddf4cde6d", + "url": "https://api.github.com/repos/mehrpadin/Superfish-for-Drupal/zipball/80a0a484b727e9fbe6b0ee609f80e10e5e158683", + "reference": "80a0a484b727e9fbe6b0ee609f80e10e5e158683", "shasum": "" }, - "type": "library", + "type": "drupal-library", "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" @@ -6888,7 +6906,7 @@ "jquery", "plugin" ], - "time": "2017-01-28T20:31:57+00:00" + "time": "2017-05-30T13:00:18+00:00" }, { "name": "michelf/php-markdown", @@ -7132,60 +7150,18 @@ ], "time": "2016-01-21T16:14:31+00:00" }, - { - "name": "php-instagram-api/php-instagram-api", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/galen/PHP-Instagram-API.git", - "reference": "7a796fdae715fcdccc00590933ce482437342c35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/galen/PHP-Instagram-API/zipball/7a796fdae715fcdccc00590933ce482437342c35", - "reference": "7a796fdae715fcdccc00590933ce482437342c35", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Instagram": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Galen Grover", - "email": "galenjr@gmail.com", - "homepage": "http://www.galengrover.com", - "role": "Developer" - } - ], - "description": "PHP Instagram API for PHP 5.3+", - "homepage": "https://github.com/galen/PHP-Instagram-API", - "keywords": [ - "instagram" - ], - "time": "2013-11-13T23:10:03+00:00" - }, { "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", + "version": "2.0.5", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", "shasum": "" }, "require": { @@ -7221,7 +7197,7 @@ "email": "mike.vanriel@naenius.com" } ], - "time": "2015-02-03T12:10:50+00:00" + "time": "2016-01-25T08:17:30+00:00" }, { "name": "psr/http-message", @@ -7322,16 +7298,16 @@ }, { "name": "psy/psysh", - "version": "v0.8.3", + "version": "v0.8.7", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "1dd4bbbc64d71e7ec075ffe82b42d9e096dc8d5e" + "reference": "be969b9dc89dcaefdb9a3117fa91fa38bca19f50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/1dd4bbbc64d71e7ec075ffe82b42d9e096dc8d5e", - "reference": "1dd4bbbc64d71e7ec075ffe82b42d9e096dc8d5e", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/be969b9dc89dcaefdb9a3117fa91fa38bca19f50", + "reference": "be969b9dc89dcaefdb9a3117fa91fa38bca19f50", "shasum": "" }, "require": { @@ -7361,7 +7337,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-develop": "0.9.x-dev" + "dev-develop": "0.8.x-dev" } }, "autoload": { @@ -7391,7 +7367,7 @@ "interactive", "shell" ], - "time": "2017-03-19T21:40:44+00:00" + "time": "2017-06-20T12:51:31+00:00" }, { "name": "stack/builder", @@ -7537,16 +7513,16 @@ }, { "name": "symfony-cmf/routing", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", - "url": "https://github.com/symfony-cmf/Routing.git", - "reference": "b93704ca098334f56e9b317932f21a4362e620db" + "url": "https://github.com/symfony-cmf/routing.git", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/b93704ca098334f56e9b317932f21a4362e620db", - "reference": "b93704ca098334f56e9b317932f21a4362e620db", + "url": "https://api.github.com/repos/symfony-cmf/routing/zipball/fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", "shasum": "" }, "require": { @@ -7592,20 +7568,20 @@ "database", "routing" ], - "time": "2016-03-31T09:11:39+00:00" + "time": "2017-05-09T08:10:41+00:00" }, { "name": "symfony/class-loader", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", - "reference": "2c8de07a8a4cc4da9c018ab7a81888b80e762f93" + "reference": "48b96f2fa9bf394cb428aced8efb28709ab54cfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/2c8de07a8a4cc4da9c018ab7a81888b80e762f93", - "reference": "2c8de07a8a4cc4da9c018ab7a81888b80e762f93", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/48b96f2fa9bf394cb428aced8efb28709ab54cfc", + "reference": "48b96f2fa9bf394cb428aced8efb28709ab54cfc", "shasum": "" }, "require": { @@ -7645,20 +7621,20 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "time": "2017-02-18T19:13:35+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/config", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "35b7dfa089d7605eb1fdd46281b3070fb9f38750" + "reference": "0b8541d18507d10204a08384640ff6df3c739ebe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/35b7dfa089d7605eb1fdd46281b3070fb9f38750", - "reference": "35b7dfa089d7605eb1fdd46281b3070fb9f38750", + "url": "https://api.github.com/repos/symfony/config/zipball/0b8541d18507d10204a08384640ff6df3c739ebe", + "reference": "0b8541d18507d10204a08384640ff6df3c739ebe", "shasum": "" }, "require": { @@ -7701,20 +7677,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2017-04-04T15:24:26+00:00" + "time": "2017-04-12T14:07:15+00:00" }, { "name": "symfony/console", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "86407ff20855a5eaa2a7219bd815e9c40a88633e" + "reference": "3ef6ef64abecd566d551d9e7f6393ac6e93b2462" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/86407ff20855a5eaa2a7219bd815e9c40a88633e", - "reference": "86407ff20855a5eaa2a7219bd815e9c40a88633e", + "url": "https://api.github.com/repos/symfony/console/zipball/3ef6ef64abecd566d551d9e7f6393ac6e93b2462", + "reference": "3ef6ef64abecd566d551d9e7f6393ac6e93b2462", "shasum": "" }, "require": { @@ -7762,20 +7738,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-04-03T20:37:06+00:00" + "time": "2017-06-02T14:36:56+00:00" }, { "name": "symfony/css-selector", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "742bd688bd778dde8991ba696cb372570610afcd" + "reference": "ba3204654efa779691fac9e948a96b4a7067e4ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/742bd688bd778dde8991ba696cb372570610afcd", - "reference": "742bd688bd778dde8991ba696cb372570610afcd", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/ba3204654efa779691fac9e948a96b4a7067e4ab", + "reference": "ba3204654efa779691fac9e948a96b4a7067e4ab", "shasum": "" }, "require": { @@ -7815,20 +7791,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2017-02-21T08:33:48+00:00" + "time": "2017-05-01T14:31:55+00:00" }, { "name": "symfony/debug", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "e90099a2958d4833a02d05b504cc06e1c234abcc" + "reference": "8470d7701177a88edeb0cec59b44d50ef4477e9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/e90099a2958d4833a02d05b504cc06e1c234abcc", - "reference": "e90099a2958d4833a02d05b504cc06e1c234abcc", + "url": "https://api.github.com/repos/symfony/debug/zipball/8470d7701177a88edeb0cec59b44d50ef4477e9b", + "reference": "8470d7701177a88edeb0cec59b44d50ef4477e9b", "shasum": "" }, "require": { @@ -7872,20 +7848,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-02-18T19:13:35+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/dependency-injection", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "14b9d8ae69ac4c74e8f05fee7e0a57039b99c81e" + "reference": "b4a4b8f6ae1d69a6b2c0c31623bbc474121ee075" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/14b9d8ae69ac4c74e8f05fee7e0a57039b99c81e", - "reference": "14b9d8ae69ac4c74e8f05fee7e0a57039b99c81e", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b4a4b8f6ae1d69a6b2c0c31623bbc474121ee075", + "reference": "b4a4b8f6ae1d69a6b2c0c31623bbc474121ee075", "shasum": "" }, "require": { @@ -7935,20 +7911,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2017-04-03T22:14:48+00:00" + "time": "2017-06-02T14:36:56+00:00" }, { "name": "symfony/dom-crawler", - "version": "v3.2.7", + "version": "v3.2.9", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee" + "reference": "3d0e66d86f5eeaffa44edc884ce09322be8f4716" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/403944e294cf4ceb3b8447f54cbad88ea7b99cee", - "reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/3d0e66d86f5eeaffa44edc884ce09322be8f4716", + "reference": "3d0e66d86f5eeaffa44edc884ce09322be8f4716", "shasum": "" }, "require": { @@ -7991,20 +7967,20 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2017-02-21T09:12:04+00:00" + "time": "2017-05-25T22:59:05+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "88b65f0ac25355090e524aba4ceb066025df8bd2" + "reference": "1377400fd641d7d1935981546aaef780ecd5bf6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/88b65f0ac25355090e524aba4ceb066025df8bd2", - "reference": "88b65f0ac25355090e524aba4ceb066025df8bd2", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1377400fd641d7d1935981546aaef780ecd5bf6d", + "reference": "1377400fd641d7d1935981546aaef780ecd5bf6d", "shasum": "" }, "require": { @@ -8051,20 +8027,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-04-03T20:37:06+00:00" + "time": "2017-06-02T07:47:27+00:00" }, { "name": "symfony/expression-language", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "269a0a751f07a58b315f74899a253ead71747f06" + "reference": "2b8394d92f012fe3410e55e28c24fd90c9864a01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/269a0a751f07a58b315f74899a253ead71747f06", - "reference": "269a0a751f07a58b315f74899a253ead71747f06", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/2b8394d92f012fe3410e55e28c24fd90c9864a01", + "reference": "2b8394d92f012fe3410e55e28c24fd90c9864a01", "shasum": "" }, "require": { @@ -8100,20 +8076,20 @@ ], "description": "Symfony ExpressionLanguage Component", "homepage": "https://symfony.com", - "time": "2017-04-03T23:11:44+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/filesystem", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "31ab6827a696244094e6e20d77e7d404f8eb4252" + "reference": "19c11158da8d110cc5289c063bf2ec4cc1ce9e7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/31ab6827a696244094e6e20d77e7d404f8eb4252", - "reference": "31ab6827a696244094e6e20d77e7d404f8eb4252", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/19c11158da8d110cc5289c063bf2ec4cc1ce9e7c", + "reference": "19c11158da8d110cc5289c063bf2ec4cc1ce9e7c", "shasum": "" }, "require": { @@ -8149,20 +8125,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2017-03-26T15:40:40+00:00" + "time": "2017-05-28T14:07:33+00:00" }, { "name": "symfony/finder", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "7131327eb95d86d72039fd1216226c28f36fd02a" + "reference": "4f4e84811004e065a3bb5ceeb1d9aa592630f9ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/7131327eb95d86d72039fd1216226c28f36fd02a", - "reference": "7131327eb95d86d72039fd1216226c28f36fd02a", + "url": "https://api.github.com/repos/symfony/finder/zipball/4f4e84811004e065a3bb5ceeb1d9aa592630f9ad", + "reference": "4f4e84811004e065a3bb5ceeb1d9aa592630f9ad", "shasum": "" }, "require": { @@ -8198,20 +8174,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-03-20T08:46:40+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/http-foundation", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "0717efd2f2264dbd3d8e1bc69a0418c2fd6295d2" + "reference": "de8d8e83b9ec898e14ef8db84cee5919753b2ae5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/0717efd2f2264dbd3d8e1bc69a0418c2fd6295d2", - "reference": "0717efd2f2264dbd3d8e1bc69a0418c2fd6295d2", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/de8d8e83b9ec898e14ef8db84cee5919753b2ae5", + "reference": "de8d8e83b9ec898e14ef8db84cee5919753b2ae5", "shasum": "" }, "require": { @@ -8253,20 +8229,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2017-04-04T15:24:26+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/http-kernel", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "3256e9e554f02ba2dd49cff253f15df69c36cf40" + "reference": "03ca9421948142df8b9d3ffaeb3bfe8ddee02ca4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3256e9e554f02ba2dd49cff253f15df69c36cf40", - "reference": "3256e9e554f02ba2dd49cff253f15df69c36cf40", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/03ca9421948142df8b9d3ffaeb3bfe8ddee02ca4", + "reference": "03ca9421948142df8b9d3ffaeb3bfe8ddee02ca4", "shasum": "" }, "require": { @@ -8277,7 +8253,8 @@ "symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.7", + "twig/twig": "<1.34|<2.4,>=2" }, "require-dev": { "symfony/browser-kit": "~2.3|~3.0.0", @@ -8335,20 +8312,20 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2017-04-05T04:04:34+00:00" + "time": "2017-06-07T20:12:31+00:00" }, { "name": "symfony/polyfill-apcu", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-apcu.git", - "reference": "5d4474f447403c3348e37b70acc2b95475b7befa" + "reference": "2e7965b8cdfbba50d0092d3f6dca97dddec409e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/5d4474f447403c3348e37b70acc2b95475b7befa", - "reference": "5d4474f447403c3348e37b70acc2b95475b7befa", + "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/2e7965b8cdfbba50d0092d3f6dca97dddec409e2", + "reference": "2e7965b8cdfbba50d0092d3f6dca97dddec409e2", "shasum": "" }, "require": { @@ -8357,7 +8334,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -8388,20 +8365,20 @@ "portable", "shim" ], - "time": "2016-11-14T01:06:16+00:00" + "time": "2017-06-09T08:25:21+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "cba36f3616d9866b3e52662e88da5c090fac1e97" + "reference": "ae1347fa81423b67dbc232c8c111facb367ff8b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/cba36f3616d9866b3e52662e88da5c090fac1e97", - "reference": "cba36f3616d9866b3e52662e88da5c090fac1e97", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/ae1347fa81423b67dbc232c8c111facb367ff8b9", + "reference": "ae1347fa81423b67dbc232c8c111facb367ff8b9", "shasum": "" }, "require": { @@ -8413,7 +8390,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -8447,20 +8424,20 @@ "portable", "shim" ], - "time": "2016-11-14T01:06:16+00:00" + "time": "2017-06-09T08:25:21+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" + "reference": "f29dca382a6485c3cbe6379f0c61230167681937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f29dca382a6485c3cbe6379f0c61230167681937", + "reference": "f29dca382a6485c3cbe6379f0c61230167681937", "shasum": "" }, "require": { @@ -8472,7 +8449,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -8506,20 +8483,20 @@ "portable", "shim" ], - "time": "2016-11-14T01:06:16+00:00" + "time": "2017-06-09T14:24:12+00:00" }, { "name": "symfony/polyfill-php54", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0" + "reference": "7dd1a8b9f0442273fdfeb1c4f5eaff6890a82789" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0", - "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0", + "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/7dd1a8b9f0442273fdfeb1c4f5eaff6890a82789", + "reference": "7dd1a8b9f0442273fdfeb1c4f5eaff6890a82789", "shasum": "" }, "require": { @@ -8528,7 +8505,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -8564,20 +8541,20 @@ "portable", "shim" ], - "time": "2016-11-14T01:06:16+00:00" + "time": "2017-06-09T08:25:21+00:00" }, { "name": "symfony/polyfill-php55", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "03e3f0350bca2220e3623a0e340eef194405fc67" + "reference": "94566239a7720cde0820f15f0cc348ddb51ba51d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/03e3f0350bca2220e3623a0e340eef194405fc67", - "reference": "03e3f0350bca2220e3623a0e340eef194405fc67", + "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/94566239a7720cde0820f15f0cc348ddb51ba51d", + "reference": "94566239a7720cde0820f15f0cc348ddb51ba51d", "shasum": "" }, "require": { @@ -8587,7 +8564,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -8620,20 +8597,20 @@ "portable", "shim" ], - "time": "2016-11-14T01:06:16+00:00" + "time": "2017-06-09T08:25:21+00:00" }, { "name": "symfony/process", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "41336b20b52f5fd5b42a227e394e673c8071118f" + "reference": "d54232f5682fda2f8bbebff7c81b864646867ab9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/41336b20b52f5fd5b42a227e394e673c8071118f", - "reference": "41336b20b52f5fd5b42a227e394e673c8071118f", + "url": "https://api.github.com/repos/symfony/process/zipball/d54232f5682fda2f8bbebff7c81b864646867ab9", + "reference": "d54232f5682fda2f8bbebff7c81b864646867ab9", "shasum": "" }, "require": { @@ -8669,7 +8646,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-03-04T12:20:59+00:00" + "time": "2017-05-08T01:19:21+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -8733,16 +8710,16 @@ }, { "name": "symfony/routing", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "d145cd396f702c497cb24b21785ddac90a23fe71" + "reference": "d428588038f13a0e5771a2a8ccbc9de46bba9a19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/d145cd396f702c497cb24b21785ddac90a23fe71", - "reference": "d145cd396f702c497cb24b21785ddac90a23fe71", + "url": "https://api.github.com/repos/symfony/routing/zipball/d428588038f13a0e5771a2a8ccbc9de46bba9a19", + "reference": "d428588038f13a0e5771a2a8ccbc9de46bba9a19", "shasum": "" }, "require": { @@ -8804,20 +8781,20 @@ "uri", "url" ], - "time": "2017-03-02T15:56:34+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/serializer", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "d1c3d68daee29bbf0b4600745899a7000c215642" + "reference": "c6ccf71a899711efa21b0a98150b2c0af08f3cb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/d1c3d68daee29bbf0b4600745899a7000c215642", - "reference": "d1c3d68daee29bbf0b4600745899a7000c215642", + "url": "https://api.github.com/repos/symfony/serializer/zipball/c6ccf71a899711efa21b0a98150b2c0af08f3cb2", + "reference": "c6ccf71a899711efa21b0a98150b2c0af08f3cb2", "shasum": "" }, "require": { @@ -8868,20 +8845,20 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com", - "time": "2017-03-21T22:47:17+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/translation", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "047e97a64d609778cadfc76e3a09793696bb19f1" + "reference": "14db4cc1172a722aaa3b558bfa8eff593b43cd46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/047e97a64d609778cadfc76e3a09793696bb19f1", - "reference": "047e97a64d609778cadfc76e3a09793696bb19f1", + "url": "https://api.github.com/repos/symfony/translation/zipball/14db4cc1172a722aaa3b558bfa8eff593b43cd46", + "reference": "14db4cc1172a722aaa3b558bfa8eff593b43cd46", "shasum": "" }, "require": { @@ -8932,20 +8909,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2017-03-21T21:39:01+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/validator", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "43f617ee200af4f4dedbb0782c6c689e06994286" + "reference": "9f323f762ad21bfb9df7c1afacbdd8addf0f8c50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/43f617ee200af4f4dedbb0782c6c689e06994286", - "reference": "43f617ee200af4f4dedbb0782c6c689e06994286", + "url": "https://api.github.com/repos/symfony/validator/zipball/9f323f762ad21bfb9df7c1afacbdd8addf0f8c50", + "reference": "9f323f762ad21bfb9df7c1afacbdd8addf0f8c50", "shasum": "" }, "require": { @@ -9005,20 +8982,20 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com", - "time": "2017-03-23T16:08:03+00:00" + "time": "2017-06-02T14:36:56+00:00" }, { "name": "symfony/var-dumper", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "f8ff23ad5352f96e66c1df5468d492d2f37f3ac4" + "reference": "8108f6200e8a1cf999df2691431a2d71e6db1152" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f8ff23ad5352f96e66c1df5468d492d2f37f3ac4", - "reference": "f8ff23ad5352f96e66c1df5468d492d2f37f3ac4", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/8108f6200e8a1cf999df2691431a2d71e6db1152", + "reference": "8108f6200e8a1cf999df2691431a2d71e6db1152", "shasum": "" }, "require": { @@ -9029,9 +9006,11 @@ "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, "require-dev": { - "twig/twig": "~1.20|~2.0" + "ext-iconv": "*", + "twig/twig": "~1.34|~2.4" }, "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", "ext-symfony_debug": "" }, "type": "library", @@ -9071,20 +9050,20 @@ "debug", "dump" ], - "time": "2017-03-12T16:01:59+00:00" + "time": "2017-06-02T08:28:06+00:00" }, { "name": "symfony/yaml", - "version": "v2.8.19", + "version": "v2.8.22", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "286d84891690b0e2515874717e49360d1c98a703" + "reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/286d84891690b0e2515874717e49360d1c98a703", - "reference": "286d84891690b0e2515874717e49360d1c98a703", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5", + "reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5", "shasum": "" }, "require": { @@ -9120,7 +9099,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-03-20T09:41:44+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "twbs/bootstrap-sass", @@ -9177,20 +9156,20 @@ }, { "name": "twig/twig", - "version": "v1.33.0", + "version": "v1.34.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a" + "reference": "451c6f4197e113e24c1c85bc3fc8c2d77adeff2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a", - "reference": "05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/451c6f4197e113e24c1c85bc3fc8c2d77adeff2e", + "reference": "451c6f4197e113e24c1c85bc3fc8c2d77adeff2e", "shasum": "" }, "require": { - "php": ">=5.2.7" + "php": ">=5.3.3" }, "require-dev": { "psr/container": "^1.0", @@ -9200,12 +9179,15 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.33-dev" + "dev-master": "1.34-dev" } }, "autoload": { "psr-0": { "Twig_": "lib/" + }, + "psr-4": { + "Twig\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -9235,20 +9217,20 @@ "keywords": [ "templating" ], - "time": "2017-03-22T15:40:09+00:00" + "time": "2017-06-07T18:45:17+00:00" }, { "name": "webflo/drupal-finder", - "version": "0.2.1", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/webflo/drupal-finder.git", - "reference": "4bd98f7e7b1d30e284e55f51d5d0c8712f676348" + "reference": "6ef150707aad1755d91f9b0d2108bcc16661e76b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/4bd98f7e7b1d30e284e55f51d5d0c8712f676348", - "reference": "4bd98f7e7b1d30e284e55f51d5d0c8712f676348", + "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/6ef150707aad1755d91f9b0d2108bcc16661e76b", + "reference": "6ef150707aad1755d91f9b0d2108bcc16661e76b", "shasum": "" }, "require-dev": { @@ -9272,7 +9254,7 @@ } ], "description": "Helper class to locate a Drupal installation from a given path.", - "time": "2016-11-28T18:50:45+00:00" + "time": "2017-05-04T08:54:02+00:00" }, { "name": "webmozart/assert", @@ -9856,73 +9838,6 @@ ], "time": "2015-06-14T21:17:01+00:00" }, - { - "name": "drupal/draggableviews", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://git.drupal.org/project/draggableviews", - "reference": "8.x-1.0" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/draggableviews-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "007082c2621b45bd8cf73fe5fdd4d292ee88a458" - }, - "require": { - "drupal/core": "*" - }, - "type": "drupal-module", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0", - "datestamp": "1477076039" - }, - "patches_applied": { - "Sort order not saved when using bootstrap theme": "https://www.drupal.org/files/issues/classes-defined-in-array-2729935-2.patch", - "DraggableViews displays multiple node instances when used in multiple views": "https://www.drupal.org/files/issues/2867159_fixed_problems_with_duplicates_0.patch" - } - }, - "notification-url": "https://packages.drupal.org/8/downloads", - "license": [ - "GPL-2.0+" - ], - "authors": [ - { - "name": "dixon_", - "homepage": "https://www.drupal.org/user/239911" - }, - { - "name": "ginc", - "homepage": "https://www.drupal.org/user/332249" - }, - { - "name": "iStryker", - "homepage": "https://www.drupal.org/user/303676" - }, - { - "name": "podarok", - "homepage": "https://www.drupal.org/user/116002" - }, - { - "name": "sevi", - "homepage": "https://www.drupal.org/user/199290" - }, - { - "name": "ygerasimov", - "homepage": "https://www.drupal.org/user/257311" - } - ], - "description": "Complete rewrite of D7 draggableviews", - "homepage": "https://www.drupal.org/project/draggableviews", - "support": { - "source": "http://cgit.drupalcode.org/draggableviews" - } - }, { "name": "drupal/twig_xdebug", "version": "1.0.0", @@ -10490,16 +10405,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.8.35", + "version": "4.8.36", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87" + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/791b1a67c25af50e230f841ee7a9c6eba507dc87", - "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", "shasum": "" }, "require": { @@ -10558,7 +10473,7 @@ "testing", "xunit" ], - "time": "2017-02-06T05:18:07+00:00" + "time": "2017-06-21T08:07:12+00:00" }, { "name": "phpunit/phpunit-mock-objects", @@ -10682,23 +10597,23 @@ }, { "name": "sebastian/diff", - "version": "1.4.1", + "version": "1.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", "extra": { @@ -10730,7 +10645,7 @@ "keywords": [ "diff" ], - "time": "2015-12-08T07:14:41+00:00" + "time": "2017-05-22T07:24:03+00:00" }, { "name": "sebastian/environment", @@ -10990,16 +10905,16 @@ }, { "name": "symfony/browser-kit", - "version": "v3.2.7", + "version": "v3.3.2", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "2fe0caa60c1a1dfeefd0425741182687a9b382b8" + "reference": "c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/2fe0caa60c1a1dfeefd0425741182687a9b382b8", - "reference": "2fe0caa60c1a1dfeefd0425741182687a9b382b8", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1", + "reference": "c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1", "shasum": "" }, "require": { @@ -11016,7 +10931,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "3.3-dev" } }, "autoload": { @@ -11043,7 +10958,7 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2017-02-21T09:12:04+00:00" + "time": "2017-04-12T14:14:56+00:00" } ], "aliases": [], diff --git a/console/cache/701af009-9170-41a7-a4a2-034d6ca6acce/console.services.yml b/console/cache/701af009-9170-41a7-a4a2-034d6ca6acce/console.services.yml deleted file mode 100644 index ec2cf54dc..000000000 --- a/console/cache/701af009-9170-41a7-a4a2-034d6ca6acce/console.services.yml +++ /dev/null @@ -1,1390 +0,0 @@ -services: - console.cache_context_debug: - class: Drupal\Console\Command\Cache\ContextDebugCommand - tags: - - { name: drupal.command } - console.cache_rebuild: - class: Drupal\Console\Command\Cache\RebuildCommand - arguments: - - '@console.drupal_api' - - '@console.site' - - '@class_loader' - - '@request_stack' - tags: - - { name: drupal.command } - console.entity_debug: - class: Drupal\Console\Command\Entity\DebugCommand - arguments: - - '@entity_type.repository' - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.entity_delete: - class: Drupal\Console\Command\Entity\DeleteCommand - arguments: - - '@entity_type.repository' - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.field_info: - class: Drupal\Console\Command\Field\InfoCommand - arguments: - - '@entity_type.manager' - - '@entity_field.manager' - tags: - - { name: drupal.command } - console.create_nodes: - class: Drupal\Console\Command\Create\NodesCommand - arguments: - - '@console.drupal_api' - - '@console.create_node_data' - tags: - - { name: drupal.command } - console.create_comments: - class: Drupal\Console\Command\Create\CommentsCommand - arguments: - - '@console.create_comment_data' - tags: - - { name: drupal.command } - console.create_terms: - class: Drupal\Console\Command\Create\TermsCommand - arguments: - - '@console.drupal_api' - - '@console.create_term_data' - tags: - - { name: drupal.command } - console.create_users: - class: Drupal\Console\Command\Create\UsersCommand - arguments: - - '@console.drupal_api' - - '@console.create_user_data' - tags: - - { name: drupal.command } - console.create_vocabularies: - class: Drupal\Console\Command\Create\VocabulariesCommand - arguments: - - '@console.create_vocabulary_data' - tags: - - { name: drupal.command } - theme_debug: - class: Drupal\Console\Command\Theme\DebugCommand - arguments: - - '@config.factory' - - '@theme_handler' - tags: - - { name: drupal.command } - theme_download: - class: Drupal\Console\Command\Theme\DownloadCommand - arguments: - - '@console.drupal_api' - - '@http_client' - - '@app.root' - tags: - - { name: drupal.command } - theme_install: - class: Drupal\Console\Command\Theme\InstallCommand - arguments: - - '@config.factory' - - '@theme_handler' - - '@console.chain_queue' - tags: - - { name: drupal.command } - theme_path: - class: Drupal\Console\Command\Theme\PathCommand - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.command } - theme_uninstall: - class: Drupal\Console\Command\Theme\UninstallCommand - arguments: - - '@config.factory' - - '@theme_handler' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.state_debug: - class: Drupal\Console\Command\State\DebugCommand - arguments: - - '@state' - - '@keyvalue' - tags: - - { name: drupal.command } - console.state_delete: - class: Drupal\Console\Command\State\DeleteCommand - arguments: - - '@state' - - '@keyvalue' - tags: - - { name: drupal.command } - console.state_override: - class: Drupal\Console\Command\State\OverrideCommand - arguments: - - '@state' - - '@keyvalue' - tags: - - { name: drupal.command } - console.image_styles_debug: - class: Drupal\Console\Command\Image\StylesDebugCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.image_styles_flush: - class: Drupal\Console\Command\Image\StylesFlushCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.site_import_local: - class: Drupal\Console\Command\Site\ImportLocalCommand - arguments: - - '@app.root' - - '@console.configuration_manager' - tags: - - { name: drupal.command } - console.site_maintenance: - class: Drupal\Console\Command\Site\MaintenanceCommand - arguments: - - '@state' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.site_statistics: - class: Drupal\Console\Command\Site\StatisticsCommand - arguments: - - '@console.drupal_api' - - '@entity.query' - - '@console.extension_manager' - - '@module_handler' - tags: - - { name: drupal.command } - console.site_status: - class: Drupal\Console\Command\Site\StatusCommand - arguments: - - '@system.manager' - - '@settings' - - '@config.factory' - - '@theme_handler' - - '@app.root' - tags: - - { name: drupal.command } - console.config_debug: - class: Drupal\Console\Command\Config\DebugCommand - arguments: - - '@config.factory' - - '@config.storage' - tags: - - { name: drupal.command } - console.config_delete: - class: Drupal\Console\Command\Config\DeleteCommand - arguments: - - '@config.factory' - - '@config.storage' - - '@config.storage.sync' - tags: - - { name: drupal.command } - console.config_diff: - class: Drupal\Console\Command\Config\DiffCommand - arguments: - - '@config.storage' - - '@config.manager' - tags: - - { name: drupal.command } - console.config_edit: - class: Drupal\Console\Command\Config\EditCommand - arguments: - - '@config.factory' - - '@config.storage' - - '@console.configuration_manager' - tags: - - { name: drupal.command } - console.config_export: - class: Drupal\Console\Command\Config\ExportCommand - arguments: - - '@config.manager' - tags: - - { name: drupal.command } - console.config_export_content_type: - class: Drupal\Console\Command\Config\ExportContentTypeCommand - arguments: - - '@entity_type.manager' - - '@config.storage' - - '@console.extension_manager' - tags: - - { name: drupal.command } - console.config_export_single: - class: Drupal\Console\Command\Config\ExportSingleCommand - arguments: - - '@entity_type.manager' - - '@config.storage' - tags: - - { name: drupal.command } - console.config_export_view: - class: Drupal\Console\Command\Config\ExportViewCommand - arguments: - - '@entity_type.manager' - - '@config.storage' - - '@console.extension_manager' - tags: - - { name: drupal.command } - console.config_import: - class: Drupal\Console\Command\Config\ImportCommand - arguments: - - '@config.storage' - - '@config.manager' - tags: - - { name: drupal.command } - console.config_import_single: - class: Drupal\Console\Command\Config\ImportSingleCommand - arguments: - - '@config.storage' - - '@config.manager' - tags: - - { name: drupal.command } - console.config_override: - class: Drupal\Console\Command\Config\OverrideCommand - arguments: - - '@config.storage' - - '@config.factory' - tags: - - { name: drupal.command } - console.config_settings_debug: - class: Drupal\Console\Command\Config\SettingsDebugCommand - arguments: - - '@settings' - tags: - - { name: drupal.command } - console.config_validate: - class: Drupal\Console\Command\Config\ValidateCommand - tags: - - { name: drupal.command } - console.config_validate_debug: - class: Drupal\Console\Command\Config\ValidateDebugCommand - tags: - - { name: drupal.command } - console.queue_debug: - class: Drupal\Console\Command\Queue\DebugCommand - arguments: - - '@plugin.manager.queue_worker' - tags: - - { name: drupal.command } - console.queue_run: - class: Drupal\Console\Command\Queue\RunCommand - arguments: - - '@plugin.manager.queue_worker' - - '@queue' - tags: - - { name: drupal.command } - console.generate_module: - class: Drupal\Console\Command\Generate\ModuleCommand - arguments: - - '@console.module_generator' - - '@console.validator' - - '@app.root' - - '@console.string_converter' - - '@console.drupal_api' - - '@http_client' - - '@console.site' - tags: - - { name: drupal.command } - console.generate_modulefile: - class: Drupal\Console\Command\Generate\ModuleFileCommand - arguments: - - '@console.extension_manager' - - '@console.modulefile_generator' - tags: - - { name: drupal.command } - console.generate_authentication_provider: - class: Drupal\Console\Command\Generate\AuthenticationProviderCommand - arguments: - - '@console.extension_manager' - - '@console.authentication_provider_generator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_controller: - class: Drupal\Console\Command\Generate\ControllerCommand - arguments: - - '@console.extension_manager' - - '@console.controller_generator' - - '@console.string_converter' - - '@console.validator' - - '@router.route_provider' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_breakpoint: - class: Drupal\Console\Command\Generate\BreakPointCommand - arguments: - - '@console.breakpoint_generator' - - '@app.root' - - '@theme_handler' - - '@console.validator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_help: - class: Drupal\Console\Command\Generate\HelpCommand - arguments: - - '@console.help_generator' - - '@console.site' - - '@console.extension_manager' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_form: - class: Drupal\Console\Command\Generate\FormBaseCommand - arguments: - - '@console.extension_manager' - - '@console.form_generator' - - '@console.chain_queue' - - '@console.string_converter' - - '@plugin.manager.element_info' - - '@router.route_provider' - tags: - - { name: drupal.command } - console.generate_form_alter: - class: Drupal\Console\Command\Generate\FormAlterCommand - arguments: - - '@console.extension_manager' - - '@console.form_alter_generator' - - '@console.string_converter' - - '@module_handler' - - '@plugin.manager.element_info' - - '@?profiler' - - '@app.root' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_permissions: - class: Drupal\Console\Command\Generate\PermissionCommand - arguments: - - '@console.extension_manager' - - '@console.string_converter' - - '@console.permission_generator' - tags: - - { name: drupal.command } - console.generate_event_subscriber: - class: Drupal\Console\Command\Generate\EventSubscriberCommand - arguments: - - '@console.extension_manager' - - '@console.event_subscriber_generator' - - '@console.string_converter' - - '@event_dispatcher' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_form_config: - class: Drupal\Console\Command\Generate\ConfigFormBaseCommand - arguments: - - '@console.extension_manager' - - '@console.form_generator' - - '@console.string_converter' - - '@router.route_provider' - - '@plugin.manager.element_info' - - '@app.root' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_type_annotation: - class: Drupal\Console\Command\Generate\PluginTypeAnnotationCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_type_annotation_generator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_plugin_condition: - class: Drupal\Console\Command\Generate\PluginConditionCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_condition_generator' - - '@console.chain_queue' - - '@entity_type.repository' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_plugin_field: - class: Drupal\Console\Command\Generate\PluginFieldCommand - arguments: - - '@console.extension_manager' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_field_formatter: - class: Drupal\Console\Command\Generate\PluginFieldFormatterCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_field_formatter_generator' - - '@console.string_converter' - - '@plugin.manager.field.field_type' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_field_type: - class: Drupal\Console\Command\Generate\PluginFieldTypeCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_field_type_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_field_widget: - class: Drupal\Console\Command\Generate\PluginFieldWidgetCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_field_widget_generator' - - '@console.string_converter' - - '@plugin.manager.field.field_type' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_image_effect: - class: Drupal\Console\Command\Generate\PluginImageEffectCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_image_effect_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_image_formatter: - class: Drupal\Console\Command\Generate\PluginImageFormatterCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_image_formatter_generator' - - '@console.string_converter' - - '@console.validator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_mail: - class: Drupal\Console\Command\Generate\PluginMailCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_mail_generator' - - '@console.string_converter' - - '@console.validator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_migrate_source: - class: Drupal\Console\Command\Generate\PluginMigrateSourceCommand - arguments: - - '@config.factory' - - '@console.chain_queue' - - '@console.plugin_migrate_source_generator' - - '@entity_type.manager' - - '@console.extension_manager' - - '@console.validator' - - '@console.string_converter' - - '@plugin.manager.element_info' - tags: - - { name: drupal.command } - console.generate_plugin_migrate_process: - class: Drupal\Console\Command\Generate\PluginMigrateProcessCommand - arguments: - - '@console.plugin_migrate_process_generator' - - '@console.chain_queue' - - '@console.extension_manager' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_plugin_rest_resource: - class: Drupal\Console\Command\Generate\PluginRestResourceCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_rest_resource_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_rules_action: - class: Drupal\Console\Command\Generate\PluginRulesActionCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_rules_action_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_skeleton: - class: Drupal\Console\Command\Generate\PluginSkeletonCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_skeleton_generator' - - '@console.string_converter' - - '@console.validator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_type_yaml: - class: Drupal\Console\Command\Generate\PluginTypeYamlCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_type_yaml_generator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_plugin_views_field: - class: Drupal\Console\Command\Generate\PluginViewsFieldCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_views_field_generator' - - '@console.site' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_post_update: - class: Drupal\Console\Command\Generate\PostUpdateCommand - arguments: - - '@console.extension_manager' - - '@console.post_update_generator' - - '@console.site' - - '@console.validator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_profile: - class: Drupal\Console\Command\Generate\ProfileCommand - arguments: - - '@console.extension_manager' - - '@console.profile_generator' - - '@console.string_converter' - - '@console.validator' - - '@app.root' - - '@console.site' - - '@http_client' - tags: - - { name: drupal.command } - console.generate_route_subscriber: - class: Drupal\Console\Command\Generate\RouteSubscriberCommand - arguments: - - '@console.extension_manager' - - '@console.route_subscriber_generator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_service: - class: Drupal\Console\Command\Generate\ServiceCommand - arguments: - - '@console.extension_manager' - - '@console.service_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_theme: - class: Drupal\Console\Command\Generate\ThemeCommand - arguments: - - '@console.extension_manager' - - '@console.theme_generator' - - '@console.validator' - - '@app.root' - - '@theme_handler' - - '@console.site' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_twig_extension: - class: Drupal\Console\Command\Generate\TwigExtensionCommand - arguments: - - '@console.extension_manager' - - '@console.twig_extension_generator' - - '@console.site' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_update: - class: Drupal\Console\Command\Generate\UpdateCommand - arguments: - - '@console.extension_manager' - - '@console.update_generator' - - '@console.site' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_pluginblock: - class: Drupal\Console\Command\Generate\PluginBlockCommand - arguments: - - '@config.factory' - - '@console.chain_queue' - - '@console.pluginblock_generator' - - '@entity_type.manager' - - '@console.extension_manager' - - '@console.validator' - - '@console.string_converter' - - '@plugin.manager.element_info' - tags: - - { name: drupal.command } - console.generate_command: - class: Drupal\Console\Command\Generate\CommandCommand - arguments: - - '@console.command_generator' - - '@console.extension_manager' - - '@console.validator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_ckeditorbutton: - class: Drupal\Console\Command\Generate\PluginCKEditorButtonCommand - arguments: - - '@console.chain_queue' - - '@console.command_ckeditorbutton' - - '@console.extension_manager' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_entitycontent: - class: Drupal\Console\Command\Generate\EntityContentCommand - arguments: - - '@console.chain_queue' - - '@console.entitycontent_generator' - - '@console.string_converter' - - '@console.extension_manager' - - '@console.validator' - tags: - - { name: drupal.command } - console.generate_entitybundle: - class: Drupal\Console\Command\Generate\EntityBundleCommand - arguments: - - '@console.validator' - - '@console.entitybundle_generator' - - '@console.extension_manager' - tags: - - { name: drupal.command } - console.generate_entityconfig: - class: Drupal\Console\Command\Generate\EntityConfigCommand - arguments: - - '@console.extension_manager' - - '@console.entityconfig_generator' - - '@console.validator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_cache_context: - class: Drupal\Console\Command\Generate\CacheContextCommand - arguments: - - '@console.cache_context_generator' - - '@console.chain_queue' - - '@console.extension_manager' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.update_debug: - class: Drupal\Console\Command\Update\DebugCommand - arguments: - - '@console.site' - - '@update.post_update_registry' - tags: - - { name: drupal.command } - console.update_entities: - class: Drupal\Console\Command\Update\EntitiesCommand - arguments: - - '@state' - - '@entity.definition_update_manager' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.update_execute: - class: Drupal\Console\Command\Update\ExecuteCommand - arguments: - - '@console.site' - - '@state' - - '@module_handler' - - '@update.post_update_registry' - - '@console.extension_manager' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.libraries_debug: - class: Drupal\Console\Command\Libraries\DebugCommand - arguments: - - '@module_handler' - - '@theme_handler' - - '@library.discovery' - - '@app.root' - tags: - - { name: drupal.command } - console.taxonomy_delete: - class: Drupal\Console\Command\Taxonomy\DeleteTermCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.views_disable: - class: Drupal\Console\Command\Views\DisableCommand - arguments: - - '@entity_type.manager' - - '@entity.query' - tags: - - { name: drupal.command } - console.views_enable: - class: Drupal\Console\Command\Views\EnableCommand - arguments: - - '@entity_type.manager' - - '@entity.query' - tags: - - { name: drupal.command } - console.views_debug: - class: Drupal\Console\Command\Views\DebugCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.views_plugins_debug: - class: Drupal\Console\Command\Views\PluginsDebugCommand - tags: - - { name: drupal.command } - console.cron_debug: - class: Drupal\Console\Command\Cron\DebugCommand - arguments: - - '@module_handler' - tags: - - { name: drupal.command } - console.cron_execute: - class: Drupal\Console\Command\Cron\ExecuteCommand - arguments: - - '@module_handler' - - '@lock' - - '@state' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.cron_release: - class: Drupal\Console\Command\Cron\ReleaseCommand - arguments: - - '@lock' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_doc_cheatsheet: - class: Drupal\Console\Command\Develop\GenerateDocCheatsheetCommand - tags: - - { name: drupal.command } - console.generate_doc_dash: - class: Drupal\Console\Command\Develop\GenerateDocDashCommand - arguments: - - '@console.renderer' - - '@console.root' - tags: - - { name: drupal.command } - console.generate_doc_data: - class: Drupal\Console\Command\Develop\GenerateDocDataCommand - tags: - - { name: drupal.command } - console.generate_doc_gitbook: - class: Drupal\Console\Command\Develop\GenerateDocGitbookCommand - arguments: - - '@console.renderer' - tags: - - { name: drupal.command } - console.translation_cleanup: - class: Drupal\Console\Command\Develop\TranslationCleanupCommand - arguments: - - '@console.root' - - '@console.configuration_manager' - tags: - - { name: drupal.command } - console.translation_pending: - class: Drupal\Console\Command\Develop\TranslationPendingCommand - arguments: - - '@console.root' - - '@console.configuration_manager' - - '@console.nested_array' - tags: - - { name: drupal.command } - console.translation_stats: - class: Drupal\Console\Command\Develop\TranslationStatsCommand - arguments: - - '@console.root' - - '@console.configuration_manager' - - '@console.renderer' - - '@console.nested_array' - tags: - - { name: drupal.command } - console.translation_sync: - class: Drupal\Console\Command\Develop\TranslationSyncCommand - arguments: - - '@console.root' - - '@console.configuration_manager' - tags: - - { name: drupal.command } - console.user_debug: - class: Drupal\Console\Command\User\DebugCommand - arguments: - - '@entity_type.manager' - - '@entity.query' - - '@console.drupal_api' - tags: - - { name: drupal.command } - console.user_delete: - class: Drupal\Console\Command\User\DeleteCommand - arguments: - - '@entity_type.manager' - - '@entity.query' - - '@console.drupal_api' - tags: - - { name: drupal.command } - console.user_login_clear_attempts: - class: Drupal\Console\Command\User\LoginCleanAttemptsCommand - arguments: - - '@database' - tags: - - { name: drupal.command } - console.user_login_url: - class: Drupal\Console\Command\User\LoginUrlCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.user_password_hash: - class: Drupal\Console\Command\User\PasswordHashCommand - arguments: - - '@password' - tags: - - { name: drupal.command } - console.user_password_reset: - class: Drupal\Console\Command\User\PasswordResetCommand - arguments: - - '@database' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.user_role: - class: Drupal\Console\Command\User\RoleCommand - arguments: - - '@console.drupal_api' - tags: - - { name: drupal.command } - console.user_create: - class: Drupal\Console\Command\User\CreateCommand - arguments: - - '@database' - - '@entity_type.manager' - - '@date.formatter' - - '@console.drupal_api' - tags: - - { name: drupal.command } - translation_status: - class: Drupal\Console\Command\Locale\TranslationStatusCommand - arguments: - - '@console.site' - - '@console.extension_manager' - tags: - - { name: drupal.command } - language_delete: - class: Drupal\Console\Command\Locale\LanguageDeleteCommand - arguments: - - '@console.site' - - '@entity_type.manager' - - '@module_handler' - tags: - - { name: drupal.command } - language_add: - class: Drupal\Console\Command\Locale\LanguageAddCommand - arguments: - - '@console.site' - - '@module_handler' - tags: - - { name: drupal.command } - console.node_access_rebuild: - class: Drupal\Console\Command\Node\AccessRebuildCommand - arguments: - - '@state' - tags: - - { name: drupal.command } - router_debug: - class: Drupal\Console\Command\Router\DebugCommand - arguments: - - '@router.route_provider' - tags: - - { name: drupal.command } - console.router_rebuild: - class: Drupal\Console\Command\Router\RebuildCommand - arguments: - - '@router.builder' - tags: - - { name: drupal.command } - feature_debug: - class: Drupal\Console\Command\Features\DebugCommand - tags: - - { name: drupal.command } - feature_import: - class: Drupal\Console\Command\Features\ImportCommand - tags: - - { name: drupal.command } - module_debug: - class: Drupal\Console\Command\Module\DebugCommand - arguments: - - '@console.configuration_manager' - - '@console.site' - - '@http_client' - tags: - - { name: drupal.command } - module_dependency_install: - class: Drupal\Console\Command\Module\InstallDependencyCommand - arguments: - - '@console.site' - - '@console.validator' - - '@module_installer' - - '@console.chain_queue' - tags: - - { name: drupal.command } - module_download: - class: Drupal\Console\Command\Module\DownloadCommand - arguments: - - '@console.drupal_api' - - '@http_client' - - '@app.root' - - '@console.extension_manager' - - '@console.validator' - - '@console.site' - - '@console.configuration_manager' - - '@console.shell_process' - - '@console.root' - tags: - - { name: drupal.command } - module_install: - class: Drupal\Console\Command\Module\InstallCommand - arguments: - - '@console.site' - - '@console.validator' - - '@module_installer' - - '@console.drupal_api' - - '@console.extension_manager' - - '@app.root' - - '@console.chain_queue' - tags: - - { name: drupal.command } - module_path: - class: Drupal\Console\Command\Module\PathCommand - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.command } - module_uninstall: - class: Drupal\Console\Command\Module\UninstallCommand - arguments: - - '@console.site' - - '@module_installer' - - '@console.chain_queue' - - '@config.factory' - tags: - - { name: drupal.command } - module_update: - class: Drupal\Console\Command\Module\UpdateCommand - arguments: - - '@console.shell_process' - - '@console.root' - tags: - - { name: drupal.command } - console.container_debug: - class: Drupal\Console\Command\ContainerDebugCommand - tags: - - { name: drupal.command } - console.plugin_debug: - class: Drupal\Console\Command\PluginDebugCommand - tags: - - { name: drupal.command } - console.permission_debug: - class: Drupal\Console\Command\PermissionDebugCommand - tags: - - { name: drupal.command } - console.event_debug: - class: Drupal\Console\Command\EventDebugCommand - arguments: - - '@event_dispatcher' - tags: - - { name: drupal.command } - console.devel_dumper: - class: Drupal\Console\Command\DevelDumperCommand - arguments: - - '@?plugin.manager.devel_dumper' - tags: - - { name: drupal.command } - console.shell: - class: Drupal\Console\Command\ShellCommand - tags: - - { name: drupal.command } - console.module_generator: - class: Drupal\Console\Generator\ModuleGenerator - tags: - - { name: drupal.generator } - console.modulefile_generator: - class: Drupal\Console\Generator\ModuleFileGenerator - tags: - - { name: drupal.generator } - console.authentication_provider_generator: - class: Drupal\Console\Generator\AuthenticationProviderGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.help_generator: - class: Drupal\Console\Generator\HelpGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.controller_generator: - class: Drupal\Console\Generator\ControllerGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.breakpoint_generator: - class: Drupal\Console\Generator\BreakPointGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.form_alter_generator: - class: Drupal\Console\Generator\FormAlterGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.permission_generator: - class: Drupal\Console\Generator\PermissionGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.event_subscriber_generator: - class: Drupal\Console\Generator\EventSubscriberGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.form_generator: - class: Drupal\Console\Generator\FormGenerator - arguments: - - '@console.extension_manager' - - '@console.string_converter' - tags: - - { name: drupal.generator } - console.profile_generator: - class: Drupal\Console\Generator\ProfileGenerator - tags: - - { name: drupal.generator } - console.post_update_generator: - class: Drupal\Console\Generator\PostUpdateGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_condition_generator: - class: Drupal\Console\Generator\PluginConditionGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_field_generator: - class: Drupal\Console\Generator\PluginFieldFormatterGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_field_formatter_generator: - class: Drupal\Console\Generator\PluginFieldFormatterGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_field_type_generator: - class: Drupal\Console\Generator\PluginFieldTypeGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_field_widget_generator: - class: Drupal\Console\Generator\PluginFieldWidgetGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_image_effect_generator: - class: Drupal\Console\Generator\PluginImageEffectGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_image_formatter_generator: - class: Drupal\Console\Generator\PluginImageFormatterGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_mail_generator: - class: Drupal\Console\Generator\PluginMailGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_migrate_source_generator: - class: Drupal\Console\Generator\PluginMigrateSourceGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_migrate_process_generator: - class: Drupal\Console\Generator\PluginMigrateProcessGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_rest_resource_generator: - class: Drupal\Console\Generator\PluginRestResourceGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_rules_action_generator: - class: Drupal\Console\Generator\PluginRulesActionGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_skeleton_generator: - class: Drupal\Console\Generator\PluginSkeletonGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_views_field_generator: - class: Drupal\Console\Generator\PluginViewsFieldGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_type_annotation_generator: - class: Drupal\Console\Generator\PluginTypeAnnotationGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_type_yaml_generator: - class: Drupal\Console\Generator\PluginTypeYamlGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.route_subscriber_generator: - class: Drupal\Console\Generator\RouteSubscriberGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.service_generator: - class: Drupal\Console\Generator\ServiceGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.theme_generator: - class: Drupal\Console\Generator\ThemeGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.twig_extension_generator: - class: Drupal\Console\Generator\TwigExtensionGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.update_generator: - class: Drupal\Console\Generator\UpdateGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.pluginblock_generator: - class: Drupal\Console\Generator\PluginBlockGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.command_generator: - class: Drupal\Console\Generator\CommandGenerator - arguments: - - '@console.extension_manager' - - '@console.translator_manager' - tags: - - { name: drupal.generator } - console.command_ckeditorbutton: - class: Drupal\Console\Generator\PluginCKEditorButtonGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.database_settings_generator: - class: Drupal\Console\Generator\DatabaseSettingsGenerator - arguments: - - '@kernel' - tags: - - { name: drupal.generator } - console.entitycontent_generator: - class: Drupal\Console\Generator\EntityContentGenerator - arguments: - - '@console.extension_manager' - - '@console.site' - - '@console.renderer' - tags: - - { name: drupal.generator } - console.entitybundle_generator: - class: Drupal\Console\Generator\EntityBundleGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.entityconfig_generator: - class: Drupal\Console\Generator\EntityConfigGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.cache_context_generator: - class: Drupal\Console\Generator\CacheContextGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.database_add: - class: Drupal\Console\Command\Database\AddCommand - arguments: - - '@console.database_settings_generator' - tags: - - { name: drupal.command } - console.database_client: - class: Drupal\Console\Command\Database\ClientCommand - tags: - - { name: drupal.command } - console.database_query: - class: Drupal\Console\Command\Database\QueryCommand - tags: - - { name: drupal.command } - console.database_connect: - class: Drupal\Console\Command\Database\ConnectCommand - tags: - - { name: drupal.command } - console.database_drop: - class: Drupal\Console\Command\Database\DropCommand - arguments: - - '@database' - tags: - - { name: drupal.command } - console.database_dump: - class: Drupal\Console\Command\Database\DumpCommand - arguments: - - '@app.root' - - '@console.shell_process' - tags: - - { name: drupal.command } - console.database_log_clear: - class: Drupal\Console\Command\Database\LogClearCommand - arguments: - - '@database' - tags: - - { name: drupal.command } - console.database_log_debug: - class: Drupal\Console\Command\Database\LogDebugCommand - arguments: - - '@database' - - '@date.formatter' - - '@entity_type.manager' - - '@string_translation' - tags: - - { name: drupal.command } - console.database_log_poll: - class: Drupal\Console\Command\Database\LogPollCommand - arguments: - - '@database' - - '@date.formatter' - - '@entity_type.manager' - - '@string_translation' - tags: - - { name: drupal.command } - console.database_restore: - class: Drupal\Console\Command\Database\RestoreCommand - arguments: - - '@app.root' - tags: - - { name: drupal.command } - console.database_table_debug: - class: Drupal\Console\Command\Database\TableDebugCommand - arguments: - - '@console.redbean' - - '@database' - tags: - - { name: drupal.command } - console.breakpoints_debug: - class: Drupal\Console\Command\Breakpoints\DebugCommand - arguments: - - '@breakpoint.manager' - - '@app.root' - tags: - - { name: drupal.command } - migrate_rollback: - class: Drupal\Console\Command\Migrate\RollBackCommand - arguments: - - '@plugin.manager.migration' - tags: - - { name: drupal.command } - migrate_execute: - class: Drupal\Console\Command\Migrate\ExecuteCommand - arguments: - - '@plugin.manager.migration' - tags: - - { name: drupal.command } - migrate_debug: - class: Drupal\Console\Command\Migrate\DebugCommand - arguments: - - '@plugin.manager.migration' - tags: - - { name: drupal.command } - migrate_setup: - class: Drupal\Console\Command\Migrate\SetupCommand - arguments: - - '@state' - - '@plugin.manager.migration' - tags: - - { name: drupal.command } - metatag.generate_tag: - class: Drupal\metatag\Command\GenerateTagCommand - arguments: - - '@metatag.manager' - - '@metatag.tag_generator' - - '@?console.extension_manager' - - '@?console.string_converter' - - '@?console.chain_queue' - tags: - - { name: drupal.command } - metatag.generate_group: - class: Drupal\metatag\Command\GenerateGroupCommand - arguments: - - '@metatag.group_generator' - - '@?console.extension_manager' - - '@?console.chain_queue' - tags: - - { name: drupal.command } - metatag.tag_generator: - class: Drupal\metatag\Generator\MetatagTagGenerator - arguments: - - '@?console.extension_manager' - - '@?console.renderer' - tags: - - { name: drupal.generator } - metatag.group_generator: - class: Drupal\metatag\Generator\MetatagGroupGenerator - arguments: - - '@?console.extension_manager' - - '@?console.renderer' - tags: - - { name: drupal.generator } diff --git a/console/cache/c5b9512e-b1a5-48a3-987b-243f4ec2675e/console.services.yml b/console/cache/c5b9512e-b1a5-48a3-987b-243f4ec2675e/console.services.yml deleted file mode 100644 index ec2cf54dc..000000000 --- a/console/cache/c5b9512e-b1a5-48a3-987b-243f4ec2675e/console.services.yml +++ /dev/null @@ -1,1390 +0,0 @@ -services: - console.cache_context_debug: - class: Drupal\Console\Command\Cache\ContextDebugCommand - tags: - - { name: drupal.command } - console.cache_rebuild: - class: Drupal\Console\Command\Cache\RebuildCommand - arguments: - - '@console.drupal_api' - - '@console.site' - - '@class_loader' - - '@request_stack' - tags: - - { name: drupal.command } - console.entity_debug: - class: Drupal\Console\Command\Entity\DebugCommand - arguments: - - '@entity_type.repository' - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.entity_delete: - class: Drupal\Console\Command\Entity\DeleteCommand - arguments: - - '@entity_type.repository' - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.field_info: - class: Drupal\Console\Command\Field\InfoCommand - arguments: - - '@entity_type.manager' - - '@entity_field.manager' - tags: - - { name: drupal.command } - console.create_nodes: - class: Drupal\Console\Command\Create\NodesCommand - arguments: - - '@console.drupal_api' - - '@console.create_node_data' - tags: - - { name: drupal.command } - console.create_comments: - class: Drupal\Console\Command\Create\CommentsCommand - arguments: - - '@console.create_comment_data' - tags: - - { name: drupal.command } - console.create_terms: - class: Drupal\Console\Command\Create\TermsCommand - arguments: - - '@console.drupal_api' - - '@console.create_term_data' - tags: - - { name: drupal.command } - console.create_users: - class: Drupal\Console\Command\Create\UsersCommand - arguments: - - '@console.drupal_api' - - '@console.create_user_data' - tags: - - { name: drupal.command } - console.create_vocabularies: - class: Drupal\Console\Command\Create\VocabulariesCommand - arguments: - - '@console.create_vocabulary_data' - tags: - - { name: drupal.command } - theme_debug: - class: Drupal\Console\Command\Theme\DebugCommand - arguments: - - '@config.factory' - - '@theme_handler' - tags: - - { name: drupal.command } - theme_download: - class: Drupal\Console\Command\Theme\DownloadCommand - arguments: - - '@console.drupal_api' - - '@http_client' - - '@app.root' - tags: - - { name: drupal.command } - theme_install: - class: Drupal\Console\Command\Theme\InstallCommand - arguments: - - '@config.factory' - - '@theme_handler' - - '@console.chain_queue' - tags: - - { name: drupal.command } - theme_path: - class: Drupal\Console\Command\Theme\PathCommand - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.command } - theme_uninstall: - class: Drupal\Console\Command\Theme\UninstallCommand - arguments: - - '@config.factory' - - '@theme_handler' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.state_debug: - class: Drupal\Console\Command\State\DebugCommand - arguments: - - '@state' - - '@keyvalue' - tags: - - { name: drupal.command } - console.state_delete: - class: Drupal\Console\Command\State\DeleteCommand - arguments: - - '@state' - - '@keyvalue' - tags: - - { name: drupal.command } - console.state_override: - class: Drupal\Console\Command\State\OverrideCommand - arguments: - - '@state' - - '@keyvalue' - tags: - - { name: drupal.command } - console.image_styles_debug: - class: Drupal\Console\Command\Image\StylesDebugCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.image_styles_flush: - class: Drupal\Console\Command\Image\StylesFlushCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.site_import_local: - class: Drupal\Console\Command\Site\ImportLocalCommand - arguments: - - '@app.root' - - '@console.configuration_manager' - tags: - - { name: drupal.command } - console.site_maintenance: - class: Drupal\Console\Command\Site\MaintenanceCommand - arguments: - - '@state' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.site_statistics: - class: Drupal\Console\Command\Site\StatisticsCommand - arguments: - - '@console.drupal_api' - - '@entity.query' - - '@console.extension_manager' - - '@module_handler' - tags: - - { name: drupal.command } - console.site_status: - class: Drupal\Console\Command\Site\StatusCommand - arguments: - - '@system.manager' - - '@settings' - - '@config.factory' - - '@theme_handler' - - '@app.root' - tags: - - { name: drupal.command } - console.config_debug: - class: Drupal\Console\Command\Config\DebugCommand - arguments: - - '@config.factory' - - '@config.storage' - tags: - - { name: drupal.command } - console.config_delete: - class: Drupal\Console\Command\Config\DeleteCommand - arguments: - - '@config.factory' - - '@config.storage' - - '@config.storage.sync' - tags: - - { name: drupal.command } - console.config_diff: - class: Drupal\Console\Command\Config\DiffCommand - arguments: - - '@config.storage' - - '@config.manager' - tags: - - { name: drupal.command } - console.config_edit: - class: Drupal\Console\Command\Config\EditCommand - arguments: - - '@config.factory' - - '@config.storage' - - '@console.configuration_manager' - tags: - - { name: drupal.command } - console.config_export: - class: Drupal\Console\Command\Config\ExportCommand - arguments: - - '@config.manager' - tags: - - { name: drupal.command } - console.config_export_content_type: - class: Drupal\Console\Command\Config\ExportContentTypeCommand - arguments: - - '@entity_type.manager' - - '@config.storage' - - '@console.extension_manager' - tags: - - { name: drupal.command } - console.config_export_single: - class: Drupal\Console\Command\Config\ExportSingleCommand - arguments: - - '@entity_type.manager' - - '@config.storage' - tags: - - { name: drupal.command } - console.config_export_view: - class: Drupal\Console\Command\Config\ExportViewCommand - arguments: - - '@entity_type.manager' - - '@config.storage' - - '@console.extension_manager' - tags: - - { name: drupal.command } - console.config_import: - class: Drupal\Console\Command\Config\ImportCommand - arguments: - - '@config.storage' - - '@config.manager' - tags: - - { name: drupal.command } - console.config_import_single: - class: Drupal\Console\Command\Config\ImportSingleCommand - arguments: - - '@config.storage' - - '@config.manager' - tags: - - { name: drupal.command } - console.config_override: - class: Drupal\Console\Command\Config\OverrideCommand - arguments: - - '@config.storage' - - '@config.factory' - tags: - - { name: drupal.command } - console.config_settings_debug: - class: Drupal\Console\Command\Config\SettingsDebugCommand - arguments: - - '@settings' - tags: - - { name: drupal.command } - console.config_validate: - class: Drupal\Console\Command\Config\ValidateCommand - tags: - - { name: drupal.command } - console.config_validate_debug: - class: Drupal\Console\Command\Config\ValidateDebugCommand - tags: - - { name: drupal.command } - console.queue_debug: - class: Drupal\Console\Command\Queue\DebugCommand - arguments: - - '@plugin.manager.queue_worker' - tags: - - { name: drupal.command } - console.queue_run: - class: Drupal\Console\Command\Queue\RunCommand - arguments: - - '@plugin.manager.queue_worker' - - '@queue' - tags: - - { name: drupal.command } - console.generate_module: - class: Drupal\Console\Command\Generate\ModuleCommand - arguments: - - '@console.module_generator' - - '@console.validator' - - '@app.root' - - '@console.string_converter' - - '@console.drupal_api' - - '@http_client' - - '@console.site' - tags: - - { name: drupal.command } - console.generate_modulefile: - class: Drupal\Console\Command\Generate\ModuleFileCommand - arguments: - - '@console.extension_manager' - - '@console.modulefile_generator' - tags: - - { name: drupal.command } - console.generate_authentication_provider: - class: Drupal\Console\Command\Generate\AuthenticationProviderCommand - arguments: - - '@console.extension_manager' - - '@console.authentication_provider_generator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_controller: - class: Drupal\Console\Command\Generate\ControllerCommand - arguments: - - '@console.extension_manager' - - '@console.controller_generator' - - '@console.string_converter' - - '@console.validator' - - '@router.route_provider' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_breakpoint: - class: Drupal\Console\Command\Generate\BreakPointCommand - arguments: - - '@console.breakpoint_generator' - - '@app.root' - - '@theme_handler' - - '@console.validator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_help: - class: Drupal\Console\Command\Generate\HelpCommand - arguments: - - '@console.help_generator' - - '@console.site' - - '@console.extension_manager' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_form: - class: Drupal\Console\Command\Generate\FormBaseCommand - arguments: - - '@console.extension_manager' - - '@console.form_generator' - - '@console.chain_queue' - - '@console.string_converter' - - '@plugin.manager.element_info' - - '@router.route_provider' - tags: - - { name: drupal.command } - console.generate_form_alter: - class: Drupal\Console\Command\Generate\FormAlterCommand - arguments: - - '@console.extension_manager' - - '@console.form_alter_generator' - - '@console.string_converter' - - '@module_handler' - - '@plugin.manager.element_info' - - '@?profiler' - - '@app.root' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_permissions: - class: Drupal\Console\Command\Generate\PermissionCommand - arguments: - - '@console.extension_manager' - - '@console.string_converter' - - '@console.permission_generator' - tags: - - { name: drupal.command } - console.generate_event_subscriber: - class: Drupal\Console\Command\Generate\EventSubscriberCommand - arguments: - - '@console.extension_manager' - - '@console.event_subscriber_generator' - - '@console.string_converter' - - '@event_dispatcher' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_form_config: - class: Drupal\Console\Command\Generate\ConfigFormBaseCommand - arguments: - - '@console.extension_manager' - - '@console.form_generator' - - '@console.string_converter' - - '@router.route_provider' - - '@plugin.manager.element_info' - - '@app.root' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_type_annotation: - class: Drupal\Console\Command\Generate\PluginTypeAnnotationCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_type_annotation_generator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_plugin_condition: - class: Drupal\Console\Command\Generate\PluginConditionCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_condition_generator' - - '@console.chain_queue' - - '@entity_type.repository' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_plugin_field: - class: Drupal\Console\Command\Generate\PluginFieldCommand - arguments: - - '@console.extension_manager' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_field_formatter: - class: Drupal\Console\Command\Generate\PluginFieldFormatterCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_field_formatter_generator' - - '@console.string_converter' - - '@plugin.manager.field.field_type' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_field_type: - class: Drupal\Console\Command\Generate\PluginFieldTypeCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_field_type_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_field_widget: - class: Drupal\Console\Command\Generate\PluginFieldWidgetCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_field_widget_generator' - - '@console.string_converter' - - '@plugin.manager.field.field_type' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_image_effect: - class: Drupal\Console\Command\Generate\PluginImageEffectCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_image_effect_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_image_formatter: - class: Drupal\Console\Command\Generate\PluginImageFormatterCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_image_formatter_generator' - - '@console.string_converter' - - '@console.validator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_mail: - class: Drupal\Console\Command\Generate\PluginMailCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_mail_generator' - - '@console.string_converter' - - '@console.validator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_migrate_source: - class: Drupal\Console\Command\Generate\PluginMigrateSourceCommand - arguments: - - '@config.factory' - - '@console.chain_queue' - - '@console.plugin_migrate_source_generator' - - '@entity_type.manager' - - '@console.extension_manager' - - '@console.validator' - - '@console.string_converter' - - '@plugin.manager.element_info' - tags: - - { name: drupal.command } - console.generate_plugin_migrate_process: - class: Drupal\Console\Command\Generate\PluginMigrateProcessCommand - arguments: - - '@console.plugin_migrate_process_generator' - - '@console.chain_queue' - - '@console.extension_manager' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_plugin_rest_resource: - class: Drupal\Console\Command\Generate\PluginRestResourceCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_rest_resource_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_rules_action: - class: Drupal\Console\Command\Generate\PluginRulesActionCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_rules_action_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_skeleton: - class: Drupal\Console\Command\Generate\PluginSkeletonCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_skeleton_generator' - - '@console.string_converter' - - '@console.validator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_plugin_type_yaml: - class: Drupal\Console\Command\Generate\PluginTypeYamlCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_type_yaml_generator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_plugin_views_field: - class: Drupal\Console\Command\Generate\PluginViewsFieldCommand - arguments: - - '@console.extension_manager' - - '@console.plugin_views_field_generator' - - '@console.site' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_post_update: - class: Drupal\Console\Command\Generate\PostUpdateCommand - arguments: - - '@console.extension_manager' - - '@console.post_update_generator' - - '@console.site' - - '@console.validator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_profile: - class: Drupal\Console\Command\Generate\ProfileCommand - arguments: - - '@console.extension_manager' - - '@console.profile_generator' - - '@console.string_converter' - - '@console.validator' - - '@app.root' - - '@console.site' - - '@http_client' - tags: - - { name: drupal.command } - console.generate_route_subscriber: - class: Drupal\Console\Command\Generate\RouteSubscriberCommand - arguments: - - '@console.extension_manager' - - '@console.route_subscriber_generator' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_service: - class: Drupal\Console\Command\Generate\ServiceCommand - arguments: - - '@console.extension_manager' - - '@console.service_generator' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_theme: - class: Drupal\Console\Command\Generate\ThemeCommand - arguments: - - '@console.extension_manager' - - '@console.theme_generator' - - '@console.validator' - - '@app.root' - - '@theme_handler' - - '@console.site' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_twig_extension: - class: Drupal\Console\Command\Generate\TwigExtensionCommand - arguments: - - '@console.extension_manager' - - '@console.twig_extension_generator' - - '@console.site' - - '@console.string_converter' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_update: - class: Drupal\Console\Command\Generate\UpdateCommand - arguments: - - '@console.extension_manager' - - '@console.update_generator' - - '@console.site' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_pluginblock: - class: Drupal\Console\Command\Generate\PluginBlockCommand - arguments: - - '@config.factory' - - '@console.chain_queue' - - '@console.pluginblock_generator' - - '@entity_type.manager' - - '@console.extension_manager' - - '@console.validator' - - '@console.string_converter' - - '@plugin.manager.element_info' - tags: - - { name: drupal.command } - console.generate_command: - class: Drupal\Console\Command\Generate\CommandCommand - arguments: - - '@console.command_generator' - - '@console.extension_manager' - - '@console.validator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_ckeditorbutton: - class: Drupal\Console\Command\Generate\PluginCKEditorButtonCommand - arguments: - - '@console.chain_queue' - - '@console.command_ckeditorbutton' - - '@console.extension_manager' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_entitycontent: - class: Drupal\Console\Command\Generate\EntityContentCommand - arguments: - - '@console.chain_queue' - - '@console.entitycontent_generator' - - '@console.string_converter' - - '@console.extension_manager' - - '@console.validator' - tags: - - { name: drupal.command } - console.generate_entitybundle: - class: Drupal\Console\Command\Generate\EntityBundleCommand - arguments: - - '@console.validator' - - '@console.entitybundle_generator' - - '@console.extension_manager' - tags: - - { name: drupal.command } - console.generate_entityconfig: - class: Drupal\Console\Command\Generate\EntityConfigCommand - arguments: - - '@console.extension_manager' - - '@console.entityconfig_generator' - - '@console.validator' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.generate_cache_context: - class: Drupal\Console\Command\Generate\CacheContextCommand - arguments: - - '@console.cache_context_generator' - - '@console.chain_queue' - - '@console.extension_manager' - - '@console.string_converter' - tags: - - { name: drupal.command } - console.update_debug: - class: Drupal\Console\Command\Update\DebugCommand - arguments: - - '@console.site' - - '@update.post_update_registry' - tags: - - { name: drupal.command } - console.update_entities: - class: Drupal\Console\Command\Update\EntitiesCommand - arguments: - - '@state' - - '@entity.definition_update_manager' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.update_execute: - class: Drupal\Console\Command\Update\ExecuteCommand - arguments: - - '@console.site' - - '@state' - - '@module_handler' - - '@update.post_update_registry' - - '@console.extension_manager' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.libraries_debug: - class: Drupal\Console\Command\Libraries\DebugCommand - arguments: - - '@module_handler' - - '@theme_handler' - - '@library.discovery' - - '@app.root' - tags: - - { name: drupal.command } - console.taxonomy_delete: - class: Drupal\Console\Command\Taxonomy\DeleteTermCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.views_disable: - class: Drupal\Console\Command\Views\DisableCommand - arguments: - - '@entity_type.manager' - - '@entity.query' - tags: - - { name: drupal.command } - console.views_enable: - class: Drupal\Console\Command\Views\EnableCommand - arguments: - - '@entity_type.manager' - - '@entity.query' - tags: - - { name: drupal.command } - console.views_debug: - class: Drupal\Console\Command\Views\DebugCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.views_plugins_debug: - class: Drupal\Console\Command\Views\PluginsDebugCommand - tags: - - { name: drupal.command } - console.cron_debug: - class: Drupal\Console\Command\Cron\DebugCommand - arguments: - - '@module_handler' - tags: - - { name: drupal.command } - console.cron_execute: - class: Drupal\Console\Command\Cron\ExecuteCommand - arguments: - - '@module_handler' - - '@lock' - - '@state' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.cron_release: - class: Drupal\Console\Command\Cron\ReleaseCommand - arguments: - - '@lock' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.generate_doc_cheatsheet: - class: Drupal\Console\Command\Develop\GenerateDocCheatsheetCommand - tags: - - { name: drupal.command } - console.generate_doc_dash: - class: Drupal\Console\Command\Develop\GenerateDocDashCommand - arguments: - - '@console.renderer' - - '@console.root' - tags: - - { name: drupal.command } - console.generate_doc_data: - class: Drupal\Console\Command\Develop\GenerateDocDataCommand - tags: - - { name: drupal.command } - console.generate_doc_gitbook: - class: Drupal\Console\Command\Develop\GenerateDocGitbookCommand - arguments: - - '@console.renderer' - tags: - - { name: drupal.command } - console.translation_cleanup: - class: Drupal\Console\Command\Develop\TranslationCleanupCommand - arguments: - - '@console.root' - - '@console.configuration_manager' - tags: - - { name: drupal.command } - console.translation_pending: - class: Drupal\Console\Command\Develop\TranslationPendingCommand - arguments: - - '@console.root' - - '@console.configuration_manager' - - '@console.nested_array' - tags: - - { name: drupal.command } - console.translation_stats: - class: Drupal\Console\Command\Develop\TranslationStatsCommand - arguments: - - '@console.root' - - '@console.configuration_manager' - - '@console.renderer' - - '@console.nested_array' - tags: - - { name: drupal.command } - console.translation_sync: - class: Drupal\Console\Command\Develop\TranslationSyncCommand - arguments: - - '@console.root' - - '@console.configuration_manager' - tags: - - { name: drupal.command } - console.user_debug: - class: Drupal\Console\Command\User\DebugCommand - arguments: - - '@entity_type.manager' - - '@entity.query' - - '@console.drupal_api' - tags: - - { name: drupal.command } - console.user_delete: - class: Drupal\Console\Command\User\DeleteCommand - arguments: - - '@entity_type.manager' - - '@entity.query' - - '@console.drupal_api' - tags: - - { name: drupal.command } - console.user_login_clear_attempts: - class: Drupal\Console\Command\User\LoginCleanAttemptsCommand - arguments: - - '@database' - tags: - - { name: drupal.command } - console.user_login_url: - class: Drupal\Console\Command\User\LoginUrlCommand - arguments: - - '@entity_type.manager' - tags: - - { name: drupal.command } - console.user_password_hash: - class: Drupal\Console\Command\User\PasswordHashCommand - arguments: - - '@password' - tags: - - { name: drupal.command } - console.user_password_reset: - class: Drupal\Console\Command\User\PasswordResetCommand - arguments: - - '@database' - - '@console.chain_queue' - tags: - - { name: drupal.command } - console.user_role: - class: Drupal\Console\Command\User\RoleCommand - arguments: - - '@console.drupal_api' - tags: - - { name: drupal.command } - console.user_create: - class: Drupal\Console\Command\User\CreateCommand - arguments: - - '@database' - - '@entity_type.manager' - - '@date.formatter' - - '@console.drupal_api' - tags: - - { name: drupal.command } - translation_status: - class: Drupal\Console\Command\Locale\TranslationStatusCommand - arguments: - - '@console.site' - - '@console.extension_manager' - tags: - - { name: drupal.command } - language_delete: - class: Drupal\Console\Command\Locale\LanguageDeleteCommand - arguments: - - '@console.site' - - '@entity_type.manager' - - '@module_handler' - tags: - - { name: drupal.command } - language_add: - class: Drupal\Console\Command\Locale\LanguageAddCommand - arguments: - - '@console.site' - - '@module_handler' - tags: - - { name: drupal.command } - console.node_access_rebuild: - class: Drupal\Console\Command\Node\AccessRebuildCommand - arguments: - - '@state' - tags: - - { name: drupal.command } - router_debug: - class: Drupal\Console\Command\Router\DebugCommand - arguments: - - '@router.route_provider' - tags: - - { name: drupal.command } - console.router_rebuild: - class: Drupal\Console\Command\Router\RebuildCommand - arguments: - - '@router.builder' - tags: - - { name: drupal.command } - feature_debug: - class: Drupal\Console\Command\Features\DebugCommand - tags: - - { name: drupal.command } - feature_import: - class: Drupal\Console\Command\Features\ImportCommand - tags: - - { name: drupal.command } - module_debug: - class: Drupal\Console\Command\Module\DebugCommand - arguments: - - '@console.configuration_manager' - - '@console.site' - - '@http_client' - tags: - - { name: drupal.command } - module_dependency_install: - class: Drupal\Console\Command\Module\InstallDependencyCommand - arguments: - - '@console.site' - - '@console.validator' - - '@module_installer' - - '@console.chain_queue' - tags: - - { name: drupal.command } - module_download: - class: Drupal\Console\Command\Module\DownloadCommand - arguments: - - '@console.drupal_api' - - '@http_client' - - '@app.root' - - '@console.extension_manager' - - '@console.validator' - - '@console.site' - - '@console.configuration_manager' - - '@console.shell_process' - - '@console.root' - tags: - - { name: drupal.command } - module_install: - class: Drupal\Console\Command\Module\InstallCommand - arguments: - - '@console.site' - - '@console.validator' - - '@module_installer' - - '@console.drupal_api' - - '@console.extension_manager' - - '@app.root' - - '@console.chain_queue' - tags: - - { name: drupal.command } - module_path: - class: Drupal\Console\Command\Module\PathCommand - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.command } - module_uninstall: - class: Drupal\Console\Command\Module\UninstallCommand - arguments: - - '@console.site' - - '@module_installer' - - '@console.chain_queue' - - '@config.factory' - tags: - - { name: drupal.command } - module_update: - class: Drupal\Console\Command\Module\UpdateCommand - arguments: - - '@console.shell_process' - - '@console.root' - tags: - - { name: drupal.command } - console.container_debug: - class: Drupal\Console\Command\ContainerDebugCommand - tags: - - { name: drupal.command } - console.plugin_debug: - class: Drupal\Console\Command\PluginDebugCommand - tags: - - { name: drupal.command } - console.permission_debug: - class: Drupal\Console\Command\PermissionDebugCommand - tags: - - { name: drupal.command } - console.event_debug: - class: Drupal\Console\Command\EventDebugCommand - arguments: - - '@event_dispatcher' - tags: - - { name: drupal.command } - console.devel_dumper: - class: Drupal\Console\Command\DevelDumperCommand - arguments: - - '@?plugin.manager.devel_dumper' - tags: - - { name: drupal.command } - console.shell: - class: Drupal\Console\Command\ShellCommand - tags: - - { name: drupal.command } - console.module_generator: - class: Drupal\Console\Generator\ModuleGenerator - tags: - - { name: drupal.generator } - console.modulefile_generator: - class: Drupal\Console\Generator\ModuleFileGenerator - tags: - - { name: drupal.generator } - console.authentication_provider_generator: - class: Drupal\Console\Generator\AuthenticationProviderGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.help_generator: - class: Drupal\Console\Generator\HelpGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.controller_generator: - class: Drupal\Console\Generator\ControllerGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.breakpoint_generator: - class: Drupal\Console\Generator\BreakPointGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.form_alter_generator: - class: Drupal\Console\Generator\FormAlterGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.permission_generator: - class: Drupal\Console\Generator\PermissionGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.event_subscriber_generator: - class: Drupal\Console\Generator\EventSubscriberGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.form_generator: - class: Drupal\Console\Generator\FormGenerator - arguments: - - '@console.extension_manager' - - '@console.string_converter' - tags: - - { name: drupal.generator } - console.profile_generator: - class: Drupal\Console\Generator\ProfileGenerator - tags: - - { name: drupal.generator } - console.post_update_generator: - class: Drupal\Console\Generator\PostUpdateGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_condition_generator: - class: Drupal\Console\Generator\PluginConditionGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_field_generator: - class: Drupal\Console\Generator\PluginFieldFormatterGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_field_formatter_generator: - class: Drupal\Console\Generator\PluginFieldFormatterGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_field_type_generator: - class: Drupal\Console\Generator\PluginFieldTypeGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_field_widget_generator: - class: Drupal\Console\Generator\PluginFieldWidgetGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_image_effect_generator: - class: Drupal\Console\Generator\PluginImageEffectGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_image_formatter_generator: - class: Drupal\Console\Generator\PluginImageFormatterGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_mail_generator: - class: Drupal\Console\Generator\PluginMailGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_migrate_source_generator: - class: Drupal\Console\Generator\PluginMigrateSourceGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_migrate_process_generator: - class: Drupal\Console\Generator\PluginMigrateProcessGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_rest_resource_generator: - class: Drupal\Console\Generator\PluginRestResourceGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_rules_action_generator: - class: Drupal\Console\Generator\PluginRulesActionGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_skeleton_generator: - class: Drupal\Console\Generator\PluginSkeletonGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_views_field_generator: - class: Drupal\Console\Generator\PluginViewsFieldGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_type_annotation_generator: - class: Drupal\Console\Generator\PluginTypeAnnotationGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.plugin_type_yaml_generator: - class: Drupal\Console\Generator\PluginTypeYamlGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.route_subscriber_generator: - class: Drupal\Console\Generator\RouteSubscriberGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.service_generator: - class: Drupal\Console\Generator\ServiceGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.theme_generator: - class: Drupal\Console\Generator\ThemeGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.twig_extension_generator: - class: Drupal\Console\Generator\TwigExtensionGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.update_generator: - class: Drupal\Console\Generator\UpdateGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.pluginblock_generator: - class: Drupal\Console\Generator\PluginBlockGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.command_generator: - class: Drupal\Console\Generator\CommandGenerator - arguments: - - '@console.extension_manager' - - '@console.translator_manager' - tags: - - { name: drupal.generator } - console.command_ckeditorbutton: - class: Drupal\Console\Generator\PluginCKEditorButtonGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.database_settings_generator: - class: Drupal\Console\Generator\DatabaseSettingsGenerator - arguments: - - '@kernel' - tags: - - { name: drupal.generator } - console.entitycontent_generator: - class: Drupal\Console\Generator\EntityContentGenerator - arguments: - - '@console.extension_manager' - - '@console.site' - - '@console.renderer' - tags: - - { name: drupal.generator } - console.entitybundle_generator: - class: Drupal\Console\Generator\EntityBundleGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.entityconfig_generator: - class: Drupal\Console\Generator\EntityConfigGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.cache_context_generator: - class: Drupal\Console\Generator\CacheContextGenerator - arguments: - - '@console.extension_manager' - tags: - - { name: drupal.generator } - console.database_add: - class: Drupal\Console\Command\Database\AddCommand - arguments: - - '@console.database_settings_generator' - tags: - - { name: drupal.command } - console.database_client: - class: Drupal\Console\Command\Database\ClientCommand - tags: - - { name: drupal.command } - console.database_query: - class: Drupal\Console\Command\Database\QueryCommand - tags: - - { name: drupal.command } - console.database_connect: - class: Drupal\Console\Command\Database\ConnectCommand - tags: - - { name: drupal.command } - console.database_drop: - class: Drupal\Console\Command\Database\DropCommand - arguments: - - '@database' - tags: - - { name: drupal.command } - console.database_dump: - class: Drupal\Console\Command\Database\DumpCommand - arguments: - - '@app.root' - - '@console.shell_process' - tags: - - { name: drupal.command } - console.database_log_clear: - class: Drupal\Console\Command\Database\LogClearCommand - arguments: - - '@database' - tags: - - { name: drupal.command } - console.database_log_debug: - class: Drupal\Console\Command\Database\LogDebugCommand - arguments: - - '@database' - - '@date.formatter' - - '@entity_type.manager' - - '@string_translation' - tags: - - { name: drupal.command } - console.database_log_poll: - class: Drupal\Console\Command\Database\LogPollCommand - arguments: - - '@database' - - '@date.formatter' - - '@entity_type.manager' - - '@string_translation' - tags: - - { name: drupal.command } - console.database_restore: - class: Drupal\Console\Command\Database\RestoreCommand - arguments: - - '@app.root' - tags: - - { name: drupal.command } - console.database_table_debug: - class: Drupal\Console\Command\Database\TableDebugCommand - arguments: - - '@console.redbean' - - '@database' - tags: - - { name: drupal.command } - console.breakpoints_debug: - class: Drupal\Console\Command\Breakpoints\DebugCommand - arguments: - - '@breakpoint.manager' - - '@app.root' - tags: - - { name: drupal.command } - migrate_rollback: - class: Drupal\Console\Command\Migrate\RollBackCommand - arguments: - - '@plugin.manager.migration' - tags: - - { name: drupal.command } - migrate_execute: - class: Drupal\Console\Command\Migrate\ExecuteCommand - arguments: - - '@plugin.manager.migration' - tags: - - { name: drupal.command } - migrate_debug: - class: Drupal\Console\Command\Migrate\DebugCommand - arguments: - - '@plugin.manager.migration' - tags: - - { name: drupal.command } - migrate_setup: - class: Drupal\Console\Command\Migrate\SetupCommand - arguments: - - '@state' - - '@plugin.manager.migration' - tags: - - { name: drupal.command } - metatag.generate_tag: - class: Drupal\metatag\Command\GenerateTagCommand - arguments: - - '@metatag.manager' - - '@metatag.tag_generator' - - '@?console.extension_manager' - - '@?console.string_converter' - - '@?console.chain_queue' - tags: - - { name: drupal.command } - metatag.generate_group: - class: Drupal\metatag\Command\GenerateGroupCommand - arguments: - - '@metatag.group_generator' - - '@?console.extension_manager' - - '@?console.chain_queue' - tags: - - { name: drupal.command } - metatag.tag_generator: - class: Drupal\metatag\Generator\MetatagTagGenerator - arguments: - - '@?console.extension_manager' - - '@?console.renderer' - tags: - - { name: drupal.generator } - metatag.group_generator: - class: Drupal\metatag\Generator\MetatagGroupGenerator - arguments: - - '@?console.extension_manager' - - '@?console.renderer' - tags: - - { name: drupal.generator } diff --git a/vendor/caxy/php-htmldiff/lib/Caxy/HtmlDiff/AbstractDiff.php b/vendor/caxy/php-htmldiff/lib/Caxy/HtmlDiff/AbstractDiff.php index 85545b396..c23464497 100644 --- a/vendor/caxy/php-htmldiff/lib/Caxy/HtmlDiff/AbstractDiff.php +++ b/vendor/caxy/php-htmldiff/lib/Caxy/HtmlDiff/AbstractDiff.php @@ -132,6 +132,11 @@ abstract class AbstractDiff $HTMLPurifierConfig->set('Cache.SerializerPath', $defaultPurifierSerializerCache); } + // Cache.SerializerPermissions defaults to 0744. + // This setting allows the cache files to be deleted by any user, as they are typically + // created by the web/php user (www-user, php-fpm, etc.) + $HTMLPurifierConfig->set('Cache.SerializerPermissions', 0777); + $this->purifier = new \HTMLPurifier($HTMLPurifierConfig); } diff --git a/vendor/caxy/php-htmldiff/tests/Caxy/Tests/HtmlDiff/Functional/HTMLPurifierConfigTest.php b/vendor/caxy/php-htmldiff/tests/Caxy/Tests/HtmlDiff/Functional/HTMLPurifierConfigTest.php index 7a883bbc8..89aec8d93 100644 --- a/vendor/caxy/php-htmldiff/tests/Caxy/Tests/HtmlDiff/Functional/HTMLPurifierConfigTest.php +++ b/vendor/caxy/php-htmldiff/tests/Caxy/Tests/HtmlDiff/Functional/HTMLPurifierConfigTest.php @@ -24,7 +24,8 @@ class HTMLPurifierConfigTest extends AbstractTest $this->config->expects($this->atLeastOnce()) ->method('set') - ->with('Cache.SerializerPath', '/tmp'); + ->with($this->anything(), $this->anything()) + ; $this->config->expects($this->any()) ->method('getHTMLDefinition') diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 46f64f50a..ff4b0b794 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -21,9 +21,12 @@ return array( 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php', 'PHPUnit\\Framework\\BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php', + 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Test.php', 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.php', 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestListener.php', + 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php', 'PHPUnit_Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', 'PHPUnit_Extensions_GroupTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php', 'PHPUnit_Extensions_PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestCase.php', @@ -461,4 +464,5 @@ return array( 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', 'SessionHandlerInterface' => $vendorDir . '/symfony/polyfill-php54/Resources/stubs/SessionHandlerInterface.php', 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', + 'TwitterAPIExchange' => $vendorDir . '/j7mbo/twitter-api-php/TwitterAPIExchange.php', ); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 19447c6a5..fad47ed38 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -14,14 +14,12 @@ return array( 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', - 'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php', '5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php', + 'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php', '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', 'fbeead2280a8f3911a1fe6dd034f7d5e' => $vendorDir . '/mkalkbrenner/php-htmldiff-advanced/src/HtmlDiffAdvancedInterface.php', '96f8d8288528d52059397cad6ec61f17' => $vendorDir . '/mkalkbrenner/php-htmldiff-advanced/src/HtmlDiffAdvanced.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', 'e7223560d890eab89cda23685e711e2c' => $vendorDir . '/psy/psysh/src/Psy/functions.php', - 'aca594cec0c196659a3b7d4dc2665c0b' => $vendorDir . '/j7mbo/twitter-api-php/TwitterAPIExchange.php', - '15a4f52ecde7234868b7009f6257de9a' => $vendorDir . '/drupal/console-core/src/constants.php', '5a12a5271c58108e0aa33355e6ac54ea' => $vendorDir . '/drupal/console-core/src/functions.php', ); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index 63e839744..5dd3efe8c 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -15,7 +15,6 @@ return array( 'Michelf' => array($vendorDir . '/michelf/php-markdown'), 'JakubOnderka\\PhpConsoleHighlighter' => array($vendorDir . '/jakub-onderka/php-console-highlighter/src'), 'JakubOnderka\\PhpConsoleColor' => array($vendorDir . '/jakub-onderka/php-console-color/src'), - 'Instagram' => array($vendorDir . '/php-instagram-api/php-instagram-api'), 'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'), 'Egulias\\' => array($vendorDir . '/egulias/email-validator/src'), 'EasyRdf_' => array($vendorDir . '/easyrdf/easyrdf/lib'), diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index f304acaf5..25c9d24e7 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -17,6 +17,7 @@ return array( 'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'), 'Webmozart\\PathUtil\\' => array($vendorDir . '/webmozart/path-util/src'), 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), + 'Twig\\' => array($vendorDir . '/twig/twig/src'), 'Symfony\\Polyfill\\Php55\\' => array($vendorDir . '/symfony/polyfill-php55'), 'Symfony\\Polyfill\\Php54\\' => array($vendorDir . '/symfony/polyfill-php54'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 693d5106a..0be8f5f6f 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -15,15 +15,13 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', - 'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php', '5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php', + 'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php', '2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', 'fbeead2280a8f3911a1fe6dd034f7d5e' => __DIR__ . '/..' . '/mkalkbrenner/php-htmldiff-advanced/src/HtmlDiffAdvancedInterface.php', '96f8d8288528d52059397cad6ec61f17' => __DIR__ . '/..' . '/mkalkbrenner/php-htmldiff-advanced/src/HtmlDiffAdvanced.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', 'e7223560d890eab89cda23685e711e2c' => __DIR__ . '/..' . '/psy/psysh/src/Psy/functions.php', - 'aca594cec0c196659a3b7d4dc2665c0b' => __DIR__ . '/..' . '/j7mbo/twitter-api-php/TwitterAPIExchange.php', - '15a4f52ecde7234868b7009f6257de9a' => __DIR__ . '/..' . '/drupal/console-core/src/constants.php', '5a12a5271c58108e0aa33355e6ac54ea' => __DIR__ . '/..' . '/drupal/console-core/src/functions.php', ); @@ -51,6 +49,10 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549 'Webmozart\\PathUtil\\' => 19, 'Webmozart\\Assert\\' => 17, ), + 'T' => + array ( + 'Twig\\' => 5, + ), 'S' => array ( 'Symfony\\Polyfill\\Php55\\' => 23, @@ -184,6 +186,10 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549 array ( 0 => __DIR__ . '/..' . '/webmozart/assert/src', ), + 'Twig\\' => + array ( + 0 => __DIR__ . '/..' . '/twig/twig/src', + ), 'Symfony\\Polyfill\\Php55\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php55', @@ -481,13 +487,6 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549 0 => __DIR__ . '/..' . '/jakub-onderka/php-console-color/src', ), ), - 'I' => - array ( - 'Instagram' => - array ( - 0 => __DIR__ . '/..' . '/php-instagram-api/php-instagram-api', - ), - ), 'H' => array ( 'HTMLPurifier' => @@ -571,9 +570,12 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549 'File_Iterator_Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php', 'File_Iterator_Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php', 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php', 'PHPUnit\\Framework\\BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php', + 'PHPUnit\\Framework\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/Test.php', 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.php', 'PHPUnit\\Framework\\TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestListener.php', + 'PHPUnit\\Framework\\TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php', 'PHPUnit_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php', 'PHPUnit_Extensions_GroupTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php', 'PHPUnit_Extensions_PhptTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/PhptTestCase.php', @@ -1011,6 +1013,7 @@ class ComposerStaticInit045d6a3105edf51cf91c16e965235549 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', 'SessionHandlerInterface' => __DIR__ . '/..' . '/symfony/polyfill-php54/Resources/stubs/SessionHandlerInterface.php', 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php', + 'TwitterAPIExchange' => __DIR__ . '/..' . '/j7mbo/twitter-api-php/TwitterAPIExchange.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 6f235ff67..5c0c690ea 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,156 +1,4 @@ [ - { - "name": "drupal-composer/drupal-scaffold", - "version": "2.2.0", - "version_normalized": "2.2.0.0", - "source": { - "type": "git", - "url": "https://github.com/drupal-composer/drupal-scaffold.git", - "reference": "3ad465ac853c2e52e6a808f5529859917662c256" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/drupal-composer/drupal-scaffold/zipball/3ad465ac853c2e52e6a808f5529859917662c256", - "reference": "3ad465ac853c2e52e6a808f5529859917662c256", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0.0", - "php": ">=5.4.5" - }, - "require-dev": { - "composer/composer": "dev-master", - "phpunit/phpunit": "^4.4.0" - }, - "time": "2016-11-05T10:46:44+00:00", - "type": "composer-plugin", - "extra": { - "class": "DrupalComposer\\DrupalScaffold\\Plugin", - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "DrupalComposer\\DrupalScaffold\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0+" - ], - "description": "Composer Plugin for updating the Drupal scaffold files when using drupal/core" - }, - { - "name": "composer/installers", - "version": "v1.2.0", - "version_normalized": "1.2.0.0", - "source": { - "type": "git", - "url": "https://github.com/composer/installers.git", - "reference": "d78064c68299743e0161004f2de3a0204e33b804" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/d78064c68299743e0161004f2de3a0204e33b804", - "reference": "d78064c68299743e0161004f2de3a0204e33b804", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0" - }, - "replace": { - "roundcube/plugin-installer": "*", - "shama/baton": "*" - }, - "require-dev": { - "composer/composer": "1.0.*@dev", - "phpunit/phpunit": "4.1.*" - }, - "time": "2016-08-13T20:53:52+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", - "Hurad", - "ImageCMS", - "MODX Evo", - "Mautic", - "OXID", - "Plentymarkets", - "RadPHP", - "SMF", - "Thelia", - "WolfCMS", - "agl", - "aimeos", - "annotatecms", - "attogram", - "bitrix", - "cakephp", - "chef", - "cockpit", - "codeigniter", - "concrete5", - "croogo", - "dokuwiki", - "drupal", - "elgg", - "expressionengine", - "fuelphp", - "grav", - "installer", - "joomla", - "kohana", - "laravel", - "lithium", - "magento", - "mako", - "mediawiki", - "modulework", - "moodle", - "phpbb", - "piwik", - "ppi", - "puppet", - "reindex", - "roundcube", - "shopware", - "silverstripe", - "symfony", - "typo3", - "wordpress", - "yawik", - "zend", - "zikula" - ] - }, { "name": "zendframework/zend-stdlib", "version": "3.1.0", @@ -296,67 +144,6 @@ "response" ] }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "time": "2016-11-14T01:06:16+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "installation-source": "dist", - "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" - ] - }, { "name": "ircmaxell/password-compat", "version": "v1.0.4", @@ -402,39 +189,35 @@ ] }, { - "name": "symfony/polyfill-php55", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", + "name": "psr/log", + "version": "1.0.2", + "version_normalized": "1.0.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "03e3f0350bca2220e3623a0e340eef194405fc67" + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/03e3f0350bca2220e3623a0e340eef194405fc67", - "reference": "03e3f0350bca2220e3623a0e340eef194405fc67", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, "require": { - "ircmaxell/password-compat": "~1.0", - "php": ">=5.3.3" + "php": ">=5.3.0" }, - "time": "2016-11-14T01:06:16+00:00", + "time": "2016-10-10T12:19:37+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.0.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Polyfill\\Php55\\": "" - }, - "files": [ - "bootstrap.php" - ] + "Psr\\Log\\": "Psr/Log/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -442,59 +225,53 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", - "homepage": "https://symfony.com", + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "log", + "psr", + "psr-3" ] }, { - "name": "symfony/polyfill-php54", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", + "name": "stack/builder", + "version": "v1.0.4", + "version_normalized": "1.0.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0" + "url": "https://github.com/stackphp/builder.git", + "reference": "59fcc9b448a8ce5e338a04c4e2e4aca893e83425" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0", - "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0", + "url": "https://api.github.com/repos/stackphp/builder/zipball/59fcc9b448a8ce5e338a04c4e2e4aca893e83425", + "reference": "59fcc9b448a8ce5e338a04c4e2e4aca893e83425", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.0", + "symfony/http-foundation": "~2.1|~3.0", + "symfony/http-kernel": "~2.1|~3.0" }, - "time": "2016-11-14T01:06:16+00:00", + "require-dev": { + "silex/silex": "~1.0" + }, + "time": "2016-06-02T06:58:42+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.0-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php54\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] + "psr-0": { + "Stack": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -502,59 +279,51 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" } ], - "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", - "homepage": "https://symfony.com", + "description": "Builder for stack middlewares based on HttpKernelInterface.", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "stack" ] }, { - "name": "symfony/polyfill-iconv", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", + "name": "masterminds/html5", + "version": "2.2.2", + "version_normalized": "2.2.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "cba36f3616d9866b3e52662e88da5c090fac1e97" + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "7866e93dcf0245de22378414e0c2c7350abc45af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/cba36f3616d9866b3e52662e88da5c090fac1e97", - "reference": "cba36f3616d9866b3e52662e88da5c090fac1e97", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/7866e93dcf0245de22378414e0c2c7350abc45af", + "reference": "7866e93dcf0245de22378414e0c2c7350abc45af", "shasum": "" }, "require": { - "php": ">=5.3.3" + "ext-libxml": "*", + "php": ">=5.3.0" }, - "suggest": { - "ext-iconv": "For best performance" + "require-dev": { + "phpunit/phpunit": "4.*", + "sami/sami": "~2.0", + "satooshi/php-coveralls": "1.0.*" }, - "time": "2016-11-14T01:06:16+00:00", + "time": "2016-09-22T11:01:11+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "2.2-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Polyfill\\Iconv\\": "" - }, - "files": [ - "bootstrap.php" - ] + "Masterminds\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -562,54 +331,66 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Matt Butcher", + "email": "technosophos@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" } ], - "description": "Symfony polyfill for the Iconv extension", - "homepage": "https://symfony.com", + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", "keywords": [ - "compatibility", - "iconv", - "polyfill", - "portable", - "shim" + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" ] }, { - "name": "psr/log", - "version": "1.0.2", - "version_normalized": "1.0.2.0", + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "version_normalized": "1.3.1.0", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=5.5.0" }, - "time": "2016-10-10T12:19:37+00:00", + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "time": "2016-12-20T10:07:11+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.4-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -617,48 +398,46 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Guzzle promises library", "keywords": [ - "log", - "psr", - "psr-3" + "promise" ] }, { - "name": "symfony/polyfill-apcu", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", + "name": "doctrine/lexer", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-apcu.git", - "reference": "5d4474f447403c3348e37b70acc2b95475b7befa" + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/5d4474f447403c3348e37b70acc2b95475b7befa", - "reference": "5d4474f447403c3348e37b70acc2b95475b7befa", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.2" }, - "time": "2016-11-14T01:06:16+00:00", + "time": "2014-09-09T13:34:57+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.0.x-dev" } }, "installation-source": "dist", "autoload": { - "files": [ - "bootstrap.php" - ] + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -666,66 +445,58 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Roman Borschel", + "email": "roman@code-factory.org" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", - "homepage": "https://symfony.com", + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", "keywords": [ - "apcu", - "compatibility", - "polyfill", - "portable", - "shim" + "lexer", + "parser" ] }, { - "name": "symfony-cmf/routing", - "version": "1.4.0", - "version_normalized": "1.4.0.0", + "name": "egulias/email-validator", + "version": "1.2.14", + "version_normalized": "1.2.14.0", "source": { "type": "git", - "url": "https://github.com/symfony-cmf/Routing.git", - "reference": "b93704ca098334f56e9b317932f21a4362e620db" + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "5642614492f0ca2064c01d60cc33284cc2f731a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/b93704ca098334f56e9b317932f21a4362e620db", - "reference": "b93704ca098334f56e9b317932f21a4362e620db", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/5642614492f0ca2064c01d60cc33284cc2f731a9", + "reference": "5642614492f0ca2064c01d60cc33284cc2f731a9", "shasum": "" }, "require": { - "php": "^5.3.9|^7.0", - "psr/log": "1.*", - "symfony/http-kernel": "^2.2|3.*", - "symfony/routing": "^2.2|3.*" + "doctrine/lexer": "^1.0.1", + "php": ">= 5.3.3" }, "require-dev": { - "friendsofsymfony/jsrouting-bundle": "^1.1", - "symfony-cmf/testing": "^1.3", - "symfony/config": "^2.2|3.*", - "symfony/dependency-injection": "^2.0.5|3.*", - "symfony/event-dispatcher": "^2.1|3.*" - }, - "suggest": { - "symfony/event-dispatcher": "DynamicRouter can optionally trigger an event at the start of matching. Minimal version (~2.1)" + "phpunit/phpunit": "^4.8.24" }, - "time": "2016-03-31T09:11:39+00:00", + "time": "2017-02-03T22:48:59+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "2.0.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Symfony\\Cmf\\Component\\Routing\\": "" + "psr-0": { + "Egulias\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -734,103 +505,115 @@ ], "authors": [ { - "name": "Symfony CMF Community", - "homepage": "https://github.com/symfony-cmf/Routing/contributors" + "name": "Eduardo Gulias Davis" } ], - "description": "Extends the Symfony2 routing component for dynamic routes and chaining several routers", - "homepage": "http://cmf.symfony.com", + "description": "A library for validating emails", + "homepage": "https://github.com/egulias/EmailValidator", "keywords": [ - "database", - "routing" + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" ] }, { - "name": "stack/builder", - "version": "v1.0.4", - "version_normalized": "1.0.4.0", + "name": "easyrdf/easyrdf", + "version": "0.9.1", + "version_normalized": "0.9.1.0", "source": { "type": "git", - "url": "https://github.com/stackphp/builder.git", - "reference": "59fcc9b448a8ce5e338a04c4e2e4aca893e83425" + "url": "https://github.com/njh/easyrdf.git", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stackphp/builder/zipball/59fcc9b448a8ce5e338a04c4e2e4aca893e83425", - "reference": "59fcc9b448a8ce5e338a04c4e2e4aca893e83425", + "url": "https://api.github.com/repos/njh/easyrdf/zipball/acd09dfe0555fbcfa254291e433c45fdd4652566", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566", "shasum": "" }, "require": { - "php": ">=5.3.0", - "symfony/http-foundation": "~2.1|~3.0", - "symfony/http-kernel": "~2.1|~3.0" + "ext-mbstring": "*", + "ext-pcre": "*", + "php": ">=5.2.8" }, "require-dev": { - "silex/silex": "~1.0" + "phpunit/phpunit": "~3.5", + "sami/sami": "~1.4", + "squizlabs/php_codesniffer": "~1.4.3" }, - "time": "2016-06-02T06:58:42+00:00", + "suggest": { + "ml/json-ld": "~1.0" + }, + "time": "2015-02-27T09:45:49+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, "installation-source": "dist", "autoload": { "psr-0": { - "Stack": "src" + "EasyRdf_": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" + "name": "Nicholas Humfrey", + "email": "njh@aelius.com", + "homepage": "http://www.aelius.com/njh/", + "role": "Developer" + }, + { + "name": "Alexey Zakhlestin", + "email": "indeyets@gmail.com", + "role": "Developer" } ], - "description": "Builder for stack middlewares based on HttpKernelInterface.", + "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", + "homepage": "http://www.easyrdf.org/", "keywords": [ - "stack" + "Linked Data", + "RDF", + "Semantic Web", + "Turtle", + "rdfa", + "sparql" ] }, { - "name": "masterminds/html5", - "version": "2.2.2", - "version_normalized": "2.2.2.0", + "name": "doctrine/inflector", + "version": "v1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", - "url": "https://github.com/Masterminds/html5-php.git", - "reference": "7866e93dcf0245de22378414e0c2c7350abc45af" + "url": "https://github.com/doctrine/inflector.git", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/7866e93dcf0245de22378414e0c2c7350abc45af", - "reference": "7866e93dcf0245de22378414e0c2c7350abc45af", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", "shasum": "" }, "require": { - "ext-libxml": "*", - "php": ">=5.3.0" + "php": ">=5.3.2" }, "require-dev": { - "phpunit/phpunit": "4.*", - "sami/sami": "~2.0", - "satooshi/php-coveralls": "1.0.*" + "phpunit/phpunit": "4.*" }, - "time": "2016-09-22T11:01:11+00:00", + "time": "2015-11-06T14:35:42+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "1.1.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Masterminds\\": "src" + "psr-0": { + "Doctrine\\Common\\Inflector\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", @@ -839,66 +622,73 @@ ], "authors": [ { - "name": "Matt Butcher", - "email": "technosophos@gmail.com" + "name": "Roman Borschel", + "email": "roman@code-factory.org" }, { - "name": "Asmir Mustafic", - "email": "goetas@gmail.com" + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" }, { - "name": "Matt Farina", - "email": "matt@mattfarina.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "An HTML5 parser and serializer.", - "homepage": "http://masterminds.github.io/html5-php", + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", "keywords": [ - "HTML5", - "dom", - "html", - "parser", - "querypath", - "serializer", - "xml" + "inflection", + "pluralize", + "singularize", + "string" ] }, { - "name": "guzzlehttp/promises", - "version": "v1.3.1", - "version_normalized": "1.3.1.0", + "name": "doctrine/cache", + "version": "v1.6.1", + "version_normalized": "1.6.1.0", "source": { "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + "url": "https://github.com/doctrine/cache.git", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "url": "https://api.github.com/repos/doctrine/cache/zipball/b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3", "shasum": "" }, "require": { - "php": ">=5.5.0" + "php": "~5.5|~7.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "phpunit/phpunit": "^4.0" + "phpunit/phpunit": "~4.8|~5.0", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" }, - "time": "2016-12-20T10:07:11+00:00", + "time": "2016-10-29T11:16:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.6.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -906,45 +696,67 @@ ], "authors": [ { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "Guzzle promises library", + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", "keywords": [ - "promise" + "cache", + "caching" ] }, { - "name": "doctrine/lexer", - "version": "v1.0.1", - "version_normalized": "1.0.1.0", + "name": "doctrine/annotations", + "version": "v1.2.7", + "version_normalized": "1.2.7.0", "source": { "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + "url": "https://github.com/doctrine/annotations.git", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", "shasum": "" }, "require": { + "doctrine/lexer": "1.*", "php": ">=5.3.2" }, - "time": "2014-09-09T13:34:57+00:00", + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "4.*" + }, + "time": "2015-08-31T12:32:49+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.3.x-dev" } }, "installation-source": "dist", "autoload": { "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" + "Doctrine\\Common\\Annotations\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", @@ -956,55 +768,64 @@ "name": "Roman Borschel", "email": "roman@code-factory.org" }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, { "name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com" }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" } ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "description": "Docblock Annotations Parser", "homepage": "http://www.doctrine-project.org", "keywords": [ - "lexer", + "annotations", + "docblock", "parser" ] }, { - "name": "egulias/email-validator", - "version": "1.2.14", - "version_normalized": "1.2.14.0", + "name": "composer/semver", + "version": "1.4.2", + "version_normalized": "1.4.2.0", "source": { "type": "git", - "url": "https://github.com/egulias/EmailValidator.git", - "reference": "5642614492f0ca2064c01d60cc33284cc2f731a9" + "url": "https://github.com/composer/semver.git", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/5642614492f0ca2064c01d60cc33284cc2f731a9", - "reference": "5642614492f0ca2064c01d60cc33284cc2f731a9", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", "shasum": "" }, "require": { - "doctrine/lexer": "^1.0.1", - "php": ">= 5.3.3" + "php": "^5.3.2 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.24" + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" }, - "time": "2017-02-03T22:48:59+00:00", + "time": "2016-08-30T16:08:34+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-0": { - "Egulias\\": "src/" + "psr-4": { + "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1013,115 +834,106 @@ ], "authors": [ { - "name": "Eduardo Gulias Davis" + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], - "description": "A library for validating emails", - "homepage": "https://github.com/egulias/EmailValidator", + "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ - "email", - "emailvalidation", - "emailvalidator", + "semantic", + "semver", "validation", - "validator" + "versioning" ] }, { - "name": "easyrdf/easyrdf", - "version": "0.9.1", - "version_normalized": "0.9.1.0", + "name": "jakub-onderka/php-console-color", + "version": "0.1", + "version_normalized": "0.1.0.0", "source": { "type": "git", - "url": "https://github.com/njh/easyrdf.git", - "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566" + "url": "https://github.com/JakubOnderka/PHP-Console-Color.git", + "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/njh/easyrdf/zipball/acd09dfe0555fbcfa254291e433c45fdd4652566", - "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566", - "shasum": "" + "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1", + "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1", + "shasum": "" }, "require": { - "ext-mbstring": "*", - "ext-pcre": "*", - "php": ">=5.2.8" + "php": ">=5.3.2" }, "require-dev": { - "phpunit/phpunit": "~3.5", - "sami/sami": "~1.4", - "squizlabs/php_codesniffer": "~1.4.3" - }, - "suggest": { - "ml/json-ld": "~1.0" + "jakub-onderka/php-code-style": "1.0", + "jakub-onderka/php-parallel-lint": "0.*", + "jakub-onderka/php-var-dump-check": "0.*", + "phpunit/phpunit": "3.7.*", + "squizlabs/php_codesniffer": "1.*" }, - "time": "2015-02-27T09:45:49+00:00", + "time": "2014-04-08T15:00:19+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-0": { - "EasyRdf_": "lib/" + "JakubOnderka\\PhpConsoleColor": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "BSD-2-Clause" ], "authors": [ { - "name": "Nicholas Humfrey", - "email": "njh@aelius.com", - "homepage": "http://www.aelius.com/njh/", - "role": "Developer" - }, - { - "name": "Alexey Zakhlestin", - "email": "indeyets@gmail.com", - "role": "Developer" + "name": "Jakub Onderka", + "email": "jakub.onderka@gmail.com", + "homepage": "http://www.acci.cz" } - ], - "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", - "homepage": "http://www.easyrdf.org/", - "keywords": [ - "Linked Data", - "RDF", - "Semantic Web", - "Turtle", - "rdfa", - "sparql" ] }, { - "name": "doctrine/inflector", - "version": "v1.1.0", - "version_normalized": "1.1.0.0", + "name": "jakub-onderka/php-console-highlighter", + "version": "v0.3.2", + "version_normalized": "0.3.2.0", "source": { "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" + "url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git", + "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", - "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", + "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/7daa75df45242c8d5b75a22c00a201e7954e4fb5", + "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5", "shasum": "" }, "require": { - "php": ">=5.3.2" + "jakub-onderka/php-console-color": "~0.1", + "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "4.*" + "jakub-onderka/php-code-style": "~1.0", + "jakub-onderka/php-parallel-lint": "~0.5", + "jakub-onderka/php-var-dump-check": "~0.1", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5" }, - "time": "2015-11-06T14:35:42+00:00", + "time": "2015-04-20T18:58:01+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, "installation-source": "dist", "autoload": { "psr-0": { - "Doctrine\\Common\\Inflector\\": "lib/" + "JakubOnderka\\PhpConsoleHighlighter": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1130,140 +942,80 @@ ], "authors": [ { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Jakub Onderka", + "email": "acci@acci.cz", + "homepage": "http://www.acci.cz/" } - ], - "description": "Common String Manipulations with regard to casing and singular/plural rules.", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "inflection", - "pluralize", - "singularize", - "string" ] }, { - "name": "doctrine/collections", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", + "name": "dnoegel/php-xdg-base-dir", + "version": "0.1", + "version_normalized": "0.1.0.0", "source": { "type": "git", - "url": "https://github.com/doctrine/collections.git", - "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", - "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/265b8593498b997dc2d31e75b89f053b5cc9621a", + "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a", "shasum": "" }, "require": { "php": ">=5.3.2" }, "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "time": "2015-04-14T22:21:58+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } + "phpunit/phpunit": "@stable" }, + "time": "2014-10-24T07:27:01+00:00", + "type": "project", "installation-source": "dist", "autoload": { - "psr-0": { - "Doctrine\\Common\\Collections\\": "lib/" + "psr-4": { + "XdgBaseDir\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Collections Abstraction library", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "array", - "collections", - "iterator" - ] + "description": "implementation of xdg base directory specification for php" }, { - "name": "doctrine/cache", - "version": "v1.6.1", - "version_normalized": "1.6.1.0", + "name": "stecman/symfony-console-completion", + "version": "0.7.0", + "version_normalized": "0.7.0.0", "source": { "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3" + "url": "https://github.com/stecman/symfony-console-completion.git", + "reference": "5461d43e53092b3d3b9dbd9d999f2054730f4bbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/b6f544a20f4807e81f7044d31e679ccbb1866dc3", - "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "url": "https://api.github.com/repos/stecman/symfony-console-completion/zipball/5461d43e53092b3d3b9dbd9d999f2054730f4bbb", + "reference": "5461d43e53092b3d3b9dbd9d999f2054730f4bbb", "shasum": "" }, "require": { - "php": "~5.5|~7.0" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" + "php": ">=5.3.2", + "symfony/console": "~2.3 || ~3.0" }, "require-dev": { - "phpunit/phpunit": "~4.8|~5.0", - "predis/predis": "~1.0", - "satooshi/php-coveralls": "~0.6" + "phpunit/phpunit": "~4.4" }, - "time": "2016-10-29T11:16:17+00:00", + "time": "2016-02-24T05:08:54+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "0.6.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + "Stecman\\Component\\Symfony\\Console\\BashCompletion\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1272,67 +1024,41 @@ ], "authors": [ { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Stephen Holdaway", + "email": "stephen@stecman.co.nz" } ], - "description": "Caching library offering an object-oriented API for many cache backends", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "cache", - "caching" - ] + "description": "Automatic BASH completion for Symfony Console Component based applications." }, { - "name": "doctrine/annotations", - "version": "v1.2.7", - "version_normalized": "1.2.7.0", + "name": "dflydev/placeholder-resolver", + "version": "v1.0.2", + "version_normalized": "1.0.2.0", "source": { "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" + "url": "https://github.com/dflydev/dflydev-placeholder-resolver.git", + "reference": "c498d0cae91b1bb36cc7d60906dab8e62bb7c356" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", - "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "url": "https://api.github.com/repos/dflydev/dflydev-placeholder-resolver/zipball/c498d0cae91b1bb36cc7d60906dab8e62bb7c356", + "reference": "c498d0cae91b1bb36cc7d60906dab8e62bb7c356", "shasum": "" }, "require": { - "doctrine/lexer": "1.*", "php": ">=5.3.2" }, - "require-dev": { - "doctrine/cache": "1.*", - "phpunit/phpunit": "4.*" - }, - "time": "2015-08-31T12:32:49+00:00", + "time": "2012-10-28T21:08:28+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "1.0-dev" } }, "installation-source": "dist", "autoload": { "psr-0": { - "Doctrine\\Common\\Annotations\\": "lib/" + "Dflydev\\PlaceholderResolver": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1341,67 +1067,52 @@ ], "authors": [ { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" }, { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" } ], - "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", + "description": "Given a data source representing key => value pairs, resolve placeholders like ${foo.bar} to the value associated with the 'foo.bar' key in the data source.", + "homepage": "https://github.com/dflydev/dflydev-placeholder-resolver", "keywords": [ - "annotations", - "docblock", - "parser" + "placeholder", + "resolver" ] }, { - "name": "composer/semver", - "version": "1.4.2", - "version_normalized": "1.4.2.0", + "name": "dflydev/dot-access-data", + "version": "v1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/3fbd874921ab2c041e899d044585a2ab9795df8a", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.5 || ^5.0.5", - "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + "php": ">=5.3.2" }, - "time": "2016-08-30T16:08:34+00:00", + "time": "2017-01-20T21:14:22+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-master": "1.0-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" + "psr-0": { + "Dflydev\\DotAccessData": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1410,106 +1121,137 @@ ], "authors": [ { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" }, { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" }, { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" } ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", "keywords": [ - "semantic", - "semver", - "validation", - "versioning" + "access", + "data", + "dot", + "notation" ] }, { - "name": "jakub-onderka/php-console-color", - "version": "0.1", - "version_normalized": "0.1.0.0", + "name": "dflydev/dot-access-configuration", + "version": "v1.0.1", + "version_normalized": "1.0.1.0", "source": { "type": "git", - "url": "https://github.com/JakubOnderka/PHP-Console-Color.git", - "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1" + "url": "https://github.com/dflydev/dflydev-dot-access-configuration.git", + "reference": "9b65c83159c9003e00284ea1144ad96b69d9c8b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1", - "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-configuration/zipball/9b65c83159c9003e00284ea1144ad96b69d9c8b9", + "reference": "9b65c83159c9003e00284ea1144ad96b69d9c8b9", "shasum": "" }, "require": { + "dflydev/dot-access-data": "1.*", + "dflydev/placeholder-resolver": "1.*", "php": ">=5.3.2" }, "require-dev": { - "jakub-onderka/php-code-style": "1.0", - "jakub-onderka/php-parallel-lint": "0.*", - "jakub-onderka/php-var-dump-check": "0.*", - "phpunit/phpunit": "3.7.*", - "squizlabs/php_codesniffer": "1.*" + "symfony/yaml": "~2.1" }, - "time": "2014-04-08T15:00:19+00:00", + "suggest": { + "symfony/yaml": "Required for using the YAML Configuration Builders" + }, + "time": "2014-11-14T03:26:12+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, "installation-source": "dist", "autoload": { "psr-0": { - "JakubOnderka\\PhpConsoleColor": "src/" + "Dflydev\\DotAccessConfiguration": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-2-Clause" + "MIT" ], "authors": [ { - "name": "Jakub Onderka", - "email": "jakub.onderka@gmail.com", - "homepage": "http://www.acci.cz" + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" } + ], + "description": "Given a deep data structure representing a configuration, access configuration by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-configuration", + "keywords": [ + "config", + "configuration" ] }, { - "name": "jakub-onderka/php-console-highlighter", - "version": "v0.3.2", - "version_normalized": "0.3.2.0", + "name": "alchemy/zippy", + "version": "0.4.3", + "version_normalized": "0.4.3.0", "source": { "type": "git", - "url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git", - "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5" + "url": "https://github.com/alchemy-fr/Zippy.git", + "reference": "5ffdc93de0af2770d396bf433d8b2667c77277ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/7daa75df45242c8d5b75a22c00a201e7954e4fb5", - "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5", + "url": "https://api.github.com/repos/alchemy-fr/Zippy/zipball/5ffdc93de0af2770d396bf433d8b2667c77277ea", + "reference": "5ffdc93de0af2770d396bf433d8b2667c77277ea", "shasum": "" }, "require": { - "jakub-onderka/php-console-color": "~0.1", - "php": ">=5.3.0" + "doctrine/collections": "~1.0", + "ext-mbstring": "*", + "php": ">=5.5", + "symfony/filesystem": "^2.0.5|^3.0", + "symfony/process": "^2.1|^3.0" }, "require-dev": { - "jakub-onderka/php-code-style": "~1.0", - "jakub-onderka/php-parallel-lint": "~0.5", - "jakub-onderka/php-var-dump-check": "~0.1", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~1.5" + "ext-zip": "*", + "guzzle/guzzle": "~3.0", + "guzzlehttp/guzzle": "^6.0", + "phpunit/phpunit": "^4.0|^5.0", + "symfony/finder": "^2.0.5|^3.0" }, - "time": "2015-04-20T18:58:01+00:00", + "suggest": { + "ext-zip": "To use the ZipExtensionAdapter", + "guzzle/guzzle": "To use the GuzzleTeleporter with Guzzle 3", + "guzzlehttp/guzzle": "To use the GuzzleTeleporter with Guzzle 6" + }, + "time": "2016-11-03T16:10:31+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.4.x-dev" + } + }, "installation-source": "dist", "autoload": { - "psr-0": { - "JakubOnderka\\PhpConsoleHighlighter": "src/" + "psr-4": { + "Alchemy\\Zippy\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1518,85 +1260,109 @@ ], "authors": [ { - "name": "Jakub Onderka", - "email": "acci@acci.cz", - "homepage": "http://www.acci.cz/" + "name": "Alchemy", + "email": "dev.team@alchemy.fr", + "homepage": "http://www.alchemy.fr/" } + ], + "description": "Zippy, the archive manager companion", + "keywords": [ + "bzip", + "compression", + "tar", + "zip" ] }, { - "name": "dnoegel/php-xdg-base-dir", - "version": "0.1", - "version_normalized": "0.1.0.0", + "name": "fabpot/goutte", + "version": "v3.2.1", + "version_normalized": "3.2.1.0", "source": { "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a" + "url": "https://github.com/FriendsOfPHP/Goutte.git", + "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/265b8593498b997dc2d31e75b89f053b5cc9621a", - "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a", + "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/db5c28f4a010b4161d507d5304e28a7ebf211638", + "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638", "shasum": "" }, "require": { - "php": ">=5.3.2" + "guzzlehttp/guzzle": "^6.0", + "php": ">=5.5.0", + "symfony/browser-kit": "~2.1|~3.0", + "symfony/css-selector": "~2.1|~3.0", + "symfony/dom-crawler": "~2.1|~3.0" }, - "require-dev": { - "phpunit/phpunit": "@stable" + "time": "2017-01-03T13:21:43+00:00", + "type": "application", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } }, - "time": "2014-10-24T07:27:01+00:00", - "type": "project", "installation-source": "dist", "autoload": { "psr-4": { - "XdgBaseDir\\": "src/" + "Goutte\\": "Goutte" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "implementation of xdg base directory specification for php" + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A simple PHP Web Scraper", + "homepage": "https://github.com/FriendsOfPHP/Goutte", + "keywords": [ + "scraper" + ] }, { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", - "version_normalized": "2.0.4.0", + "name": "behat/mink", + "version": "v1.7.1", + "version_normalized": "1.7.1.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + "url": "https://github.com/minkphp/Mink.git", + "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9", + "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.1", + "symfony/css-selector": "~2.1|~3.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "symfony/phpunit-bridge": "~2.7|~3.0" }, "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" + "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", + "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation", + "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", + "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)" }, - "time": "2015-02-03T12:10:50+00:00", + "time": "2016-03-05T08:26:18+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.7.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/" - ] + "psr-4": { + "Behat\\Mink\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1605,169 +1371,229 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" } + ], + "description": "Browser controller/emulator abstraction for PHP", + "homepage": "http://mink.behat.org/", + "keywords": [ + "browser", + "testing", + "web" ] }, { - "name": "gabordemooij/redbean", - "version": "v4.3.3", - "version_normalized": "4.3.3.0", + "name": "behat/mink-browserkit-driver", + "version": "v1.3.2", + "version_normalized": "1.3.2.0", "source": { "type": "git", - "url": "https://github.com/gabordemooij/redbean.git", - "reference": "1c7ec69850e9f7966ff7feb87b01d8f43a9753d3" + "url": "https://github.com/minkphp/MinkBrowserKitDriver.git", + "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/gabordemooij/redbean/zipball/1c7ec69850e9f7966ff7feb87b01d8f43a9753d3", - "reference": "1c7ec69850e9f7966ff7feb87b01d8f43a9753d3", + "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/10e67fb4a295efcd62ea0bf16025a85ea19534fb", + "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb", "shasum": "" }, "require": { - "php": ">=5.3.4" + "behat/mink": "^1.7.1@dev", + "php": ">=5.3.6", + "symfony/browser-kit": "~2.3|~3.0", + "symfony/dom-crawler": "~2.3|~3.0" + }, + "require-dev": { + "silex/silex": "~1.2", + "symfony/phpunit-bridge": "~2.7|~3.0" + }, + "time": "2016-03-05T08:59:47+00:00", + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } }, - "time": "2016-10-03T21:25:17+00:00", - "type": "library", "installation-source": "dist", "autoload": { "psr-4": { - "RedBeanPHP\\": "RedBeanPHP" + "Behat\\Mink\\Driver\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "New BSD and GPLv2" + "MIT" ], "authors": [ { - "name": "Gabor de Mooij", - "email": "gabor@redbeanphp.com", - "homepage": "http://redbeanphp.com" + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" } ], - "description": "RedBeanPHP ORM", - "homepage": "http://redbeanphp.com/", + "description": "Symfony2 BrowserKit driver for Mink framework", + "homepage": "http://mink.behat.org/", "keywords": [ - "orm" + "Mink", + "Symfony2", + "browser", + "testing" ] }, { - "name": "drupal/console-extend-plugin", - "version": "0.4.0", - "version_normalized": "0.4.0.0", + "name": "behat/mink-goutte-driver", + "version": "v1.2.1", + "version_normalized": "1.2.1.0", "source": { "type": "git", - "url": "https://github.com/hechoendrupal/drupal-console-extend-plugin.git", - "reference": "df2396782960335d18a8e5eb6ab630a37ca5f493" + "url": "https://github.com/minkphp/MinkGoutteDriver.git", + "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-extend-plugin/zipball/df2396782960335d18a8e5eb6ab630a37ca5f493", - "reference": "df2396782960335d18a8e5eb6ab630a37ca5f493", + "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", + "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0", - "symfony/finder": ">=2.7 <3.0", - "symfony/yaml": ">=2.7 <3.0" + "behat/mink": "~1.6@dev", + "behat/mink-browserkit-driver": "~1.2@dev", + "fabpot/goutte": "~1.0.4|~2.0|~3.1", + "php": ">=5.3.1" }, - "time": "2017-02-14T08:38:49+00:00", - "type": "composer-plugin", + "require-dev": { + "symfony/phpunit-bridge": "~2.7|~3.0" + }, + "time": "2016-03-05T09:04:22+00:00", + "type": "mink-driver", "extra": { - "class": "Drupal\\Console\\Composer\\Plugin\\Extender" + "branch-alias": { + "dev-master": "1.2.x-dev" + } }, "installation-source": "dist", "autoload": { "psr-4": { - "Drupal\\Console\\Composer\\Plugin\\": "src" + "Behat\\Mink\\Driver\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Jesus Manuel Olivas", - "email": "jesus.olivas@gmail.com" + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" } ], - "description": "Drupal Console Extend Plugin" + "description": "Goutte driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "browser", + "goutte", + "headless", + "testing" + ] }, { - "name": "webflo/drupal-finder", - "version": "0.2.1", - "version_normalized": "0.2.1.0", + "name": "jcalderonzumba/gastonjs", + "version": "v1.0.3", + "version_normalized": "1.0.3.0", "source": { "type": "git", - "url": "https://github.com/webflo/drupal-finder.git", - "reference": "4bd98f7e7b1d30e284e55f51d5d0c8712f676348" + "url": "https://github.com/jcalderonzumba/gastonjs.git", + "reference": "4ff4a788d4995ae0d4b45fdcb1b76650e2eec72a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/4bd98f7e7b1d30e284e55f51d5d0c8712f676348", - "reference": "4bd98f7e7b1d30e284e55f51d5d0c8712f676348", + "url": "https://api.github.com/repos/jcalderonzumba/gastonjs/zipball/4ff4a788d4995ae0d4b45fdcb1b76650e2eec72a", + "reference": "4ff4a788d4995ae0d4b45fdcb1b76650e2eec72a", "shasum": "" }, + "require": { + "guzzlehttp/guzzle": "~5.0|~6.0", + "php": ">=5.4" + }, "require-dev": { - "mikey179/vfsstream": "^1.6", - "phpunit/phpunit": "^4.8" + "phpunit/phpunit": "~4.6", + "silex/silex": "~1.2", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.1" + }, + "time": "2016-05-04T16:27:07+00:00", + "type": "phantomjs-api", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } }, - "time": "2016-11-28T18:50:45+00:00", - "type": "library", "installation-source": "dist", "autoload": { - "classmap": [ - "src/DrupalFinder.php" - ] + "psr-4": { + "Zumba\\GastonJS\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Florian Weber", - "email": "florian@webflo.org" + "name": "Juan Francisco Calderón Zumba", + "email": "juanfcz@gmail.com", + "homepage": "http://github.com/jcalderonzumba" } ], - "description": "Helper class to locate a Drupal installation from a given path." + "description": "PhantomJS API based server for webpage automation", + "homepage": "https://github.com/jcalderonzumba/gastonjs", + "keywords": [ + "api", + "automation", + "browser", + "headless", + "phantomjs" + ] }, { - "name": "stecman/symfony-console-completion", - "version": "0.7.0", - "version_normalized": "0.7.0.0", + "name": "jcalderonzumba/mink-phantomjs-driver", + "version": "v0.3.3", + "version_normalized": "0.3.3.0", "source": { "type": "git", - "url": "https://github.com/stecman/symfony-console-completion.git", - "reference": "5461d43e53092b3d3b9dbd9d999f2054730f4bbb" + "url": "https://github.com/jcalderonzumba/MinkPhantomJSDriver.git", + "reference": "008f43670e94acd39273d15add1e7348eb23848d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stecman/symfony-console-completion/zipball/5461d43e53092b3d3b9dbd9d999f2054730f4bbb", - "reference": "5461d43e53092b3d3b9dbd9d999f2054730f4bbb", + "url": "https://api.github.com/repos/jcalderonzumba/MinkPhantomJSDriver/zipball/008f43670e94acd39273d15add1e7348eb23848d", + "reference": "008f43670e94acd39273d15add1e7348eb23848d", "shasum": "" }, "require": { - "php": ">=5.3.2", - "symfony/console": "~2.3 || ~3.0" + "behat/mink": "~1.7", + "jcalderonzumba/gastonjs": "~1.0", + "php": ">=5.4", + "twig/twig": "~1.20|~2.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "mink/driver-testsuite": "dev-master", + "phpunit/phpunit": "~4.6" }, - "time": "2016-02-24T05:08:54+00:00", - "type": "library", + "time": "2016-12-01T10:57:30+00:00", + "type": "mink-driver", "extra": { "branch-alias": { - "dev-master": "0.6.x-dev" + "dev-master": "0.4.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Stecman\\Component\\Symfony\\Console\\BashCompletion\\": "src/" + "Zumba\\Mink\\Driver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1776,87 +1602,132 @@ ], "authors": [ { - "name": "Stephen Holdaway", - "email": "stephen@stecman.co.nz" + "name": "Juan Francisco Calderón Zumba", + "email": "juanfcz@gmail.com", + "homepage": "http://github.com/jcalderonzumba" } ], - "description": "Automatic BASH completion for Symfony Console Component based applications." + "description": "PhantomJS driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "ajax", + "browser", + "headless", + "javascript", + "phantomjs", + "testing" + ] }, { - "name": "drupal/console-en", - "version": "1.0.0-rc16", - "version_normalized": "1.0.0.0-RC16", + "name": "mikey179/vfsStream", + "version": "v1.6.4", + "version_normalized": "1.6.4.0", "source": { "type": "git", - "url": "https://github.com/hechoendrupal/drupal-console-en.git", - "reference": "32c1e4c31500ba4ccd5e68bd74977fd6258c3e37" + "url": "https://github.com/mikey179/vfsStream.git", + "reference": "0247f57b2245e8ad2e689d7cee754b45fbabd592" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-en/zipball/32c1e4c31500ba4ccd5e68bd74977fd6258c3e37", - "reference": "32c1e4c31500ba4ccd5e68bd74977fd6258c3e37", + "url": "https://api.github.com/repos/mikey179/vfsStream/zipball/0247f57b2245e8ad2e689d7cee754b45fbabd592", + "reference": "0247f57b2245e8ad2e689d7cee754b45fbabd592", "shasum": "" }, - "time": "2017-02-09T16:02:27+00:00", - "type": "drupal-console-language", + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.5" + }, + "time": "2016-07-18T14:02:57+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, "installation-source": "dist", + "autoload": { + "psr-0": { + "org\\bovigo\\vfs\\": "src/main/php" + } + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "BSD-3-Clause" ], "authors": [ { - "name": "David Flores", - "email": "dmousex@gmail.com", - "homepage": "http://dmouse.net" - }, - { - "name": "Jesus Manuel Olivas", - "email": "jesus.olivas@gmail.com", - "homepage": "http://jmolivas.com" - }, - { - "name": "Drupal Console Contributors", - "homepage": "https://github.com/hechoendrupal/DrupalConsole/graphs/contributors" - }, - { - "name": "Eduardo Garcia", - "email": "enzo@enzolutions.com", - "homepage": "http://enzolutions.com/" - }, - { - "name": "Omar Aguirre", - "email": "omersguchigu@gmail.com" - } + "name": "Frank Kleine", + "homepage": "http://frankkleine.de/", + "role": "Developer" + } ], - "description": "Drupal Console English Language", - "homepage": "http://drupalconsole.com/", - "keywords": [ - "console", - "development", - "drupal", - "symfony" - ] + "description": "Virtual file system to mock the real file system in unit tests.", + "homepage": "http://vfs.bovigo.org/" }, { - "name": "dflydev/placeholder-resolver", - "version": "v1.0.2", - "version_normalized": "1.0.2.0", + "name": "sebastian/version", + "version": "1.0.6", + "version_normalized": "1.0.6.0", "source": { "type": "git", - "url": "https://github.com/dflydev/dflydev-placeholder-resolver.git", - "reference": "c498d0cae91b1bb36cc7d60906dab8e62bb7c356" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-placeholder-resolver/zipball/c498d0cae91b1bb36cc7d60906dab8e62bb7c356", - "reference": "c498d0cae91b1bb36cc7d60906dab8e62bb7c356", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "time": "2015-06-21T13:59:46+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": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "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.2" + "php": ">=5.3.3" }, - "time": "2012-10-28T21:08:28+00:00", + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "time": "2015-10-12T03:26:01+00:00", "type": "library", "extra": { "branch-alias": { @@ -1865,284 +1736,249 @@ }, "installation-source": "dist", "autoload": { - "psr-0": { - "Dflydev\\PlaceholderResolver": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Dragonfly Development Inc.", - "email": "info@dflydev.com", - "homepage": "http://dflydev.com" - }, - { - "name": "Beau Simensen", - "email": "beau@dflydev.com", - "homepage": "http://beausimensen.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Given a data source representing key => value pairs, resolve placeholders like ${foo.bar} to the value associated with the 'foo.bar' key in the data source.", - "homepage": "https://github.com/dflydev/dflydev-placeholder-resolver", + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ - "placeholder", - "resolver" + "global state" ] }, { - "name": "dflydev/dot-access-data", - "version": "v1.1.0", - "version_normalized": "1.1.0.0", + "name": "sebastian/exporter", + "version": "1.2.2", + "version_normalized": "1.2.2.0", "source": { "type": "git", - "url": "https://github.com/dflydev/dflydev-dot-access-data.git", - "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a" + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/3fbd874921ab2c041e899d044585a2ab9795df8a", - "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" }, - "time": "2017-01-20T21:14:22+00:00", + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "time": "2016-06-17T09:04:28+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.3.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-0": { - "Dflydev\\DotAccessData": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Dragonfly Development Inc.", - "email": "info@dflydev.com", - "homepage": "http://dflydev.com" + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" }, { - "name": "Beau Simensen", - "email": "beau@dflydev.com", - "homepage": "http://beausimensen.com" + "name": "Volker Dusch", + "email": "github@wallbash.com" }, { - "name": "Carlos Frutos", - "email": "carlos@kiwing.it", - "homepage": "https://github.com/cfrutos" + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Given a deep data structure, access data by dot notation.", - "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", "keywords": [ - "access", - "data", - "dot", - "notation" + "export", + "exporter" ] }, { - "name": "dflydev/dot-access-configuration", - "version": "v1.0.1", - "version_normalized": "1.0.1.0", + "name": "sebastian/environment", + "version": "1.3.8", + "version_normalized": "1.3.8.0", "source": { "type": "git", - "url": "https://github.com/dflydev/dflydev-dot-access-configuration.git", - "reference": "9b65c83159c9003e00284ea1144ad96b69d9c8b9" + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-configuration/zipball/9b65c83159c9003e00284ea1144ad96b69d9c8b9", - "reference": "9b65c83159c9003e00284ea1144ad96b69d9c8b9", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", "shasum": "" }, "require": { - "dflydev/dot-access-data": "1.*", - "dflydev/placeholder-resolver": "1.*", - "php": ">=5.3.2" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "symfony/yaml": "~2.1" - }, - "suggest": { - "symfony/yaml": "Required for using the YAML Configuration Builders" + "phpunit/phpunit": "^4.8 || ^5.0" }, - "time": "2014-11-14T03:26:12+00:00", + "time": "2016-08-18T05:49:44+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.3.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-0": { - "Dflydev\\DotAccessConfiguration": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Dragonfly Development Inc.", - "email": "info@dflydev.com", - "homepage": "http://dflydev.com" - }, - { - "name": "Beau Simensen", - "email": "beau@dflydev.com", - "homepage": "http://beausimensen.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Given a deep data structure representing a configuration, access configuration by dot notation.", - "homepage": "https://github.com/dflydev/dflydev-dot-access-configuration", + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ - "config", - "configuration" + "Xdebug", + "environment", + "hhvm" ] }, { - "name": "drupal/console-core", - "version": "1.0.0-rc16", - "version_normalized": "1.0.0.0-RC16", + "name": "sebastian/comparator", + "version": "1.2.4", + "version_normalized": "1.2.4.0", "source": { "type": "git", - "url": "https://github.com/hechoendrupal/drupal-console-core.git", - "reference": "42690f652b3a61d7d15fe9b785b946f3eb9227bf" + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-core/zipball/42690f652b3a61d7d15fe9b785b946f3eb9227bf", - "reference": "42690f652b3a61d7d15fe9b785b946f3eb9227bf", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", "shasum": "" }, "require": { - "dflydev/dot-access-configuration": "1.0.1", - "drupal/console-en": "1.0.0-rc16", - "php": "^5.5.9 || ^7.0", - "stecman/symfony-console-completion": "~0.7", - "symfony/config": ">=2.7 <3.0", - "symfony/console": ">=2.7 <3.0", - "symfony/debug": ">=2.6 <3.0", - "symfony/dependency-injection": ">=2.7 <3.0", - "symfony/event-dispatcher": ">=2.7 <3.0", - "symfony/filesystem": ">=2.7 <3.0", - "symfony/finder": ">=2.7 <3.0", - "symfony/process": ">=2.7 <3.0", - "symfony/translation": ">=2.7 <3.0", - "symfony/yaml": ">=2.7 <3.0", - "twig/twig": "^1.23.1", - "webflo/drupal-finder": "0.*" - }, - "time": "2017-02-09T18:22:32+00:00", - "type": "project", - "installation-source": "dist", - "autoload": { - "files": [ - "src/constants.php", - "src/functions.php" - ], - "psr-4": { - "Drupal\\Console\\Core\\": "src" - } + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "time": "2017-01-29T09:50:25+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "BSD-3-Clause" ], "authors": [ { - "name": "David Flores", - "email": "dmousex@gmail.com", - "homepage": "http://dmouse.net" - }, - { - "name": "Jesus Manuel Olivas", - "email": "jesus.olivas@gmail.com", - "homepage": "http://jmolivas.com" + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" }, { - "name": "Drupal Console Contributors", - "homepage": "https://github.com/hechoendrupal/DrupalConsole/graphs/contributors" + "name": "Volker Dusch", + "email": "github@wallbash.com" }, { - "name": "Eduardo Garcia", - "email": "enzo@enzolutions.com", - "homepage": "http://enzolutions.com/" + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" }, { - "name": "Omar Aguirre", - "email": "omersguchigu@gmail.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Drupal Console Core", - "homepage": "http://drupalconsole.com/", + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", "keywords": [ - "console", - "development", - "drupal", - "symfony" + "comparator", + "compare", + "equality" ] }, { - "name": "alchemy/zippy", - "version": "0.4.3", - "version_normalized": "0.4.3.0", + "name": "doctrine/instantiator", + "version": "1.0.5", + "version_normalized": "1.0.5.0", "source": { "type": "git", - "url": "https://github.com/alchemy-fr/Zippy.git", - "reference": "5ffdc93de0af2770d396bf433d8b2667c77277ea" + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/alchemy-fr/Zippy/zipball/5ffdc93de0af2770d396bf433d8b2667c77277ea", - "reference": "5ffdc93de0af2770d396bf433d8b2667c77277ea", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", "shasum": "" }, "require": { - "doctrine/collections": "~1.0", - "ext-mbstring": "*", - "php": ">=5.5", - "symfony/filesystem": "^2.0.5|^3.0", - "symfony/process": "^2.1|^3.0" + "php": ">=5.3,<8.0-DEV" }, "require-dev": { - "ext-zip": "*", - "guzzle/guzzle": "~3.0", - "guzzlehttp/guzzle": "^6.0", - "phpunit/phpunit": "^4.0|^5.0", - "symfony/finder": "^2.0.5|^3.0" - }, - "suggest": { - "ext-zip": "To use the ZipExtensionAdapter", - "guzzle/guzzle": "To use the GuzzleTeleporter with Guzzle 3", - "guzzlehttp/guzzle": "To use the GuzzleTeleporter with Guzzle 6" + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" }, - "time": "2016-11-03T16:10:31+00:00", + "time": "2015-06-14T21:17:01+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "0.4.x-dev" + "dev-master": "1.0.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Alchemy\\Zippy\\": "src/" + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2151,617 +1987,628 @@ ], "authors": [ { - "name": "Alchemy", - "email": "dev.team@alchemy.fr", - "homepage": "http://www.alchemy.fr/" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" } ], - "description": "Zippy, the archive manager companion", + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", "keywords": [ - "bzip", - "compression", - "tar", - "zip" + "constructor", + "instantiate" ] }, { - "name": "drupal/console", - "version": "1.0.0-rc16", - "version_normalized": "1.0.0.0-RC16", + "name": "phpunit/php-text-template", + "version": "1.2.1", + "version_normalized": "1.2.1.0", "source": { "type": "git", - "url": "https://github.com/hechoendrupal/drupal-console.git", - "reference": "955b057042635a5dc935799228ec7bbddf2c0cc2" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console/zipball/955b057042635a5dc935799228ec7bbddf2c0cc2", - "reference": "955b057042635a5dc935799228ec7bbddf2c0cc2", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "shasum": "" }, "require": { - "alchemy/zippy": "0.4.3", - "composer/installers": "~1.0", - "doctrine/annotations": "1.2.*", - "doctrine/collections": "1.3.0", - "drupal/console-core": "1.0.0-rc16", - "drupal/console-extend-plugin": "~0", - "gabordemooij/redbean": "~4.3", - "guzzlehttp/guzzle": "~6.1", - "php": "^5.5.9 || ^7.0", - "psy/psysh": "0.6.* || ~0.8", - "symfony/css-selector": ">=2.7 <3.0", - "symfony/dom-crawler": ">=2.7 <3.3", - "symfony/expression-language": ">=2.7 <3.0", - "symfony/http-foundation": ">=2.7 <3.0" + "php": ">=5.3.3" }, - "time": "2017-02-09T18:54:29+00:00", - "bin": [ - "bin/drupal" - ], - "type": "project", + "time": "2015-06-21T13:50:34+00:00", + "type": "library", "installation-source": "dist", "autoload": { - "psr-4": { - "Drupal\\Console\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "BSD-3-Clause" ], "authors": [ { - "name": "David Flores", - "email": "dmousex@gmail.com", - "homepage": "http://dmouse.net" - }, - { - "name": "Jesus Manuel Olivas", - "email": "jesus.olivas@gmail.com", - "homepage": "http://jmolivas.com" - }, - { - "name": "Drupal Console Contributors", - "homepage": "https://github.com/hechoendrupal/DrupalConsole/graphs/contributors" - }, - { - "name": "Eduardo Garcia", - "email": "enzo@enzolutions.com", - "homepage": "http://enzolutions.com/" - }, - { - "name": "Omar Aguirre", - "email": "omersguchigu@gmail.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "The Drupal CLI. A tool to generate boilerplate code, interact with and debug Drupal.", - "homepage": "http://drupalconsole.com/", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "console", - "development", - "drupal", - "symfony" + "template" ] }, { - "name": "fabpot/goutte", - "version": "v3.2.1", - "version_normalized": "3.2.1.0", + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.8", + "version_normalized": "2.3.8.0", "source": { "type": "git", - "url": "https://github.com/FriendsOfPHP/Goutte.git", - "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638" + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/db5c28f4a010b4161d507d5304e28a7ebf211638", - "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "^6.0", - "php": ">=5.5.0", - "symfony/browser-kit": "~2.1|~3.0", - "symfony/css-selector": "~2.1|~3.0", - "symfony/dom-crawler": "~2.1|~3.0" + "doctrine/instantiator": "^1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" }, - "time": "2017-01-03T13:21:43+00:00", - "type": "application", + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "suggest": { + "ext-soap": "*" + }, + "time": "2015-10-02T06:51:40+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "2.3.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Goutte\\": "Goutte" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" } ], - "description": "A simple PHP Web Scraper", - "homepage": "https://github.com/FriendsOfPHP/Goutte", + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", "keywords": [ - "scraper" + "mock", + "xunit" ] }, { - "name": "behat/mink", - "version": "v1.7.1", - "version_normalized": "1.7.1.0", + "name": "phpunit/php-timer", + "version": "1.0.9", + "version_normalized": "1.0.9.0", "source": { "type": "git", - "url": "https://github.com/minkphp/Mink.git", - "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9", - "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", "shasum": "" }, "require": { - "php": ">=5.3.1", - "symfony/css-selector": "~2.1|~3.0" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "symfony/phpunit-bridge": "~2.7|~3.0" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, - "suggest": { - "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", - "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation", - "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", - "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)" - }, - "time": "2016-03-05T08:26:18+00:00", + "time": "2017-02-26T11:10:40+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-master": "1.0-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Behat\\Mink\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" } ], - "description": "Browser controller/emulator abstraction for PHP", - "homepage": "http://mink.behat.org/", + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ - "browser", - "testing", - "web" + "timer" ] }, { - "name": "behat/mink-browserkit-driver", - "version": "v1.3.2", - "version_normalized": "1.3.2.0", + "name": "phpunit/php-file-iterator", + "version": "1.4.2", + "version_normalized": "1.4.2.0", "source": { "type": "git", - "url": "https://github.com/minkphp/MinkBrowserKitDriver.git", - "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb" + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/10e67fb4a295efcd62ea0bf16025a85ea19534fb", - "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", "shasum": "" }, "require": { - "behat/mink": "^1.7.1@dev", - "php": ">=5.3.6", - "symfony/browser-kit": "~2.3|~3.0", - "symfony/dom-crawler": "~2.3|~3.0" - }, - "require-dev": { - "silex/silex": "~1.2", - "symfony/phpunit-bridge": "~2.7|~3.0" + "php": ">=5.3.3" }, - "time": "2016-03-05T08:59:47+00:00", - "type": "mink-driver", + "time": "2016-10-03T07:40:28+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "1.4.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Behat\\Mink\\Driver\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" } ], - "description": "Symfony2 BrowserKit driver for Mink framework", - "homepage": "http://mink.behat.org/", + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ - "Mink", - "Symfony2", - "browser", - "testing" + "filesystem", + "iterator" ] }, { - "name": "behat/mink-goutte-driver", - "version": "v1.2.1", - "version_normalized": "1.2.1.0", + "name": "phpunit/php-token-stream", + "version": "1.4.11", + "version_normalized": "1.4.11.0", "source": { "type": "git", - "url": "https://github.com/minkphp/MinkGoutteDriver.git", - "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca" + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", - "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", "shasum": "" }, "require": { - "behat/mink": "~1.6@dev", - "behat/mink-browserkit-driver": "~1.2@dev", - "fabpot/goutte": "~1.0.4|~2.0|~3.1", - "php": ">=5.3.1" + "ext-tokenizer": "*", + "php": ">=5.3.3" }, "require-dev": { - "symfony/phpunit-bridge": "~2.7|~3.0" + "phpunit/phpunit": "~4.2" }, - "time": "2016-03-05T09:04:22+00:00", - "type": "mink-driver", + "time": "2017-02-27T10:12:30+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.4-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Behat\\Mink\\Driver\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Goutte driver for Mink framework", - "homepage": "http://mink.behat.org/", + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", "keywords": [ - "browser", - "goutte", - "headless", - "testing" + "tokenizer" ] }, { - "name": "jcalderonzumba/gastonjs", - "version": "v1.0.3", - "version_normalized": "1.0.3.0", + "name": "phpunit/php-code-coverage", + "version": "2.2.4", + "version_normalized": "2.2.4.0", "source": { "type": "git", - "url": "https://github.com/jcalderonzumba/gastonjs.git", - "reference": "4ff4a788d4995ae0d4b45fdcb1b76650e2eec72a" + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jcalderonzumba/gastonjs/zipball/4ff4a788d4995ae0d4b45fdcb1b76650e2eec72a", - "reference": "4ff4a788d4995ae0d4b45fdcb1b76650e2eec72a", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "~5.0|~6.0", - "php": ">=5.4" + "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": { - "phpunit/phpunit": "~4.6", - "silex/silex": "~1.2", - "symfony/phpunit-bridge": "~2.7", - "symfony/process": "~2.1" + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" }, - "time": "2016-05-04T16:27:07+00:00", - "type": "phantomjs-api", + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "time": "2015-10-06T15:47:00+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.2.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Zumba\\GastonJS\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Juan Francisco Calderón Zumba", - "email": "juanfcz@gmail.com", - "homepage": "http://github.com/jcalderonzumba" + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" } ], - "description": "PhantomJS API based server for webpage automation", - "homepage": "https://github.com/jcalderonzumba/gastonjs", + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ - "api", - "automation", - "browser", - "headless", - "phantomjs" + "coverage", + "testing", + "xunit" ] }, { - "name": "jcalderonzumba/mink-phantomjs-driver", - "version": "v0.3.3", - "version_normalized": "0.3.3.0", + "name": "drupal/migrate_upgrade", + "version": "3.0.0-rc1", + "version_normalized": "3.0.0.0-RC1", "source": { "type": "git", - "url": "https://github.com/jcalderonzumba/MinkPhantomJSDriver.git", - "reference": "008f43670e94acd39273d15add1e7348eb23848d" + "url": "https://git.drupal.org/project/migrate_upgrade", + "reference": "8.x-3.0-rc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jcalderonzumba/MinkPhantomJSDriver/zipball/008f43670e94acd39273d15add1e7348eb23848d", - "reference": "008f43670e94acd39273d15add1e7348eb23848d", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/migrate_upgrade-8.x-3.0-rc1.zip", + "reference": "8.x-3.0-rc1", + "shasum": "0141d36fb99b166c5e114b946b140780489620e3" }, "require": { - "behat/mink": "~1.7", - "jcalderonzumba/gastonjs": "~1.0", - "php": ">=5.4", - "twig/twig": "~1.20|~2.0" - }, - "require-dev": { - "mink/driver-testsuite": "dev-master", - "phpunit/phpunit": "~4.6" + "drupal/core": "*", + "drupal/migrate_plus": "*" }, - "time": "2016-12-01T10:57:30+00:00", - "type": "mink-driver", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "0.4.x-dev" + "dev-3.x": "3.x-dev" + }, + "drupal": { + "version": "8.x-3.0-rc1", + "datestamp": "1476200639" } }, "installation-source": "dist", - "autoload": { - "psr-4": { - "Zumba\\Mink\\Driver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Juan Francisco Calderón Zumba", - "email": "juanfcz@gmail.com", - "homepage": "http://github.com/jcalderonzumba" - } - ], - "description": "PhantomJS driver for Mink framework", - "homepage": "http://mink.behat.org/", - "keywords": [ - "ajax", - "browser", - "headless", - "javascript", - "phantomjs", - "testing" - ] - }, - { - "name": "mikey179/vfsStream", - "version": "v1.6.4", - "version_normalized": "1.6.4.0", + "name": "Ryan Weal", + "homepage": "https://www.drupal.org/user/412402" + }, + { + "name": "abhishek-anand", + "homepage": "https://www.drupal.org/user/468982" + }, + { + "name": "ksenzee", + "homepage": "https://www.drupal.org/user/139855" + }, + { + "name": "mikeryan", + "homepage": "https://www.drupal.org/user/4420" + }, + { + "name": "ultimike", + "homepage": "https://www.drupal.org/user/51132" + }, + { + "name": "xjm", + "homepage": "https://www.drupal.org/user/65776" + } + ], + "description": "Drush support for direct upgrades from older Drupal versions.", + "homepage": "https://www.drupal.org/project/migrate_upgrade", + "support": { + "source": "http://cgit.drupalcode.org/migrate_upgrade" + } + }, + { + "name": "drupal/migrate_tools", + "version": "3.0.0-beta1", + "version_normalized": "3.0.0.0-beta1", "source": { "type": "git", - "url": "https://github.com/mikey179/vfsStream.git", - "reference": "0247f57b2245e8ad2e689d7cee754b45fbabd592" + "url": "https://git.drupal.org/project/migrate_tools", + "reference": "8.x-3.0-beta1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mikey179/vfsStream/zipball/0247f57b2245e8ad2e689d7cee754b45fbabd592", - "reference": "0247f57b2245e8ad2e689d7cee754b45fbabd592", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/migrate_tools-8.x-3.0-beta1.zip", + "reference": "8.x-3.0-beta1", + "shasum": "1511d1da1444743fa2defa54a17e62264e8ab836" }, "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.5" + "drupal/core": "^8.2", + "drupal/migrate_plus": "*" }, - "time": "2016-07-18T14:02:57+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-3.x": "3.x-dev" + }, + "drupal": { + "version": "8.x-3.0-beta1", + "datestamp": "1476313439" } }, "installation-source": "dist", - "autoload": { - "psr-0": { - "org\\bovigo\\vfs\\": "src/main/php" - } - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Frank Kleine", - "homepage": "http://frankkleine.de/", - "role": "Developer" + "name": "mikeryan", + "homepage": "https://www.drupal.org/user/4420" } ], - "description": "Virtual file system to mock the real file system in unit tests.", - "homepage": "http://vfs.bovigo.org/" + "description": "Tools to assist in developing and running migrations.", + "homepage": "https://www.drupal.org/project/migrate_tools", + "support": { + "source": "http://cgit.drupalcode.org/migrate_tools" + } }, { - "name": "sebastian/version", - "version": "1.0.6", - "version_normalized": "1.0.6.0", + "name": "drupal/eu_cookie_compliance", + "version": "1.0.0-beta7", + "version_normalized": "1.0.0.0-beta7", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + "url": "https://git.drupal.org/project/eu-cookie-compliance", + "reference": "8.x-1.0-beta7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/eu_cookie_compliance-8.x-1.0-beta7.zip", + "reference": "8.x-1.0-beta7", + "shasum": "c8859fbeb5f6b1122c0eb6c5df1c4cd4b2961421" }, - "time": "2015-06-21T13:59:46+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] + "require": { + "drupal/core": "*" }, - "notification-url": "https://packagist.org/downloads/", + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0-beta7", + "datestamp": "1471263146" + } + }, + "installation-source": "dist", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Marcin Pajdzik", + "homepage": "https://www.drupal.org/user/160555" + }, + { + "name": "achton", + "homepage": "https://www.drupal.org/user/712454" + }, + { + "name": "blairski", + "homepage": "https://www.drupal.org/user/120835" + }, + { + "name": "dakku", + "homepage": "https://www.drupal.org/user/97634" + }, + { + "name": "grzegorz.bartman", + "homepage": "https://www.drupal.org/user/363120" + }, + { + "name": "id.tornado", + "homepage": "https://www.drupal.org/user/2754049" + }, + { + "name": "killua99", + "homepage": "https://www.drupal.org/user/699418" + }, + { + "name": "mibfire", + "homepage": "https://www.drupal.org/user/155136" + }, + { + "name": "naveenvalecha", + "homepage": "https://www.drupal.org/user/2665733" + }, + { + "name": "svenryen", + "homepage": "https://www.drupal.org/user/667244" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version" + "description": "This module aims at making the website compliant with the new EU cookie regulation", + "homepage": "https://www.drupal.org/project/eu_cookie_compliance", + "support": { + "source": "http://cgit.drupalcode.org/eu_cookie_compliance" + } }, { - "name": "sebastian/global-state", - "version": "1.1.1", - "version_normalized": "1.1.1.0", + "name": "guzzlehttp/guzzle", + "version": "6.2.3", + "version_normalized": "6.2.3.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + "url": "https://github.com/guzzle/guzzle.git", + "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006", + "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006", "shasum": "" }, "require": { - "php": ">=5.3.3" + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" + "ext-curl": "*", + "phpunit/phpunit": "^4.0", + "psr/log": "^1.0" }, - "time": "2015-10-12T03:26:01+00:00", + "time": "2017-02-28T22:50:30+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "6.2-dev" } }, "installation-source": "dist", "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" } ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", "keywords": [ - "global state" + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" ] }, { - "name": "sebastian/exporter", - "version": "1.2.2", - "version_normalized": "1.2.2.0", + "name": "nikic/php-parser", + "version": "v3.0.5", + "version_normalized": "3.0.5.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "2b9e2f71b722f7c53918ab0c25f7646c2013f17d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2b9e2f71b722f7c53918ab0c25f7646c2013f17d", + "reference": "2b9e2f71b722f7c53918ab0c25f7646c2013f17d", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" + "ext-tokenizer": "*", + "php": ">=5.5" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "~4.0|~5.0" }, - "time": "2016-06-17T09:04:28+00:00", + "time": "2017-03-05T18:23:57+00:00", + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "3.0-dev" } }, "installation-source": "dist", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2769,59 +2616,41 @@ ], "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" + "name": "Nikita Popov" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "description": "A PHP parser written in PHP", "keywords": [ - "export", - "exporter" + "parser", + "php" ] }, { - "name": "sebastian/environment", - "version": "1.3.8", - "version_normalized": "1.3.8.0", + "name": "sebastian/recursion-context", + "version": "1.0.5", + "version_normalized": "1.0.5.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" + "phpunit/phpunit": "~4.4" }, - "time": "2016-08-18T05:49:44+00:00", + "time": "2016-10-03T07:41:43+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "1.0.x-dev" } }, "installation-source": "dist", @@ -2835,774 +2664,696 @@ "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 handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ] + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context" }, { - "name": "sebastian/diff", - "version": "1.4.1", - "version_normalized": "1.4.1.0", + "name": "phpspec/prophecy", + "version": "v1.7.0", + "version_normalized": "1.7.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + "url": "https://github.com/phpspec/prophecy.git", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", "shasum": "" }, "require": { - "php": ">=5.3.3" + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8 || ^5.6.5" }, - "time": "2015-12-08T07:14:41+00:00", + "time": "2017-03-02T20:05:34+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.6.x-dev" } }, "installation-source": "dist", "autoload": { - "classmap": [ - "src/" - ] + "psr-0": { + "Prophecy\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", "keywords": [ - "diff" + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" ] }, { - "name": "sebastian/comparator", - "version": "1.2.4", - "version_normalized": "1.2.4.0", + "name": "twbs/bootstrap-sass", + "version": "v3.3.7", + "version_normalized": "3.3.7.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + "url": "https://github.com/twbs/bootstrap-sass.git", + "reference": "5d6b2ebba0c2a5885ce2f0e01e9218db3d3b5e47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "url": "https://api.github.com/repos/twbs/bootstrap-sass/zipball/5d6b2ebba0c2a5885ce2f0e01e9218db3d3b5e47", + "reference": "5d6b2ebba0c2a5885ce2f0e01e9218db3d3b5e47", "shasum": "" }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "time": "2017-01-29T09:50:25+00:00", + "time": "2016-07-25T19:58:53+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "3.3.x-dev" } }, "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Mark Otto" }, { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "name": "Thomas McDonald" }, { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" + "name": "Tristan Harward" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Peter Gumeson" + }, + { + "name": "Gleb Mazovetskiy" + }, + { + "name": "Jacob Thornton" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", + "description": "bootstrap-sass is a Sass-powered version of Bootstrap 3, ready to drop right into your Sass powered applications.", + "homepage": "http://github.com/twbs/bootstrap-sass", "keywords": [ - "comparator", - "compare", - "equality" + "bootstrap", + "css", + "sass" ] }, { - "name": "doctrine/instantiator", - "version": "1.0.5", - "version_normalized": "1.0.5.0", + "name": "drupal/paragraphs", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "url": "https://git.drupal.org/project/paragraphs", + "reference": "8.x-1.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/paragraphs-8.x-1.1.zip", + "reference": "8.x-1.1", + "shasum": "c678e5704a98c6a0549e415412da081cfeb03a00" }, "require": { - "php": ">=5.3,<8.0-DEV" + "drupal/core": "~8.0", + "drupal/entity_reference_revisions": "*" }, "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "drupal/diff": "*", + "drupal/field_group": "*", + "drupal/inline_entity_form": "*", + "drupal/replicate": "*", + "drupal/search_api": "*", + "drupal/search_api_db": "*" }, - "time": "2015-06-14T21:17:01+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.1", + "datestamp": "1487331784" } }, "installation-source": "dist", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "name": "Berdir", + "homepage": "https://www.drupal.org/user/214652" + }, + { + "name": "Frans", + "homepage": "https://www.drupal.org/user/514222" + }, + { + "name": "Primsi", + "homepage": "https://www.drupal.org/user/282629" + }, + { + "name": "jeroen.b", + "homepage": "https://www.drupal.org/user/1853532" + }, + { + "name": "miro_dietiker", + "homepage": "https://www.drupal.org/user/227761" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ] + "description": "Enables the creation of paragraphs entities.", + "homepage": "https://www.drupal.org/project/paragraphs", + "support": { + "source": "http://cgit.drupalcode.org/paragraphs" + } }, { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "version_normalized": "1.2.1.0", + "name": "drupal/livereload", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "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": "" + "url": "https://git.drupal.org/project/livereload", + "reference": "223feb798d2af436818c3d8fd0b47718569ebd4b" }, "require": { - "php": ">=5.3.3" + "drupal/core": "~8.0" }, - "time": "2015-06-21T13:50:34+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.x-dev", + "datestamp": "1474009739" + } }, - "notification-url": "https://packagist.org/downloads/", + "installation-source": "source", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Hydra", + "homepage": "https://www.drupal.org/user/647364" + }, + { + "name": "tim.plunkett", + "homepage": "https://www.drupal.org/user/241634" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ] + "description": "Enables and enhances use of LiveReload during development.", + "homepage": "https://www.drupal.org/project/livereload", + "support": { + "source": "http://cgit.drupalcode.org/livereload" + } }, { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", - "version_normalized": "2.3.8.0", + "name": "drupal/front", + "version": "1.0.0-alpha2", + "version_normalized": "1.0.0.0-alpha2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + "url": "https://git.drupal.org/project/front", + "reference": "8.x-1.0-alpha2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/front-8.x-1.0-alpha2.zip", + "reference": "8.x-1.0-alpha2", + "shasum": "d4381a4fea8ebdf50575a2b443094612b0ff1eb0" }, "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": "*" + "drupal/core": "~8.0" }, - "time": "2015-10-02T06:51:40+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "2.3.x-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0-alpha2", + "datestamp": "1487686982" } }, "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" + "name": "Dublin Drupaller", + "homepage": "https://www.drupal.org/user/8625" + }, + { + "name": "Simon Georges", + "homepage": "https://www.drupal.org/user/172312" + }, + { + "name": "asenenko", + "homepage": "https://www.drupal.org/user/2641733" + }, + { + "name": "estoyausente", + "homepage": "https://www.drupal.org/user/1232954" + }, + { + "name": "timhilliard", + "homepage": "https://www.drupal.org/user/195493" } ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ] + "homepage": "https://www.drupal.org/project/front", + "support": { + "source": "http://cgit.drupalcode.org/front" + } }, { - "name": "phpunit/php-timer", - "version": "1.0.9", - "version_normalized": "1.0.9.0", + "name": "drupal/filefield_sources", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" + "url": "https://git.drupal.org/project/filefield_sources", + "reference": "b19c6a839804f47587828d4a50e29e0720fa4c08" }, "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "drupal/core": "*" }, - "time": "2017-02-26T11:10:40+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.x-dev", + "datestamp": "1464990539" } }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "installation-source": "source", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" + "name": "profak", + "homepage": "https://www.drupal.org/user/782534" + }, + { + "name": "quicksketch", + "homepage": "https://www.drupal.org/user/35821" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ] + "description": "Extends File fields to allow referencing of existing files, remote files, and server files.", + "homepage": "https://www.drupal.org/project/filefield_sources", + "support": { + "source": "http://cgit.drupalcode.org/filefield_sources" + } }, { - "name": "phpunit/php-file-iterator", - "version": "1.4.2", - "version_normalized": "1.4.2.0", + "name": "drupal/environment_indicator", + "version": "3.0.0", + "version_normalized": "3.0.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + "url": "https://git.drupal.org/project/environment_indicator", + "reference": "8.x-3.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/environment_indicator-8.x-3.0.zip", + "reference": "8.x-3.0", + "shasum": "eb435b390f07e228eb55638630c6b5b9fb3e104e" }, "require": { - "php": ">=5.3.3" + "drupal/core": "*" }, - "time": "2016-10-03T07:40:28+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-3.x": "3.x-dev" + }, + "drupal": { + "version": "8.x-3.0", + "datestamp": "1487828585" } }, "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" + "name": "e0ipso", + "homepage": "https://www.drupal.org/user/550110" + }, + { + "name": "mrfelton", + "homepage": "https://www.drupal.org/user/305669" } ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ] + "description": "Adds a color indicator for the different environments.", + "homepage": "https://www.drupal.org/project/environment_indicator", + "support": { + "source": "http://cgit.drupalcode.org/environment_indicator" + } }, { - "name": "phpunit/php-token-stream", - "version": "1.4.11", - "version_normalized": "1.4.11.0", + "name": "drupal/pathologic", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", - "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", - "shasum": "" + "url": "https://git.drupal.org/project/pathologic", + "reference": "4f9f3fdcf1e0b224c4d8650e383a769f40abf9bf" }, "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" + "drupal/core": "*" }, - "time": "2017-02-27T10:12:30+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.x-dev", + "datestamp": "1494720785" } }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "installation-source": "source", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Berdir", + "homepage": "https://www.drupal.org/user/214652" + }, + { + "name": "Garrett Albright", + "homepage": "https://www.drupal.org/user/191212" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ] + "description": "Helps avoid broken links and incorrect paths in content.", + "homepage": "https://www.drupal.org/project/pathologic", + "support": { + "source": "http://cgit.drupalcode.org/pathologic" + } }, { - "name": "phpunit/php-code-coverage", - "version": "2.2.4", - "version_normalized": "2.2.4.0", + "name": "drupal/typogrify", + "version": "1.0.0-alpha1", + "version_normalized": "1.0.0.0-alpha1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + "url": "https://git.drupal.org/project/typogrify", + "reference": "8.x-1.0-alpha1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/typogrify-8.x-1.0-alpha1.zip", + "reference": "8.x-1.0-alpha1", + "shasum": "de87791555204b3af5692d939f8c199bd7164495" }, "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": "*" + "drupal/core": "*" }, - "time": "2015-10-06T15:47:00+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "2.2.x-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0-alpha1", + "datestamp": "1478050442" } }, "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" + "name": "See contributors", + "homepage": "https://www.drupal.org/node/149970/committers", + "role": "Developer" + }, + { + "name": "migmedia", + "homepage": "https://www.drupal.org/user/1310354" + }, + { + "name": "mikl", + "homepage": "https://www.drupal.org/user/58679" + }, + { + "name": "sreynen", + "homepage": "https://www.drupal.org/user/109890" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "description": "A filter for making typographic refinements.", + "homepage": "http://drupal.org/project/typogrify", "keywords": [ - "coverage", - "testing", - "xunit" - ] + "Drupal" + ], + "support": { + "source": "http://cgit.drupalcode.org/typogrify", + "issues": "http://drupal.org/project/typogrify" + } }, { - "name": "phpunit/phpunit", - "version": "4.8.35", - "version_normalized": "4.8.35.0", + "name": "drupal/entityqueue", + "version": "1.0.0-alpha6", + "version_normalized": "1.0.0.0-alpha6", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87" + "url": "https://git.drupal.org/project/entityqueue", + "reference": "8.x-1.0-alpha6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/791b1a67c25af50e230f841ee7a9c6eba507dc87", - "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/entityqueue-8.x-1.0-alpha6.zip", + "reference": "8.x-1.0-alpha6", + "shasum": "2f7c639020a4c688b419ca90e35ffe0d08b34639" }, "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.2.2", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" + "drupal/core": "~8.0" }, - "time": "2017-02-06T05:18:07+00:00", - "bin": [ - "phpunit" - ], - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "4.8.x-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0-alpha6", + "datestamp": "1481985783" } }, "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "amateescu", + "homepage": "https://www.drupal.org/user/729614" + }, + { + "name": "jojonaloha", + "homepage": "https://www.drupal.org/user/1579186" + }, + { + "name": "tim.plunkett", + "homepage": "https://www.drupal.org/user/241634" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ] + "description": "Allows users to collect entities in arbitrarily ordered lists.", + "homepage": "https://www.drupal.org/project/entityqueue", + "support": { + "source": "http://cgit.drupalcode.org/entityqueue" + } }, { - "name": "drupal/migrate_plus", - "version": "3.0.0-beta1", - "version_normalized": "3.0.0.0-beta1", + "name": "michelf/php-markdown", + "version": "1.7.0", + "version_normalized": "1.7.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/migrate_plus", - "reference": "8.x-3.0-beta1" + "url": "https://github.com/michelf/php-markdown.git", + "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/migrate_plus-8.x-3.0-beta1.zip", - "reference": "8.x-3.0-beta1", - "shasum": "7bae5c758a432053863b7b19c94fc1b829debf00" + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/1f51cc520948f66cd2af8cbc45a5ee175e774220", + "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220", + "shasum": "" }, "require": { - "drupal/core": "^8.2" - }, - "require-dev": { - "drupal/migrate_example_advanced_setup": "*", - "drupal/migrate_example_setup": "*" - }, - "suggest": { - "sainsburys/guzzle-oauth2-plugin": "3.0 required for the OAuth2 authentication plugin" + "php": ">=5.3.0" }, - "type": "drupal-module", + "time": "2016-10-29T18:58:20+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev" - }, - "drupal": { - "version": "8.x-3.0-beta1", - "datestamp": "1476307739" + "dev-lib": "1.4.x-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-0": { + "Michelf": "" + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike Ryan", - "homepage": "https://www.drupal.org/u/mikeryan", - "role": "Maintainer" + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" } ], - "description": "Enhancements to core migration support.", - "homepage": "https://www.drupal.org/project/migrate_plus", - "support": { - "source": "https://cgit.drupalcode.org/migrate_plus", - "issues": "https://www.drupal.org/project/issues/migrate_plus", - "irc": "irc://irc.freenode.org/drupal-migrate" - } + "description": "PHP Markdown", + "homepage": "https://michelf.ca/projects/php-markdown/", + "keywords": [ + "markdown" + ] }, { - "name": "drupal/migrate_upgrade", - "version": "3.0.0-rc1", - "version_normalized": "3.0.0.0-RC1", + "name": "drupal/advanced_help", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://git.drupal.org/project/migrate_upgrade", - "reference": "8.x-3.0-rc1" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/migrate_upgrade-8.x-3.0-rc1.zip", - "reference": "8.x-3.0-rc1", - "shasum": "0141d36fb99b166c5e114b946b140780489620e3" + "url": "https://git.drupal.org/project/advanced_help", + "reference": "ed80f440c8bb0c3c5b1868f3429f296e52c841a6" }, "require": { - "drupal/core": "*", - "drupal/migrate_plus": "*" + "drupal/core": "~8.0", + "michelf/php-markdown": "^1.7" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev" + "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-3.0-rc1", - "datestamp": "1476200639" + "version": "8.x-1.x-dev", + "datestamp": "1490703369" } }, - "installation-source": "dist", + "installation-source": "source", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Ryan Weal", - "homepage": "https://www.drupal.org/user/412402" + "name": "David Valdez (gnuget)", + "homepage": "https://www.drupal.org/u/gnuget", + "role": "Maintainer" }, { - "name": "abhishek-anand", - "homepage": "https://www.drupal.org/user/468982" + "name": "dmitrig01", + "homepage": "https://www.drupal.org/user/47566" }, { - "name": "ksenzee", - "homepage": "https://www.drupal.org/user/139855" + "name": "fgm", + "homepage": "https://www.drupal.org/user/27985" }, { - "name": "mikeryan", - "homepage": "https://www.drupal.org/user/4420" + "name": "gisle", + "homepage": "https://www.drupal.org/user/409554" }, { - "name": "ultimike", - "homepage": "https://www.drupal.org/user/51132" + "name": "gnuget", + "homepage": "https://www.drupal.org/user/992990" }, { - "name": "xjm", - "homepage": "https://www.drupal.org/user/65776" - } - ], - "description": "Drush support for direct upgrades from older Drupal versions.", - "homepage": "https://www.drupal.org/project/migrate_upgrade", - "support": { - "source": "http://cgit.drupalcode.org/migrate_upgrade" - } - }, - { - "name": "drupal/migrate_tools", - "version": "3.0.0-beta1", - "version_normalized": "3.0.0.0-beta1", - "source": { - "type": "git", - "url": "https://git.drupal.org/project/migrate_tools", - "reference": "8.x-3.0-beta1" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/migrate_tools-8.x-3.0-beta1.zip", - "reference": "8.x-3.0-beta1", - "shasum": "1511d1da1444743fa2defa54a17e62264e8ab836" - }, - "require": { - "drupal/core": "^8.2", - "drupal/migrate_plus": "*" - }, - "type": "drupal-module", - "extra": { - "branch-alias": { - "dev-3.x": "3.x-dev" + "name": "merlinofchaos", + "homepage": "https://www.drupal.org/user/26979" }, - "drupal": { - "version": "8.x-3.0-beta1", - "datestamp": "1476313439" - } - }, - "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", - "license": [ - "GPL-2.0+" - ], - "authors": [ { - "name": "mikeryan", - "homepage": "https://www.drupal.org/user/4420" + "name": "redndahead", + "homepage": "https://www.drupal.org/user/160320" } ], - "description": "Tools to assist in developing and running migrations.", - "homepage": "https://www.drupal.org/project/migrate_tools", + "description": "Provide extended help and documentation.", + "homepage": "https://www.drupal.org/project/advanced_help", "support": { - "source": "http://cgit.drupalcode.org/migrate_tools" + "source": "https://cgit.drupalcode.org/advanced_help", + "issues": "https://www.drupal.org/project/issues/advanced_help", + "irc": "irc://irc.freenode.org/drupal-contribute" } }, { - "name": "drupal/metatag", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "name": "drupal/better_formats", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://git.drupal.org/project/metatag", - "reference": "8.x-1.0" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/metatag-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "604e45e89c19f5a8960b6a8ae3d80500d4328e6b" + "url": "https://git.drupal.org/project/better_formats", + "reference": "9b3b5fa792c1dfe0d1121021a230086f3599b7e4" }, "require": { - "drupal/core": "*", - "drupal/token": "*" - }, - "require-dev": { - "drupal/metatag_dc": "*", - "drupal/metatag_open_graph": "*" + "drupal/core": "~8.0" }, "type": "drupal-module", "extra": { @@ -3610,51 +3361,45 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1485902197" + "version": "8.x-1.x-dev", + "datestamp": "1474656839" } }, - "installation-source": "dist", + "installation-source": "source", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "See contributors", - "homepage": "https://www.drupal.org/node/640498/committers", - "role": "Developer" + "name": "Devin Carlson", + "homepage": "https://www.drupal.org/user/290182" }, { - "name": "Dave Reid", - "homepage": "https://www.drupal.org/user/53892" + "name": "dragonwize", + "homepage": "https://www.drupal.org/user/137882" } ], - "description": "Manage meta tags for all entities.", - "homepage": "https://www.drupal.org/project/metatag", - "keywords": [ - "php", - "seo" - ], + "description": "Enhances the core input format system by managing input format defaults and settings.", + "homepage": "https://www.drupal.org/project/better_formats", "support": { - "source": "http://cgit.drupalcode.org/metatag", - "issues": "http://drupal.org/project/issues/metatag" + "source": "http://cgit.drupalcode.org/better_formats" } }, { - "name": "drupal/eu_cookie_compliance", - "version": "1.0.0-beta7", - "version_normalized": "1.0.0.0-beta7", + "name": "drupal/block_class", + "version": "1.0.0-alpha1", + "version_normalized": "1.0.0.0-alpha1", "source": { "type": "git", - "url": "https://git.drupal.org/project/eu-cookie-compliance", - "reference": "8.x-1.0-beta7" + "url": "https://git.drupal.org/project/block_class", + "reference": "8.x-1.0-alpha1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/eu_cookie_compliance-8.x-1.0-beta7.zip", - "reference": "8.x-1.0-beta7", - "shasum": "c8859fbeb5f6b1122c0eb6c5df1c4cd4b2961421" + "url": "https://ftp.drupal.org/files/projects/block_class-8.x-1.0-alpha1.zip", + "reference": "8.x-1.0-alpha1", + "shasum": "194cd52210ea2e0e5dbbd34fad4528d500424430" }, "require": { "drupal/core": "*" @@ -3665,8 +3410,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-beta7", - "datestamp": "1471263146" + "version": "8.x-1.0-alpha1", + "datestamp": "1475623439" } }, "installation-source": "dist", @@ -3676,261 +3421,250 @@ ], "authors": [ { - "name": "Marcin Pajdzik", - "homepage": "https://www.drupal.org/user/160555" + "name": "Aaron Stanush", + "homepage": "https://www.drupal.org/user/89718" }, { - "name": "achton", - "homepage": "https://www.drupal.org/user/712454" + "name": "DYdave", + "homepage": "https://www.drupal.org/user/467284" }, { - "name": "blairski", - "homepage": "https://www.drupal.org/user/120835" + "name": "Four Kitchens", + "homepage": "https://www.drupal.org/user/358502" }, { - "name": "dakku", - "homepage": "https://www.drupal.org/user/97634" + "name": "Todd Nienkerk", + "homepage": "https://www.drupal.org/user/92096" }, { - "name": "grzegorz.bartman", - "homepage": "https://www.drupal.org/user/363120" + "name": "berenddeboer", + "homepage": "https://www.drupal.org/user/143552" }, { - "name": "id.tornado", - "homepage": "https://www.drupal.org/user/2754049" + "name": "elliotttf", + "homepage": "https://www.drupal.org/user/61601" }, { - "name": "killua99", - "homepage": "https://www.drupal.org/user/699418" + "name": "mirzu", + "homepage": "https://www.drupal.org/user/7710" }, { - "name": "mibfire", - "homepage": "https://www.drupal.org/user/155136" + "name": "patrickcoffeyo", + "homepage": "https://www.drupal.org/user/2837945" }, { - "name": "naveenvalecha", - "homepage": "https://www.drupal.org/user/2665733" + "name": "pcoffey", + "homepage": "https://www.drupal.org/user/1595818" }, { - "name": "svenryen", - "homepage": "https://www.drupal.org/user/667244" + "name": "tsmith512", + "homepage": "https://www.drupal.org/user/2031446" } ], - "description": "This module aims at making the website compliant with the new EU cookie regulation", - "homepage": "https://www.drupal.org/project/eu_cookie_compliance", + "description": "Allows assigning classes to Blocks", + "homepage": "https://www.drupal.org/project/block_class", "support": { - "source": "http://cgit.drupalcode.org/eu_cookie_compliance" + "source": "http://cgit.drupalcode.org/block_class" } }, { - "name": "guzzlehttp/guzzle", - "version": "6.2.3", - "version_normalized": "6.2.3.0", + "name": "drupal/libraries", + "version": "dev-3.x", + "version_normalized": "dev-3.x", "source": { "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006", - "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006", - "shasum": "" + "url": "https://git.drupal.org/project/libraries", + "reference": "061ead081c92a6209b09eaf23b4e3103f360946e" }, "require": { - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4", - "php": ">=5.5" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "^4.0", - "psr/log": "^1.0" + "drupal/core": "~8.0" }, - "time": "2017-02-28T22:50:30+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "6.2-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" + "dev-3.x": "3.x-dev" + }, + "drupal": { + "version": "8.x-3.x-dev", + "datestamp": "1487978583" } }, - "notification-url": "https://packagist.org/downloads/", + "installation-source": "source", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" + "name": "Pol", + "homepage": "https://www.drupal.org/user/47194" + }, + { + "name": "rjacobs", + "homepage": "https://www.drupal.org/user/422459" + }, + { + "name": "sun", + "homepage": "https://www.drupal.org/user/54136" + }, + { + "name": "tstoeckler", + "homepage": "https://www.drupal.org/user/107158" } ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ] + "description": "Allows version-dependent and shared usage of external libraries in Drupal.", + "homepage": "http://drupal.org/project/libraries", + "support": { + "source": "http://cgit.drupalcode.org/libraries", + "issues": "http://drupal.org/project/issues/libraries", + "irc": "irc://irc.freenode.org/drupal-contribute" + } }, { - "name": "nikic/php-parser", - "version": "v3.0.5", - "version_normalized": "3.0.5.0", + "name": "drupal/linkchecker", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "2b9e2f71b722f7c53918ab0c25f7646c2013f17d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2b9e2f71b722f7c53918ab0c25f7646c2013f17d", - "reference": "2b9e2f71b722f7c53918ab0c25f7646c2013f17d", - "shasum": "" + "url": "https://git.drupal.org/project/linkchecker", + "reference": "51377136199d15d6e0ca36339f68934c4eb19204" }, "require": { - "ext-tokenizer": "*", - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" + "drupal/core": "~8.0" }, - "time": "2017-03-05T18:23:57+00:00", - "bin": [ - "bin/php-parse" - ], - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.x-dev", + "datestamp": "1472288039" } }, - "notification-url": "https://packagist.org/downloads/", + "installation-source": "source", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Nikita Popov" + "name": "hass", + "homepage": "https://www.drupal.org/u/hass" + }, + { + "name": "See other contributors", + "homepage": "https://www.drupal.org/node/243795/committers" } ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ] + "description": "Periodically checks for broken links in node types, blocks and fields and reports the results.", + "homepage": "https://www.drupal.org/project/linkchecker", + "support": { + "source": "http://git.drupal.org/project/linkchecker.git", + "issues": "https://www.drupal.org/project/issues/linkchecker" + } }, { - "name": "sebastian/recursion-context", - "version": "1.0.5", - "version_normalized": "1.0.5.0", + "name": "drupal/video", + "version": "1.2.0", + "version_normalized": "1.2.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" + "url": "https://git.drupal.org/project/video", + "reference": "8.x-1.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/video-8.x-1.2.zip", + "reference": "8.x-1.2", + "shasum": "d0af8254ad0e3c496fda89d5b796d6fb86ebda7d" }, "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" + "drupal/core": "*" }, - "time": "2016-10-03T07:41:43+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.x", + "datestamp": "1455470039", + "package": "Field types" } }, "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Jorrit", + "homepage": "https://www.drupal.org/user/161217" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "abhishek-anand", + "homepage": "https://www.drupal.org/user/468982" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "brycefisherfleig", + "homepage": "https://www.drupal.org/user/1300764" + }, + { + "name": "chaitanya17", + "homepage": "https://www.drupal.org/user/1998300" + }, + { + "name": "heshanlk", + "homepage": "https://www.drupal.org/user/199102" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context" + "description": "Video module allows you to embedded videos from YouTube, Vimeo, Facebook, Vine etc (Drupal 8 only) and upload videos and play using HTML5 video player.", + "homepage": "https://www.drupal.org/project/video", + "support": { + "source": "http://cgit.drupalcode.org/video" + } }, { - "name": "phpspec/prophecy", - "version": "v1.7.0", - "version_normalized": "1.7.0.0", + "name": "ajgl/breakpoint-twig-extension", + "version": "0.3.0", + "version_normalized": "0.3.0.0", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" + "url": "https://github.com/ajgarlag/AjglBreakpointTwigExtension.git", + "reference": "0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", - "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", + "url": "https://api.github.com/repos/ajgarlag/AjglBreakpointTwigExtension/zipball/0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155", + "reference": "0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", - "sebastian/comparator": "^1.1|^2.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" + "php": ">=5.4.0", + "twig/twig": "^1.14" }, "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8 || ^5.6.5" + "symfony/framework-bundle": "^2.3", + "symfony/twig-bundle": "^2.3" }, - "time": "2017-03-02T20:05:34+00:00", + "suggest": { + "ext-xdebug": "The Xdebug extension is required for the breakpoint to work", + "symfony/framework-bundle": "The framework bundle to integrate the extension into Symfony", + "symfony/twig-bundle": "The twig bundle to integrate the extension into Symfony" + }, + "time": "2016-03-31T18:09:32+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "0.4.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-0": { - "Prophecy\\": "src/" + "psr-4": { + "Ajgl\\Twig\\Extension\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -3939,276 +3673,325 @@ ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" + "name": "Antonio J. García Lagar", + "email": "aj@garcialagar.es", + "homepage": "http://aj.garcialagar.es", + "role": "developer" } ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", + "description": "Twig extension to set breakpoints", + "homepage": "https://github.com/ajgarlag/AjglBreakpointTwigExtension", "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" + "Xdebug", + "breakpoint", + "twig" ] }, { - "name": "twbs/bootstrap-sass", - "version": "v3.3.7", - "version_normalized": "3.3.7.0", + "name": "drupal/twig_xdebug", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://github.com/twbs/bootstrap-sass.git", - "reference": "5d6b2ebba0c2a5885ce2f0e01e9218db3d3b5e47" + "url": "https://git.drupal.org/project/twig_xdebug", + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twbs/bootstrap-sass/zipball/5d6b2ebba0c2a5885ce2f0e01e9218db3d3b5e47", - "reference": "5d6b2ebba0c2a5885ce2f0e01e9218db3d3b5e47", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/twig_xdebug-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "f8a5cfef63b427d6b6b428a2c4bd19b19d082037" }, - "time": "2016-07-25T19:58:53+00:00", - "type": "library", + "require": { + "ajgl/breakpoint-twig-extension": "0.3", + "drupal/core": "~8.0" + }, + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "3.3.x-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0", + "datestamp": "1464928439" } }, "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Mark Otto" - }, - { - "name": "Thomas McDonald" - }, - { - "name": "Tristan Harward" - }, - { - "name": "Peter Gumeson" - }, - { - "name": "Gleb Mazovetskiy" - }, - { - "name": "Jacob Thornton" + "name": "charginghawk", + "homepage": "https://www.drupal.org/user/2626341" } ], - "description": "bootstrap-sass is a Sass-powered version of Bootstrap 3, ready to drop right into your Sass powered applications.", - "homepage": "http://github.com/twbs/bootstrap-sass", - "keywords": [ - "bootstrap", - "css", - "sass" - ] + "description": "Enables Xdebug breakpoints in Twig.", + "homepage": "https://www.drupal.org/project/twig_xdebug", + "support": { + "source": "http://cgit.drupalcode.org/twig_xdebug" + } }, { - "name": "drupal/entity_reference_revisions", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "name": "cebe/markdown", + "version": "1.0.2", + "version_normalized": "1.0.2.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/entity_reference_revisions", - "reference": "8.x-1.2" + "url": "https://github.com/cebe/markdown.git", + "reference": "f681fee8303310415b746f3758eeda0a7ad08bda" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/entity_reference_revisions-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "15261a4237cc2a743522a7bd81e9f34e01d12843" + "url": "https://api.github.com/repos/cebe/markdown/zipball/f681fee8303310415b746f3758eeda0a7ad08bda", + "reference": "f681fee8303310415b746f3758eeda0a7ad08bda", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "lib-pcre": "*", + "php": ">=5.4.0" }, "require-dev": { - "drupal/diff": "*" + "cebe/indent": "*", + "facebook/xhprof": "*@dev", + "phpunit/phpunit": "3.7.*" }, - "type": "drupal-module", + "time": "2015-03-06T05:21:16+00:00", + "bin": [ + "bin/markdown" + ], + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.2", - "datestamp": "1485790085" + "dev-master": "1.0.x-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "cebe\\markdown\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Frans", - "homepage": "https://www.drupal.org/user/514222" - }, - { - "name": "jeroen.b", - "homepage": "https://www.drupal.org/user/1853532" - }, - { - "name": "miro_dietiker", - "homepage": "https://www.drupal.org/user/227761" + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "http://cebe.cc/", + "role": "Creator" } ], - "description": "Adds a Entity Reference field type with revision support.", - "homepage": "https://www.drupal.org/project/entity_reference_revisions", - "support": { - "source": "http://cgit.drupalcode.org/entity_reference_revisions" - } + "description": "A super fast, highly extensible markdown parser for PHP", + "homepage": "https://github.com/cebe/markdown#readme", + "keywords": [ + "extensible", + "fast", + "gfm", + "markdown", + "markdown-extra" + ] }, { - "name": "drupal/paragraphs", - "version": "1.1.0", - "version_normalized": "1.1.0.0", + "name": "guzzlehttp/psr7", + "version": "1.4.2", + "version_normalized": "1.4.2.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/paragraphs", - "reference": "8.x-1.1" + "url": "https://github.com/guzzle/psr7.git", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/paragraphs-8.x-1.1.zip", - "reference": "8.x-1.1", - "shasum": "c678e5704a98c6a0549e415412da081cfeb03a00" + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "shasum": "" }, "require": { - "drupal/core": "~8.0", - "drupal/entity_reference_revisions": "*" + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" }, "require-dev": { - "drupal/diff": "*", - "drupal/field_group": "*", - "drupal/inline_entity_form": "*", - "drupal/replicate": "*", - "drupal/search_api": "*", - "drupal/search_api_db": "*" + "phpunit/phpunit": "~4.0" }, - "type": "drupal-module", + "time": "2017-03-20T17:10:46+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.1", - "datestamp": "1487331784" + "dev-master": "1.4-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Berdir", - "homepage": "https://www.drupal.org/user/214652" - }, - { - "name": "Frans", - "homepage": "https://www.drupal.org/user/514222" - }, - { - "name": "Primsi", - "homepage": "https://www.drupal.org/user/282629" - }, - { - "name": "jeroen.b", - "homepage": "https://www.drupal.org/user/1853532" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" }, { - "name": "miro_dietiker", - "homepage": "https://www.drupal.org/user/227761" + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" } ], - "description": "Enables the creation of paragraphs entities.", - "homepage": "https://www.drupal.org/project/paragraphs", - "support": { - "source": "http://cgit.drupalcode.org/paragraphs" - } + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "request", + "response", + "stream", + "uri", + "url" + ] }, { - "name": "drupal/livereload", - "version": "dev-1.x", - "version_normalized": "dev-1.x", + "name": "paragonie/random_compat", + "version": "v2.0.10", + "version_normalized": "2.0.10.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/livereload", - "reference": "223feb798d2af436818c3d8fd0b47718569ebd4b" + "url": "https://github.com/paragonie/random_compat.git", + "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d", + "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "php": ">=5.2.0" }, - "type": "drupal-module", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.x-dev", - "datestamp": "1474009739" - } + "require-dev": { + "phpunit/phpunit": "4.*|5.*" }, - "installation-source": "source", + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "time": "2017-03-13T16:27:32+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ] + }, + { + "name": "drupal/simple_sitemap", + "version": "2.9.0", + "version_normalized": "2.9.0.0", + "source": { + "type": "git", + "url": "https://git.drupal.org/project/simple_sitemap", + "reference": "8.x-2.9" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/simple_sitemap-8.x-2.9.zip", + "reference": "8.x-2.9", + "shasum": "73bc5b375a7563ee217688f752318fe044b1e9de" + }, + "require": { + "drupal/core": "~8.0" + }, + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + }, + "drupal": { + "version": "8.x-2.9", + "datestamp": "1490775483" + } + }, + "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Hydra", - "homepage": "https://www.drupal.org/user/647364" + "name": "Pawel Ginalski (gbyte.co)", + "homepage": "https://www.drupal.org/u/gbyte.co", + "email": "contact@gbyte.co", + "role": "Maintainer" }, { - "name": "tim.plunkett", - "homepage": "https://www.drupal.org/user/241634" + "name": "Sam Becker (Sam152)", + "homepage": "https://www.drupal.org/u/sam152", + "role": "Co-maintainer" } ], - "description": "Enables and enhances use of LiveReload during development.", - "homepage": "https://www.drupal.org/project/livereload", + "description": "Simple XML sitemap creates a standard conform XML sitemap of your content.", + "homepage": "https://drupal.org/project/simple_sitemap", "support": { - "source": "http://cgit.drupalcode.org/livereload" + "source": "https://cgit.drupalcode.org/simple_sitemap", + "issues": "https://drupal.org/project/issues/simple_sitemap", + "irc": "irc://irc.freenode.org/drupal-contribute" } }, { - "name": "drupal/front", - "version": "1.0.0-alpha2", - "version_normalized": "1.0.0.0-alpha2", + "name": "drupal/fontyourface", + "version": "3.1.0", + "version_normalized": "3.1.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/front", - "reference": "8.x-1.0-alpha2" + "url": "https://git.drupal.org/project/fontyourface", + "reference": "8.x-3.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/front-8.x-1.0-alpha2.zip", - "reference": "8.x-1.0-alpha2", - "shasum": "d4381a4fea8ebdf50575a2b443094612b0ff1eb0" + "url": "https://ftp.drupal.org/files/projects/fontyourface-8.x-3.1.zip", + "reference": "8.x-3.1", + "shasum": "c5e02349327e4962dc15901ad442a887326b5b73" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "8.*" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-3.x": "3.x-dev" }, "drupal": { - "version": "8.x-1.0-alpha2", - "datestamp": "1487686982" + "version": "8.x-3.1", + "datestamp": "1490223783" } }, "installation-source": "dist", @@ -4218,42 +4001,43 @@ ], "authors": [ { - "name": "Dublin Drupaller", - "homepage": "https://www.drupal.org/user/8625" - }, - { - "name": "Simon Georges", - "homepage": "https://www.drupal.org/user/172312" + "name": "BTMash", + "homepage": "https://www.drupal.org/user/60422" }, { - "name": "asenenko", - "homepage": "https://www.drupal.org/user/2641733" + "name": "BarisW", + "homepage": "https://www.drupal.org/user/107229" }, { - "name": "estoyausente", - "homepage": "https://www.drupal.org/user/1232954" + "name": "Drave Robber", + "homepage": "https://www.drupal.org/user/984338" }, { - "name": "timhilliard", - "homepage": "https://www.drupal.org/user/195493" + "name": "sreynen", + "homepage": "https://www.drupal.org/user/109890" } ], - "homepage": "https://www.drupal.org/project/front", + "description": "Web font management tools.", + "homepage": "https://www.drupal.org/project/fontyourface", + "keywords": [ + "Drupal" + ], "support": { - "source": "http://cgit.drupalcode.org/front" + "source": "http://cgit.drupalcode.org/fontyourface", + "issues": "http://drupal.org/project/issues/fontyourface" } }, { - "name": "drupal/filefield_sources", + "name": "drupal/php", "version": "dev-1.x", "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://git.drupal.org/project/filefield_sources", - "reference": "b19c6a839804f47587828d4a50e29e0720fa4c08" + "url": "https://git.drupal.org/project/php", + "reference": "304022be52874ef2d7916ea3acafd312766da9cc" }, "require": { - "drupal/core": "*" + "drupal/core": "~8.0" }, "type": "drupal-module", "extra": { @@ -4261,8 +4045,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.x-dev", - "datestamp": "1464990539" + "version": "8.x-1.0-beta2+1-dev", + "datestamp": "1461875939" } }, "installation-source": "source", @@ -4272,80 +4056,106 @@ ], "authors": [ { - "name": "profak", - "homepage": "https://www.drupal.org/user/782534" + "name": "hass", + "homepage": "https://www.drupal.org/u/hass" + }, + { + "name": "See other contributors", + "homepage": "https://www.drupal.org/node/1633456/committers" + }, + { + "name": "catch", + "homepage": "https://www.drupal.org/user/35733" + }, + { + "name": "dixon_", + "homepage": "https://www.drupal.org/user/239911" + }, + { + "name": "greggles", + "homepage": "https://www.drupal.org/user/36762" + }, + { + "name": "hass", + "homepage": "https://www.drupal.org/user/85918" + }, + { + "name": "msonnabaum", + "homepage": "https://www.drupal.org/user/75278" }, { "name": "quicksketch", "homepage": "https://www.drupal.org/user/35821" + }, + { + "name": "webchick", + "homepage": "https://www.drupal.org/user/24967" } ], - "description": "Extends File fields to allow referencing of existing files, remote files, and server files.", - "homepage": "https://www.drupal.org/project/filefield_sources", + "description": "Allows embedded PHP code/snippets to be evaluated. Enabling this can cause security and performance issues as it allows users to execute PHP code on your site.", + "homepage": "https://www.drupal.org/project/php", "support": { - "source": "http://cgit.drupalcode.org/filefield_sources" + "source": "http://git.drupal.org/project/php.git", + "issues": "https://www.drupal.org/project/issues/php" } }, { - "name": "drupal/environment_indicator", - "version": "3.0.0", - "version_normalized": "3.0.0.0", + "name": "cweagans/composer-patches", + "version": "1.6.1", + "version_normalized": "1.6.1.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/environment_indicator", - "reference": "8.x-3.0" + "url": "https://github.com/cweagans/composer-patches.git", + "reference": "b3036f23b73570ab5d869e345277786c8eb248a9" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/environment_indicator-8.x-3.0.zip", - "reference": "8.x-3.0", - "shasum": "eb435b390f07e228eb55638630c6b5b9fb3e104e" + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/b3036f23b73570ab5d869e345277786c8eb248a9", + "reference": "b3036f23b73570ab5d869e345277786c8eb248a9", + "shasum": "" }, "require": { - "drupal/core": "*" + "composer-plugin-api": "^1.0", + "php": ">=5.3.0" }, - "type": "drupal-module", + "require-dev": { + "composer/composer": "~1.0", + "phpunit/phpunit": "~4.6" + }, + "time": "2017-03-19T18:18:52+00:00", + "type": "composer-plugin", "extra": { - "branch-alias": { - "dev-3.x": "3.x-dev" - }, - "drupal": { - "version": "8.x-3.0", - "datestamp": "1487828585" - } + "class": "cweagans\\Composer\\Patches" }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "cweagans\\Composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "BSD-2-Clause" ], "authors": [ { - "name": "e0ipso", - "homepage": "https://www.drupal.org/user/550110" - }, - { - "name": "mrfelton", - "homepage": "https://www.drupal.org/user/305669" + "name": "Cameron Eagans", + "email": "me@cweagans.net" } ], - "description": "Adds a color indicator for the different environments.", - "homepage": "https://www.drupal.org/project/environment_indicator", - "support": { - "source": "http://cgit.drupalcode.org/environment_indicator" - } + "description": "Provides a way to patch Composer packages." }, { - "name": "drupal/pathologic", + "name": "drupal/security_review", "version": "dev-1.x", "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://git.drupal.org/project/pathologic", - "reference": "e0473546e51cbeaa3acb34e3208a0c503ca85613" + "url": "https://git.drupal.org/project/security_review", + "reference": "35ebae445bb260e961e47c4c58efe7c50c228999" }, "require": { - "drupal/core": "*" + "drupal/core": "~8.0" }, "type": "drupal-module", "extra": { @@ -4354,7 +4164,10 @@ }, "drupal": { "version": "8.x-1.x-dev", - "datestamp": "1446842039" + "datestamp": "1476978839" + }, + "patches_applied": { + "Fix missing field review list": "https://www.drupal.org/files/issues/security_review-dangerous-tags-list-2744805-2.patch" } }, "installation-source": "source", @@ -4364,37 +4177,45 @@ ], "authors": [ { - "name": "Berdir", - "homepage": "https://www.drupal.org/user/214652" + "name": "banviktor", + "homepage": "https://www.drupal.org/user/3176333" }, { - "name": "Garrett Albright", - "homepage": "https://www.drupal.org/user/191212" - } + "name": "coltrane", + "homepage": "https://www.drupal.org/user/91990" + }, + { + "name": "dsnopek", + "homepage": "https://www.drupal.org/user/266527" + }, + { + "name": "greggles", + "homepage": "https://www.drupal.org/user/36762" + } ], - "description": "Helps avoid broken links and incorrect paths in content.", - "homepage": "https://www.drupal.org/project/pathologic", + "description": "Site security and configuration review module.", + "homepage": "https://www.drupal.org/project/security_review", "support": { - "source": "http://cgit.drupalcode.org/pathologic" + "source": "http://cgit.drupalcode.org/security_review" } }, { - "name": "drupal/typogrify", - "version": "1.0.0-alpha1", - "version_normalized": "1.0.0.0-alpha1", + "name": "drupal/entity", + "version": "1.0.0-alpha4", + "version_normalized": "1.0.0.0-alpha4", "source": { "type": "git", - "url": "https://git.drupal.org/project/typogrify", - "reference": "8.x-1.0-alpha1" + "url": "https://git.drupal.org/project/entity", + "reference": "8.x-1.0-alpha4" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/typogrify-8.x-1.0-alpha1.zip", - "reference": "8.x-1.0-alpha1", - "shasum": "de87791555204b3af5692d939f8c199bd7164495" + "url": "https://ftp.drupal.org/files/projects/entity-8.x-1.0-alpha4.zip", + "reference": "8.x-1.0-alpha4", + "shasum": "c081d3757c159dfee74c9e5acb63bdee81c42e18" }, "require": { - "drupal/core": "*" + "drupal/core": "~8.1" }, "type": "drupal-module", "extra": { @@ -4402,8 +4223,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-alpha1", - "datestamp": "1478050442" + "version": "8.x-1.0-alpha4", + "datestamp": "1481194983" } }, "installation-source": "dist", @@ -4413,50 +4234,54 @@ ], "authors": [ { - "name": "See contributors", - "homepage": "https://www.drupal.org/node/149970/committers", - "role": "Developer" + "name": "Berdir", + "homepage": "https://www.drupal.org/user/214652" }, { - "name": "migmedia", - "homepage": "https://www.drupal.org/user/1310354" + "name": "bojanz", + "homepage": "https://www.drupal.org/user/86106" }, { - "name": "mikl", - "homepage": "https://www.drupal.org/user/58679" + "name": "dawehner", + "homepage": "https://www.drupal.org/user/99340" }, { - "name": "sreynen", - "homepage": "https://www.drupal.org/user/109890" + "name": "dixon_", + "homepage": "https://www.drupal.org/user/239911" + }, + { + "name": "fago", + "homepage": "https://www.drupal.org/user/16747" } ], - "description": "A filter for making typographic refinements.", - "homepage": "http://drupal.org/project/typogrify", - "keywords": [ - "Drupal" - ], + "description": "Provides expanded entity APIs, which will be moved to Drupal core one day.", + "homepage": "http://drupal.org/project/entity", "support": { - "source": "http://cgit.drupalcode.org/typogrify", - "issues": "http://drupal.org/project/typogrify" + "source": "http://cgit.drupalcode.org/entity" } }, { - "name": "drupal/entityqueue", - "version": "1.0.0-alpha6", - "version_normalized": "1.0.0.0-alpha6", + "name": "drupal/media_entity", + "version": "1.6.0", + "version_normalized": "1.6.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/entityqueue", - "reference": "8.x-1.0-alpha6" + "url": "https://git.drupal.org/project/media_entity", + "reference": "8.x-1.6" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/entityqueue-8.x-1.0-alpha6.zip", - "reference": "8.x-1.0-alpha6", - "shasum": "2f7c639020a4c688b419ca90e35ffe0d08b34639" + "url": "https://ftp.drupal.org/files/projects/media_entity-8.x-1.6.zip", + "reference": "8.x-1.6", + "shasum": "86fd1478f2448c034660faa30ef34c0e8519fecb" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "~8.1", + "drupal/entity": "^1.0.0-alpha3" + }, + "require-dev": { + "drupal/entity": "*", + "drupal/inline_entity_form": "*" }, "type": "drupal-module", "extra": { @@ -4464,8 +4289,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-alpha6", - "datestamp": "1481985783" + "version": "8.x-1.6", + "datestamp": "1480363983" } }, "installation-source": "dist", @@ -4475,89 +4300,146 @@ ], "authors": [ { - "name": "amateescu", - "homepage": "https://www.drupal.org/user/729614" + "name": "Berdir", + "homepage": "https://www.drupal.org/user/214652" }, { - "name": "jojonaloha", - "homepage": "https://www.drupal.org/user/1579186" + "name": "Dave Reid", + "homepage": "https://www.drupal.org/user/53892" }, { - "name": "tim.plunkett", - "homepage": "https://www.drupal.org/user/241634" + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" + }, + { + "name": "Drupal media CI", + "homepage": "https://www.drupal.org/user/3057985" + }, + { + "name": "Primsi", + "homepage": "https://www.drupal.org/user/282629" + }, + { + "name": "boztek", + "homepage": "https://www.drupal.org/user/134410" + }, + { + "name": "chr.fritsch", + "homepage": "https://www.drupal.org/user/2103716" + }, + { + "name": "jcisio", + "homepage": "https://www.drupal.org/user/210762" + }, + { + "name": "katzilla", + "homepage": "https://www.drupal.org/user/260398" + }, + { + "name": "phenaproxima", + "homepage": "https://www.drupal.org/user/205645" + }, + { + "name": "seanB", + "homepage": "https://www.drupal.org/user/545912" + }, + { + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Allows users to collect entities in arbitrarily ordered lists.", - "homepage": "https://www.drupal.org/project/entityqueue", + "description": "Provides a lean and simple way to store media on Drupal 8 sites.", + "homepage": "https://www.drupal.org/project/media_entity", + "keywords": [ + "Drupal" + ], "support": { - "source": "http://cgit.drupalcode.org/entityqueue" + "source": "https://www.drupal.org/project/media_entity", + "issues": "https://www.drupal.org/project/issues/media_entity" } }, { - "name": "michelf/php-markdown", - "version": "1.7.0", - "version_normalized": "1.7.0.0", + "name": "drupal/media_entity_image", + "version": "1.2.0", + "version_normalized": "1.2.0.0", "source": { "type": "git", - "url": "https://github.com/michelf/php-markdown.git", - "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220" + "url": "https://git.drupal.org/project/media_entity_image", + "reference": "8.x-1.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/1f51cc520948f66cd2af8cbc45a5ee175e774220", - "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/media_entity_image-8.x-1.2.zip", + "reference": "8.x-1.2", + "shasum": "d02d1d793a50ea3b9cb5a3219472fdd27980f4f3" }, "require": { - "php": ">=5.3.0" + "drupal/core": "~8.1", + "drupal/media_entity": "~1.0 || ~8.1.0" }, - "time": "2016-10-29T18:58:20+00:00", - "type": "library", + "require-dev": { + "drupal/entity_browser": "*" + }, + "type": "drupal-module", "extra": { "branch-alias": { - "dev-lib": "1.4.x-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.2", + "datestamp": "1470170939" } }, "installation-source": "dist", - "autoload": { - "psr-0": { - "Michelf": "" - } - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Michel Fortin", - "email": "michel.fortin@michelf.ca", - "homepage": "https://michelf.ca/", - "role": "Developer" + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" }, { - "name": "John Gruber", - "homepage": "https://daringfireball.net/" + "name": "Primsi", + "homepage": "https://www.drupal.org/user/282629" + }, + { + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "PHP Markdown", - "homepage": "https://michelf.ca/projects/php-markdown/", + "description": "Local images integration for Drupal Media entity.", + "homepage": "https://www.drupal.org/project/media_entity_image", "keywords": [ - "markdown" - ] + "Drupal", + "image", + "media" + ], + "support": { + "source": "https://www.drupal.org/project/media_entity_image", + "issues": "https://www.drupal.org/project/issues/media_entity_image" + } }, { - "name": "drupal/advanced_help", - "version": "dev-1.x", - "version_normalized": "dev-1.x", + "name": "drupal/media_entity_twitter", + "version": "1.3.0", + "version_normalized": "1.3.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/advanced_help", - "reference": "ed80f440c8bb0c3c5b1868f3429f296e52c841a6" + "url": "https://git.drupal.org/project/media_entity_twitter", + "reference": "8.x-1.3" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/media_entity_twitter-8.x-1.3.zip", + "reference": "8.x-1.3", + "shasum": "280406ba63e2c00befa9bb1434ad2d4d3113b239" }, "require": { "drupal/core": "~8.0", - "michelf/php-markdown": "^1.7" + "drupal/media_entity": "*", + "j7mbo/twitter-api-php": "~1.0" }, "type": "drupal-module", "extra": { @@ -4565,65 +4447,53 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.x-dev", - "datestamp": "1490703369" + "version": "8.x-1.3", + "datestamp": "1478549339" } }, - "installation-source": "source", + "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "David Valdez (gnuget)", - "homepage": "https://www.drupal.org/u/gnuget", - "role": "Maintainer" + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" }, { - "name": "dmitrig01", - "homepage": "https://www.drupal.org/user/47566" - }, - { - "name": "fgm", - "homepage": "https://www.drupal.org/user/27985" - }, - { - "name": "gisle", - "homepage": "https://www.drupal.org/user/409554" - }, - { - "name": "gnuget", - "homepage": "https://www.drupal.org/user/992990" - }, - { - "name": "merlinofchaos", - "homepage": "https://www.drupal.org/user/26979" + "name": "Primsi", + "homepage": "https://www.drupal.org/user/282629" }, { - "name": "redndahead", - "homepage": "https://www.drupal.org/user/160320" + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Provide extended help and documentation.", - "homepage": "https://www.drupal.org/project/advanced_help", + "description": "Media entity Twitter provider.", + "homepage": "https://www.drupal.org/project/media_entity_twitter", "support": { - "source": "https://cgit.drupalcode.org/advanced_help", - "issues": "https://www.drupal.org/project/issues/advanced_help", - "irc": "irc://irc.freenode.org/drupal-contribute" + "source": "http://cgit.drupalcode.org/media_entity_twitter" } }, { - "name": "drupal/better_formats", - "version": "dev-1.x", - "version_normalized": "dev-1.x", + "name": "drupal/media_entity_slideshow", + "version": "1.2.0", + "version_normalized": "1.2.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/better_formats", - "reference": "9b3b5fa792c1dfe0d1121021a230086f3599b7e4" + "url": "https://git.drupal.org/project/media_entity_slideshow", + "reference": "8.x-1.2" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/media_entity_slideshow-8.x-1.2.zip", + "reference": "8.x-1.2", + "shasum": "c9d49eb6be7de0ea8e500554b89842842287cd1f" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "~8.0", + "drupal/media_entity": "*" }, "type": "drupal-module", "extra": { @@ -4631,48 +4501,49 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.x-dev", - "datestamp": "1474656839" + "version": "8.x-1.2", + "datestamp": "1470687839" } }, - "installation-source": "source", + "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Devin Carlson", - "homepage": "https://www.drupal.org/user/290182" + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" }, { - "name": "dragonwize", - "homepage": "https://www.drupal.org/user/137882" + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Enhances the core input format system by managing input format defaults and settings.", - "homepage": "https://www.drupal.org/project/better_formats", + "description": "Media entity slideshow provider.", + "homepage": "https://www.drupal.org/project/media_entity_slideshow", "support": { - "source": "http://cgit.drupalcode.org/better_formats" + "source": "http://cgit.drupalcode.org/media_entity_slideshow" } }, { - "name": "drupal/block_class", - "version": "1.0.0-alpha1", - "version_normalized": "1.0.0.0-alpha1", + "name": "drupal/media_entity_document", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/block_class", - "reference": "8.x-1.0-alpha1" + "url": "https://git.drupal.org/project/media_entity_document", + "reference": "8.x-1.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/block_class-8.x-1.0-alpha1.zip", - "reference": "8.x-1.0-alpha1", - "shasum": "194cd52210ea2e0e5dbbd34fad4528d500424430" + "url": "https://ftp.drupal.org/files/projects/media_entity_document-8.x-1.1.zip", + "reference": "8.x-1.1", + "shasum": "88a45820cf0aeb5f8a3ade3338007771191508e4" }, "require": { - "drupal/core": "*" + "drupal/core": "~8.1", + "drupal/media_entity": "~1.0 || ~8.1.0" }, "type": "drupal-module", "extra": { @@ -4680,8 +4551,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-alpha1", - "datestamp": "1475623439" + "version": "8.x-1.1", + "datestamp": "1470211995" } }, "installation-source": "dist", @@ -4691,113 +4562,101 @@ ], "authors": [ { - "name": "Aaron Stanush", - "homepage": "https://www.drupal.org/user/89718" - }, - { - "name": "DYdave", - "homepage": "https://www.drupal.org/user/467284" - }, - { - "name": "Four Kitchens", - "homepage": "https://www.drupal.org/user/358502" - }, - { - "name": "Todd Nienkerk", - "homepage": "https://www.drupal.org/user/92096" - }, - { - "name": "berenddeboer", - "homepage": "https://www.drupal.org/user/143552" - }, - { - "name": "elliotttf", - "homepage": "https://www.drupal.org/user/61601" - }, - { - "name": "mirzu", - "homepage": "https://www.drupal.org/user/7710" - }, - { - "name": "patrickcoffeyo", - "homepage": "https://www.drupal.org/user/2837945" - }, - { - "name": "pcoffey", - "homepage": "https://www.drupal.org/user/1595818" - }, - { - "name": "tsmith512", - "homepage": "https://www.drupal.org/user/2031446" + "name": "NerOcrO", + "homepage": "https://www.drupal.org/user/1728164", + "role": "Maintainer" } ], - "description": "Allows assigning classes to Blocks", - "homepage": "https://www.drupal.org/project/block_class", + "description": "Local documents integration for Drupal Media entity.", + "homepage": "https://www.drupal.org/project/media_entity_document", + "keywords": [ + "Drupal", + "document", + "media" + ], "support": { - "source": "http://cgit.drupalcode.org/block_class" + "source": "https://www.drupal.org/project/media_entity_document", + "issues": "https://www.drupal.org/project/issues/media_entity_document" } }, { - "name": "drupal/libraries", - "version": "dev-3.x", - "version_normalized": "dev-3.x", + "name": "drupal/inline_entity_form", + "version": "1.0.0-beta1", + "version_normalized": "1.0.0.0-beta1", "source": { "type": "git", - "url": "https://git.drupal.org/project/libraries", - "reference": "061ead081c92a6209b09eaf23b4e3103f360946e" + "url": "https://git.drupal.org/project/inline_entity_form", + "reference": "8.x-1.0-beta1" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/inline_entity_form-8.x-1.0-beta1.zip", + "reference": "8.x-1.0-beta1", + "shasum": "185ffc28a7b68d19cce057855d1c111f1741a3ea" }, "require": { "drupal/core": "~8.0" }, + "require-dev": { + "drupal/entity_reference_revisions": "*" + }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev" + "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-3.x-dev", - "datestamp": "1487978583" + "version": "8.x-1.0-beta1", + "datestamp": "1477868343" } }, - "installation-source": "source", + "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Pol", - "homepage": "https://www.drupal.org/user/47194" + "name": "bojanz", + "homepage": "https://www.drupal.org/user/86106" }, { - "name": "rjacobs", - "homepage": "https://www.drupal.org/user/422459" + "name": "dawehner", + "homepage": "https://www.drupal.org/user/99340" }, { - "name": "sun", - "homepage": "https://www.drupal.org/user/54136" + "name": "rszrama", + "homepage": "https://www.drupal.org/user/49344" }, { - "name": "tstoeckler", - "homepage": "https://www.drupal.org/user/107158" + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" + }, + { + "name": "webflo", + "homepage": "https://www.drupal.org/user/254778" } ], - "description": "Allows version-dependent and shared usage of external libraries in Drupal.", - "homepage": "http://drupal.org/project/libraries", + "description": "Provides a widget for inline management (creation, modification, removal) of referenced entities.", + "homepage": "https://www.drupal.org/project/inline_entity_form", "support": { - "source": "http://cgit.drupalcode.org/libraries", - "issues": "http://drupal.org/project/issues/libraries", - "irc": "irc://irc.freenode.org/drupal-contribute" + "source": "http://cgit.drupalcode.org/inline_entity_form" } }, { - "name": "drupal/linkchecker", - "version": "dev-1.x", - "version_normalized": "dev-1.x", + "name": "drupal/embed", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/linkchecker", - "reference": "51377136199d15d6e0ca36339f68934c4eb19204" + "url": "https://git.drupal.org/project/embed", + "reference": "8.x-1.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/embed-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "cc746ad807260e01c7788dd82110dcebbb4d678a" }, "require": { "drupal/core": "~8.0" @@ -4808,49 +4667,66 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.x-dev", - "datestamp": "1472288039" + "version": "8.x-1.0", + "datestamp": "1490755685" } }, - "installation-source": "source", + "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "hass", - "homepage": "https://www.drupal.org/u/hass" + "name": "Dave Reid", + "homepage": "https://www.drupal.org/user/53892" }, { - "name": "See other contributors", - "homepage": "https://www.drupal.org/node/243795/committers" + "name": "Devin Carlson", + "homepage": "https://www.drupal.org/user/290182" + }, + { + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" + }, + { + "name": "cs_shadow", + "homepage": "https://www.drupal.org/user/2828287" + }, + { + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Periodically checks for broken links in node types, blocks and fields and reports the results.", - "homepage": "https://www.drupal.org/project/linkchecker", + "description": "Provide a framework for various different types of embeds in WYSIWYG editors, common functionality, interfaces, and standards.", + "homepage": "https://www.drupal.org/project/embed", "support": { - "source": "http://git.drupal.org/project/linkchecker.git", - "issues": "https://www.drupal.org/project/issues/linkchecker" + "source": "http://cgit.drupalcode.org/embed", + "issues": "https://www.drupal.org/project/issues/embed", + "irc": "irc://irc.freenode.org/drupal-media" } }, { - "name": "drupal/video", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "name": "drupal/entity_embed", + "version": "1.0.0-beta2", + "version_normalized": "1.0.0.0-beta2", "source": { "type": "git", - "url": "https://git.drupal.org/project/video", - "reference": "8.x-1.2" + "url": "https://git.drupal.org/project/entity_embed", + "reference": "8.x-1.0-beta2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/video-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "d0af8254ad0e3c496fda89d5b796d6fb86ebda7d" + "url": "https://ftp.drupal.org/files/projects/entity_embed-8.x-1.0-beta2.zip", + "reference": "8.x-1.0-beta2", + "shasum": "21cdeb2b058efce461683aed9a8951053512dca7" }, "require": { - "drupal/core": "*" + "drupal/core": "*", + "drupal/embed": "*" + }, + "require-dev": { + "drupal/entity_browser": "*" }, "type": "drupal-module", "extra": { @@ -4858,9 +4734,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.x", - "datestamp": "1455470039", - "package": "Field types" + "version": "8.x-1.0-beta2", + "datestamp": "1476698339" } }, "installation-source": "dist", @@ -4870,111 +4745,77 @@ ], "authors": [ { - "name": "Jorrit", - "homepage": "https://www.drupal.org/user/161217" + "name": "Dave Reid", + "homepage": "https://www.drupal.org/user/53892" }, { - "name": "abhishek-anand", - "homepage": "https://www.drupal.org/user/468982" + "name": "Devin Carlson", + "homepage": "https://www.drupal.org/user/290182" }, { - "name": "brycefisherfleig", - "homepage": "https://www.drupal.org/user/1300764" + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" }, { - "name": "chaitanya17", - "homepage": "https://www.drupal.org/user/1998300" + "name": "cs_shadow", + "homepage": "https://www.drupal.org/user/2828287" }, { - "name": "heshanlk", - "homepage": "https://www.drupal.org/user/199102" + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Video module allows you to embedded videos from YouTube, Vimeo, Facebook, Vine etc (Drupal 8 only) and upload videos and play using HTML5 video player.", - "homepage": "https://www.drupal.org/project/video", + "description": "Allows any entity to be embedded within a text area using a WYSIWYG editor.", + "homepage": "https://www.drupal.org/project/entity_embed", "support": { - "source": "http://cgit.drupalcode.org/video" + "source": "http://cgit.drupalcode.org/entity_embed", + "issues": "https://www.drupal.org/project/issues/entity_embed", + "irc": "irc://irc.freenode.org/drupal-media" } }, { - "name": "ajgl/breakpoint-twig-extension", - "version": "0.3.0", - "version_normalized": "0.3.0.0", + "name": "drupal/media", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://github.com/ajgarlag/AjglBreakpointTwigExtension.git", - "reference": "0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ajgarlag/AjglBreakpointTwigExtension/zipball/0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155", - "reference": "0dfa4f0ae3bbeb6c8036e3e6d6c204c43b090155", - "shasum": "" + "url": "https://git.drupal.org/project/media", + "reference": "b9d72f21ea20c583ec4b83081720eba65670a8da" }, "require": { - "php": ">=5.4.0", - "twig/twig": "^1.14" + "drupal/core": "*", + "drupal/dropzonejs_eb_widget": "*", + "drupal/entity_browser": "*", + "drupal/entity_browser_entity_form": "*", + "drupal/entity_embed": "*", + "drupal/image_widget_crop": "*", + "drupal/inline_entity_form": "*", + "drupal/media_entity": "*", + "drupal/media_entity_document": "*", + "drupal/media_entity_image": "*", + "drupal/media_entity_instagram": "*", + "drupal/media_entity_slideshow": "*", + "drupal/media_entity_twitter": "*", + "drupal/slick_media": "*", + "drupal/video_embed_field": "*", + "drupal/video_embed_media": "*" }, "require-dev": { - "symfony/framework-bundle": "^2.3", - "symfony/twig-bundle": "^2.3" - }, - "suggest": { - "ext-xdebug": "The Xdebug extension is required for the breakpoint to work", - "symfony/framework-bundle": "The framework bundle to integrate the extension into Symfony", - "symfony/twig-bundle": "The twig bundle to integrate the extension into Symfony" - }, - "time": "2016-03-31T18:09:32+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.4.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Ajgl\\Twig\\Extension\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Antonio J. García Lagar", - "email": "aj@garcialagar.es", - "homepage": "http://aj.garcialagar.es", - "role": "developer" - } - ], - "description": "Twig extension to set breakpoints", - "homepage": "https://github.com/ajgarlag/AjglBreakpointTwigExtension", - "keywords": [ - "Xdebug", - "breakpoint", - "twig" - ] - }, - { - "name": "drupal/twig_xdebug", - "version": "1.0.0", - "version_normalized": "1.0.0.0", - "source": { - "type": "git", - "url": "https://git.drupal.org/project/twig_xdebug", - "reference": "8.x-1.0" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/twig_xdebug-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "f8a5cfef63b427d6b6b428a2c4bd19b19d082037" - }, - "require": { - "ajgl/breakpoint-twig-extension": "0.3", - "drupal/core": "~8.0" + "drupal/dropzonejs_eb_widget": "*", + "drupal/entity_browser": "*", + "drupal/entity_browser_entity_form": "*", + "drupal/entity_embed": "*", + "drupal/image_widget_crop": "*", + "drupal/inline_entity_form": "*", + "drupal/media_entity": "*", + "drupal/media_entity_document": "*", + "drupal/media_entity_image": "*", + "drupal/media_entity_instagram": "*", + "drupal/media_entity_slideshow": "*", + "drupal/media_entity_twitter": "*", + "drupal/slick_media": "*", + "drupal/video_embed_field": "*", + "drupal/video_embed_media": "*" }, "type": "drupal-module", "extra": { @@ -4982,371 +4823,358 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1464928439" + "version": "8.x-1.x-dev", + "datestamp": "1476811139" } }, - "installation-source": "dist", + "installation-source": "source", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "charginghawk", - "homepage": "https://www.drupal.org/user/2626341" + "name": "Dave Reid", + "homepage": "https://www.drupal.org/user/53892" + }, + { + "name": "David_Rothstein", + "homepage": "https://www.drupal.org/user/124982" + }, + { + "name": "Devin Carlson", + "homepage": "https://www.drupal.org/user/290182" + }, + { + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" + }, + { + "name": "ParisLiakos", + "homepage": "https://www.drupal.org/user/1011436" + }, + { + "name": "arthurf", + "homepage": "https://www.drupal.org/user/27259" + }, + { + "name": "becw", + "homepage": "https://www.drupal.org/user/81067" + }, + { + "name": "effulgentsia", + "homepage": "https://www.drupal.org/user/78040" + }, + { + "name": "joseph.olstad", + "homepage": "https://www.drupal.org/user/1321830" + }, + { + "name": "ksenzee", + "homepage": "https://www.drupal.org/user/139855" + }, + { + "name": "paul.lovvik", + "homepage": "https://www.drupal.org/user/289213" + }, + { + "name": "robeano", + "homepage": "https://www.drupal.org/user/67660" + }, + { + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Enables Xdebug breakpoints in Twig.", - "homepage": "https://www.drupal.org/project/twig_xdebug", + "description": "Media module for Drupal", + "homepage": "https://github.com/drupal-media/media/", "support": { - "source": "http://cgit.drupalcode.org/twig_xdebug" + "source": "http://cgit.drupalcode.org/media", + "irc": "irc://irc.freenode.org/drupal-contribute" } }, { - "name": "cebe/markdown", - "version": "1.0.2", - "version_normalized": "1.0.2.0", + "name": "zendframework/zend-feed", + "version": "2.8.0", + "version_normalized": "2.8.0.0", "source": { "type": "git", - "url": "https://github.com/cebe/markdown.git", - "reference": "f681fee8303310415b746f3758eeda0a7ad08bda" + "url": "https://github.com/zendframework/zend-feed.git", + "reference": "94579e805dd108683209fe14b3b5d4276de3de6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cebe/markdown/zipball/f681fee8303310415b746f3758eeda0a7ad08bda", - "reference": "f681fee8303310415b746f3758eeda0a7ad08bda", + "url": "https://api.github.com/repos/zendframework/zend-feed/zipball/94579e805dd108683209fe14b3b5d4276de3de6e", + "reference": "94579e805dd108683209fe14b3b5d4276de3de6e", "shasum": "" }, "require": { - "lib-pcre": "*", - "php": ">=5.4.0" + "php": "^5.6 || ^7.0", + "zendframework/zend-escaper": "^2.5", + "zendframework/zend-stdlib": "^2.7 || ^3.1" }, "require-dev": { - "cebe/indent": "*", - "facebook/xhprof": "*@dev", - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "psr/http-message": "^1.0", + "zendframework/zend-cache": "^2.6", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-db": "^2.7", + "zendframework/zend-http": "^2.5.4", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-validator": "^2.6" }, - "time": "2015-03-06T05:21:16+00:00", - "bin": [ - "bin/markdown" - ], + "suggest": { + "psr/http-message": "PSR-7 ^1.0, if you wish to use Zend\\Feed\\Reader\\Http\\Psr7ResponseDecorator", + "zendframework/zend-cache": "Zend\\Cache component, for optionally caching feeds between requests", + "zendframework/zend-db": "Zend\\Db component, for use with PubSubHubbub", + "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for easily extending ExtensionManager implementations", + "zendframework/zend-validator": "Zend\\Validator component, for validating email addresses used in Atom feeds and entries ehen using the Writer subcomponent" + }, + "time": "2017-04-01T15:03:14+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.8-dev", + "dev-develop": "2.9-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "cebe\\markdown\\": "" + "Zend\\Feed\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" - ], - "authors": [ - { - "name": "Carsten Brandt", - "email": "mail@cebe.cc", - "homepage": "http://cebe.cc/", - "role": "Creator" - } + "BSD-3-Clause" ], - "description": "A super fast, highly extensible markdown parser for PHP", - "homepage": "https://github.com/cebe/markdown#readme", + "description": "provides functionality for consuming RSS and Atom feeds", + "homepage": "https://github.com/zendframework/zend-feed", "keywords": [ - "extensible", - "fast", - "gfm", - "markdown", - "markdown-extra" + "feed", + "zf2" ] }, { - "name": "psy/psysh", - "version": "v0.8.3", - "version_normalized": "0.8.3.0", + "name": "enyo/dropzone", + "version": "v4.3.0", + "version_normalized": "4.3.0.0", "source": { "type": "git", - "url": "https://github.com/bobthecow/psysh.git", - "reference": "1dd4bbbc64d71e7ec075ffe82b42d9e096dc8d5e" + "url": "https://github.com/enyo/dropzone.git", + "reference": "d8ef7a82e6ab5447c1f2d9512c8e1bfd4de5ac9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/1dd4bbbc64d71e7ec075ffe82b42d9e096dc8d5e", - "reference": "1dd4bbbc64d71e7ec075ffe82b42d9e096dc8d5e", + "url": "https://api.github.com/repos/enyo/dropzone/zipball/d8ef7a82e6ab5447c1f2d9512c8e1bfd4de5ac9e", + "reference": "d8ef7a82e6ab5447c1f2d9512c8e1bfd4de5ac9e", "shasum": "" }, - "require": { - "dnoegel/php-xdg-base-dir": "0.1", - "jakub-onderka/php-console-highlighter": "0.3.*", - "nikic/php-parser": "~1.3|~2.0|~3.0", - "php": ">=5.3.9", - "symfony/console": "~2.3.10|^2.4.2|~3.0", - "symfony/var-dumper": "~2.7|~3.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~1.11", - "hoa/console": "~3.16|~1.14", - "phpunit/phpunit": "~4.4|~5.0", - "symfony/finder": "~2.1|~3.0" - }, - "suggest": { - "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", - "ext-pdo-sqlite": "The doc command requires SQLite to work.", - "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", - "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", - "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." - }, - "time": "2017-03-19T21:40:44+00:00", - "bin": [ - "bin/psysh" - ], + "time": "2016-02-14T04:19:41+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "0.9.x-dev" - } - }, "installation-source": "dist", - "autoload": { - "files": [ - "src/Psy/functions.php" - ], - "psr-4": { - "Psy\\": "src/Psy/" - } - }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" + "name": "Matias Meno", + "email": "m@tias.me", + "homepage": "http://www.matiasmeno.com" } ], - "description": "An interactive shell for modern PHP.", - "homepage": "http://psysh.org", + "description": "Handles drag and drop of files for you.", + "homepage": "http://www.dropzonejs.com", "keywords": [ - "REPL", - "console", - "interactive", - "shell" + "drag and drop", + "dragndrop", + "file upload", + "upload" ] }, { - "name": "guzzlehttp/psr7", - "version": "1.4.2", - "version_normalized": "1.4.2.0", + "name": "drush/config-extra", + "version": "1.0.1", + "version_normalized": "1.0.1.0", "source": { "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" + "url": "https://github.com/drush-ops/config-extra.git", + "reference": "6bd3d5aa3ca7625115683f6e687285a3f1c48a54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "url": "https://api.github.com/repos/drush-ops/config-extra/zipball/6bd3d5aa3ca7625115683f6e687285a3f1c48a54", + "reference": "6bd3d5aa3ca7625115683f6e687285a3f1c48a54", "shasum": "" }, "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" + "php": ">=5.5.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": ">=3.5" }, - "time": "2017-03-20T17:10:46+00:00", + "time": "2015-10-16T21:32:27+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "8.0.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] + "psr-0": { + "Drush": "lib/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" }, { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" } ], - "description": "PSR-7 message implementation that also provides common utility methods", + "description": "Drush config-extra contains additional configuration Drush commands, notably config-merge.", "keywords": [ - "http", - "message", - "request", - "response", - "stream", - "uri", - "url" + "Drush" ] }, { - "name": "paragonie/random_compat", - "version": "v2.0.10", - "version_normalized": "2.0.10.0", + "name": "pear/console_table", + "version": "v1.3.0", + "version_normalized": "1.3.0.0", "source": { "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d" + "url": "https://github.com/pear/Console_Table.git", + "reference": "64100b9ee81852f4fa17823e55d0b385a544f976" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d", - "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d", + "url": "https://api.github.com/repos/pear/Console_Table/zipball/64100b9ee81852f4fa17823e55d0b385a544f976", + "reference": "64100b9ee81852f4fa17823e55d0b385a544f976", "shasum": "" }, "require": { "php": ">=5.2.0" }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*" - }, "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + "pear/Console_Color2": ">=0.1.2" }, - "time": "2017-03-13T16:27:32+00:00", + "time": "2016-01-21T16:14:31+00:00", "type": "library", "installation-source": "dist", "autoload": { - "files": [ - "lib/random.php" + "classmap": [ + "Table.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-2-Clause" ], "authors": [ { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" + "name": "Jan Schneider", + "homepage": "http://pear.php.net/user/yunosh" + }, + { + "name": "Tal Peer", + "homepage": "http://pear.php.net/user/tal" + }, + { + "name": "Xavier Noguer", + "homepage": "http://pear.php.net/user/xnoguer" + }, + { + "name": "Richard Heyes", + "homepage": "http://pear.php.net/user/richard" } ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "description": "Library that makes it easy to build console style tables.", + "homepage": "http://pear.php.net/package/Console_Table/", "keywords": [ - "csprng", - "pseudorandom", - "random" + "console" ] }, { - "name": "twig/twig", - "version": "v1.33.0", - "version_normalized": "1.33.0.0", + "name": "drupal/http2_server_push", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a" + "url": "https://git.drupal.org/project/http2_server_push", + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a", - "reference": "05cf49921b13f6f01d3cfdf9018cfa7a8086fd5a", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/http2_server_push-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "cc2df591201313f1407e55424cfe7cf35127fa47" }, "require": { - "php": ">=5.2.7" - }, - "require-dev": { - "psr/container": "^1.0", - "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~3.3@dev" + "drupal/core": "~8.0" }, - "time": "2017-03-22T15:40:09+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "1.33-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0", + "datestamp": "1489057084" } }, "installation-source": "dist", - "autoload": { - "psr-0": { - "Twig_": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - }, - { - "name": "Twig Team", - "homepage": "http://twig.sensiolabs.org/contributors", - "role": "Contributors" + "name": "Wim Leers", + "homepage": "https://www.drupal.org/user/99777" } ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org", - "keywords": [ - "templating" - ] + "description": "Pushes CSS & JS files to the client on servers using HTTP/2.", + "homepage": "https://www.drupal.org/project/http2_server_push", + "support": { + "source": "http://cgit.drupalcode.org/http2_server_push" + } }, { - "name": "drupal/simple_sitemap", - "version": "2.9.0", - "version_normalized": "2.9.0.0", + "name": "drupal/admin_toolbar", + "version": "1.19.0", + "version_normalized": "1.19.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/simple_sitemap", - "reference": "8.x-2.9" + "url": "https://git.drupal.org/project/admin_toolbar", + "reference": "8.x-1.19" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/simple_sitemap-8.x-2.9.zip", - "reference": "8.x-2.9", - "shasum": "73bc5b375a7563ee217688f752318fe044b1e9de" + "url": "https://ftp.drupal.org/files/projects/admin_toolbar-8.x-1.19.zip", + "reference": "8.x-1.19", + "shasum": "87de41eab3c5cd49d4e1b5b764cb3b9d5ad683a0" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "*" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-2.x": "2.x-dev" + "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-2.9", - "datestamp": "1490775483" + "version": "8.x-1.19", + "datestamp": "1491487683" } }, "installation-source": "dist", @@ -5356,51 +5184,62 @@ ], "authors": [ { - "name": "Pawel Ginalski (gbyte.co)", - "homepage": "https://www.drupal.org/u/gbyte.co", - "email": "contact@gbyte.co", - "role": "Maintainer" + "name": "Mohamed Anis Taktak", + "homepage": "https://www.drupal.org/u/matio89" }, { - "name": "Sam Becker (Sam152)", - "homepage": "https://www.drupal.org/u/sam152", - "role": "Co-maintainer" + "name": "eme", + "homepage": "https://www.drupal.org/user/542492" + }, + { + "name": "fethi.krout", + "homepage": "https://www.drupal.org/user/3206765" + }, + { + "name": "matio89", + "homepage": "https://www.drupal.org/user/2320090" + }, + { + "name": "romainj", + "homepage": "https://www.drupal.org/user/370706" } ], - "description": "Simple XML sitemap creates a standard conform XML sitemap of your content.", - "homepage": "https://drupal.org/project/simple_sitemap", + "description": "Admin Toolbar improve the default Drupal Toolbar, it lets the hover of sub menus.", + "homepage": "http://drupal.org/project/admin_toolbar", "support": { - "source": "https://cgit.drupalcode.org/simple_sitemap", - "issues": "https://drupal.org/project/issues/simple_sitemap", - "irc": "irc://irc.freenode.org/drupal-contribute" + "source": "http://cgit.drupalcode.org/admin_toolbar", + "issues": "https://www.drupal.org/project/issues/admin_toolbar" } }, { - "name": "drupal/fontyourface", - "version": "3.1.0", - "version_normalized": "3.1.0.0", + "name": "drupal/crop", + "version": "1.2.0", + "version_normalized": "1.2.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/fontyourface", - "reference": "8.x-3.1" + "url": "https://git.drupal.org/project/crop", + "reference": "8.x-1.2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/fontyourface-8.x-3.1.zip", - "reference": "8.x-3.1", - "shasum": "c5e02349327e4962dc15901ad442a887326b5b73" + "url": "https://ftp.drupal.org/files/projects/crop-8.x-1.2.zip", + "reference": "8.x-1.2", + "shasum": "0ad542254940c844f8a22c1b386131f06c665b4f" }, "require": { - "drupal/core": "8.*" + "drupal/core": "*" + }, + "require-dev": { + "drupal/media_entity": "*" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev" + "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-3.1", - "datestamp": "1490223783" + "version": "8.x-1.2", + "datestamp": "1491032884" } }, "installation-source": "dist", @@ -5410,660 +5249,576 @@ ], "authors": [ { - "name": "BTMash", - "homepage": "https://www.drupal.org/user/60422" - }, - { - "name": "BarisW", - "homepage": "https://www.drupal.org/user/107229" + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" }, { - "name": "Drave Robber", - "homepage": "https://www.drupal.org/user/984338" + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" }, { - "name": "sreynen", - "homepage": "https://www.drupal.org/user/109890" + "name": "woprrr", + "homepage": "https://www.drupal.org/user/858604" } ], - "description": "Web font management tools.", - "homepage": "https://www.drupal.org/project/fontyourface", - "keywords": [ - "Drupal" - ], + "description": "Provides storage and API for image crops.", + "homepage": "https://www.drupal.org/project/crop", "support": { - "source": "http://cgit.drupalcode.org/fontyourface", - "issues": "http://drupal.org/project/issues/fontyourface" + "source": "http://cgit.drupalcode.org/crop", + "issues": "https://www.drupal.org/project/issues/crop" } }, { - "name": "drupal/php", - "version": "dev-1.x", - "version_normalized": "dev-1.x", + "name": "zendframework/zend-diactoros", + "version": "1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/php", - "reference": "304022be52874ef2d7916ea3acafd312766da9cc" + "url": "https://github.com/zendframework/zend-diactoros.git", + "reference": "b03f285a333f51e58c95cce54109a4a9ed691436" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/b03f285a333f51e58c95cce54109a4a9ed691436", + "reference": "b03f285a333f51e58c95cce54109a4a9ed691436", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "php": "^5.4 || ^7.0", + "psr/http-message": "~1.0" }, - "type": "drupal-module", + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-dom": "*", + "ext-libxml": "*", + "phpunit/phpunit": "^4.6 || ^5.5", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "time": "2017-04-06T16:18:34+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0-beta2+1-dev", - "datestamp": "1461875939" + "dev-master": "1.4-dev", + "dev-develop": "1.5-dev" } }, - "installation-source": "source", - "notification-url": "https://packages.drupal.org/8/downloads", - "license": [ - "GPL-2.0+" - ], - "authors": [ - { - "name": "hass", - "homepage": "https://www.drupal.org/u/hass" - }, - { - "name": "See other contributors", - "homepage": "https://www.drupal.org/node/1633456/committers" - }, - { - "name": "catch", - "homepage": "https://www.drupal.org/user/35733" - }, - { - "name": "dixon_", - "homepage": "https://www.drupal.org/user/239911" - }, - { - "name": "greggles", - "homepage": "https://www.drupal.org/user/36762" - }, - { - "name": "hass", - "homepage": "https://www.drupal.org/user/85918" - }, - { - "name": "msonnabaum", - "homepage": "https://www.drupal.org/user/75278" - }, - { - "name": "quicksketch", - "homepage": "https://www.drupal.org/user/35821" - }, - { - "name": "webchick", - "homepage": "https://www.drupal.org/user/24967" + "installation-source": "dist", + "autoload": { + "psr-4": { + "Zend\\Diactoros\\": "src/" } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" ], - "description": "Allows embedded PHP code/snippets to be evaluated. Enabling this can cause security and performance issues as it allows users to execute PHP code on your site.", - "homepage": "https://www.drupal.org/project/php", - "support": { - "source": "http://git.drupal.org/project/php.git", - "issues": "https://www.drupal.org/project/issues/php" - } + "description": "PSR HTTP Message implementations", + "homepage": "https://github.com/zendframework/zend-diactoros", + "keywords": [ + "http", + "psr", + "psr-7" + ] }, { - "name": "cweagans/composer-patches", - "version": "1.6.1", - "version_normalized": "1.6.1.0", + "name": "symfony/psr-http-message-bridge", + "version": "v1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://github.com/cweagans/composer-patches.git", - "reference": "b3036f23b73570ab5d869e345277786c8eb248a9" + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "66085f246d3893cbdbcec5f5ad15ac60546cf0de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/b3036f23b73570ab5d869e345277786c8eb248a9", - "reference": "b3036f23b73570ab5d869e345277786c8eb248a9", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/66085f246d3893cbdbcec5f5ad15ac60546cf0de", + "reference": "66085f246d3893cbdbcec5f5ad15ac60546cf0de", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0", - "php": ">=5.3.0" + "php": ">=5.3.3", + "psr/http-message": "~1.0", + "symfony/http-foundation": "~2.3|~3.0" }, "require-dev": { - "composer/composer": "~1.0", - "phpunit/phpunit": "~4.6" + "symfony/phpunit-bridge": "~2.7|~3.0" }, - "time": "2017-03-19T18:18:52+00:00", - "type": "composer-plugin", + "suggest": { + "psr/http-message-implementation": "To use the HttpFoundation factory", + "zendframework/zend-diactoros": "To use the Zend Diactoros factory" + }, + "time": "2016-09-14T18:37:20+00:00", + "type": "symfony-bridge", "extra": { - "class": "cweagans\\Composer\\Patches" + "branch-alias": { + "dev-master": "1.0-dev" + } }, "installation-source": "dist", "autoload": { "psr-4": { - "cweagans\\Composer\\": "src" + "Symfony\\Bridge\\PsrHttpMessage\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-2-Clause" + "MIT" ], "authors": [ { - "name": "Cameron Eagans", - "email": "me@cweagans.net" + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Provides a way to patch Composer packages." + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-7" + ] }, { - "name": "drupal/security_review", - "version": "dev-1.x", - "version_normalized": "dev-1.x", + "name": "doctrine/common", + "version": "v2.7.2", + "version_normalized": "2.7.2.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/security_review", - "reference": "35ebae445bb260e961e47c4c58efe7c50c228999" + "url": "https://github.com/doctrine/common.git", + "reference": "930297026c8009a567ac051fd545bf6124150347" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/930297026c8009a567ac051fd545bf6124150347", + "reference": "930297026c8009a567ac051fd545bf6124150347", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~5.6|~7.0" }, - "type": "drupal-module", + "require-dev": { + "phpunit/phpunit": "^5.4.6" + }, + "time": "2017-01-13T14:02:13+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.x-dev", - "datestamp": "1476978839" - }, - "patches_applied": { - "Fix missing field review list": "https://www.drupal.org/files/issues/security_review-dangerous-tags-list-2744805-2.patch" + "dev-master": "2.7.x-dev" } }, - "installation-source": "source", - "notification-url": "https://packages.drupal.org/8/downloads", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "banviktor", - "homepage": "https://www.drupal.org/user/3176333" + "name": "Roman Borschel", + "email": "roman@code-factory.org" }, { - "name": "coltrane", - "homepage": "https://www.drupal.org/user/91990" + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" }, { - "name": "dsnopek", - "homepage": "https://www.drupal.org/user/266527" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "greggles", - "homepage": "https://www.drupal.org/user/36762" + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "Site security and configuration review module.", - "homepage": "https://www.drupal.org/project/security_review", - "support": { - "source": "http://cgit.drupalcode.org/security_review" - } + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ] }, { - "name": "drupal/memcache", - "version": "2.0.0-alpha2", - "version_normalized": "2.0.0.0-alpha2", + "name": "asm89/stack-cors", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/memcache", - "reference": "8.x-2.0-alpha2" + "url": "https://github.com/asm89/stack-cors.git", + "reference": "65ccbd455370f043c2e3b93482a3813603d68731" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/memcache-8.x-2.0-alpha2.zip", - "reference": "8.x-2.0-alpha2", - "shasum": "dedad417e274e06a064e282135ce2f05b2c2c6ba" + "url": "https://api.github.com/repos/asm89/stack-cors/zipball/65ccbd455370f043c2e3b93482a3813603d68731", + "reference": "65ccbd455370f043c2e3b93482a3813603d68731", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "php": ">=5.5.9", + "symfony/http-foundation": "~2.7|~3.0", + "symfony/http-kernel": "~2.7|~3.0" }, - "type": "drupal-module", + "require-dev": { + "phpunit/phpunit": "^5.0 || ^4.8.10", + "squizlabs/php_codesniffer": "^2.3" + }, + "time": "2017-04-11T20:03:41+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-2.x": "2.x-dev" - }, - "drupal": { - "version": "8.x-2.0-alpha2", - "datestamp": "1473758939" + "dev-master": "1.1-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Asm89\\Stack\\": "src/Asm89/Stack/" + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Jeremy", - "homepage": "https://www.drupal.org/user/409" - }, - { - "name": "catch", - "homepage": "https://www.drupal.org/user/35733" - }, - { - "name": "damiankloip", - "homepage": "https://www.drupal.org/user/1037976" - }, - { - "name": "jvandyk", - "homepage": "https://www.drupal.org/user/2375" - }, - { - "name": "robertDouglass", - "homepage": "https://www.drupal.org/user/5449" + "name": "Alexander", + "email": "iam.asm89@gmail.com" } ], - "description": "High performance integration with memcache.", - "homepage": "https://www.drupal.org/project/memcache", - "support": { - "source": "http://cgit.drupalcode.org/memcache" - } + "description": "Cross-origin resource sharing library and stack middleware", + "homepage": "https://github.com/asm89/stack-cors", + "keywords": [ + "cors", + "stack" + ] }, { - "name": "drupal/entity", - "version": "1.0.0-alpha4", - "version_normalized": "1.0.0.0-alpha4", + "name": "webmozart/assert", + "version": "1.2.0", + "version_normalized": "1.2.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/entity", - "reference": "8.x-1.0-alpha4" + "url": "https://github.com/webmozart/assert.git", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/entity-8.x-1.0-alpha4.zip", - "reference": "8.x-1.0-alpha4", - "shasum": "c081d3757c159dfee74c9e5acb63bdee81c42e18" + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "shasum": "" }, "require": { - "drupal/core": "~8.1" + "php": "^5.3.3 || ^7.0" }, - "type": "drupal-module", + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "time": "2016-11-23T20:04:58+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0-alpha4", - "datestamp": "1481194983" + "dev-master": "1.3-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Berdir", - "homepage": "https://www.drupal.org/user/214652" - }, - { - "name": "bojanz", - "homepage": "https://www.drupal.org/user/86106" - }, - { - "name": "dawehner", - "homepage": "https://www.drupal.org/user/99340" - }, - { - "name": "dixon_", - "homepage": "https://www.drupal.org/user/239911" - }, - { - "name": "fago", - "homepage": "https://www.drupal.org/user/16747" + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], - "description": "Provides expanded entity APIs, which will be moved to Drupal core one day.", - "homepage": "http://drupal.org/project/entity", - "support": { - "source": "http://cgit.drupalcode.org/entity" - } + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ] }, { - "name": "drupal/media_entity", - "version": "1.6.0", - "version_normalized": "1.6.0.0", + "name": "webmozart/path-util", + "version": "2.3.0", + "version_normalized": "2.3.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/media_entity", - "reference": "8.x-1.6" + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/media_entity-8.x-1.6.zip", - "reference": "8.x-1.6", - "shasum": "86fd1478f2448c034660faa30ef34c0e8519fecb" + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" }, "require": { - "drupal/core": "~8.1", - "drupal/entity": "^1.0.0-alpha3" + "php": ">=5.3.3", + "webmozart/assert": "~1.0" }, "require-dev": { - "drupal/entity": "*", - "drupal/inline_entity_form": "*" + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" }, - "type": "drupal-module", + "time": "2015-12-17T08:42:14+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.6", - "datestamp": "1480363983" + "dev-master": "2.3-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Berdir", - "homepage": "https://www.drupal.org/user/214652" - }, - { - "name": "Dave Reid", - "homepage": "https://www.drupal.org/user/53892" - }, - { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" - }, - { - "name": "Drupal media CI", - "homepage": "https://www.drupal.org/user/3057985" - }, - { - "name": "Primsi", - "homepage": "https://www.drupal.org/user/282629" - }, - { - "name": "boztek", - "homepage": "https://www.drupal.org/user/134410" - }, - { - "name": "chr.fritsch", - "homepage": "https://www.drupal.org/user/2103716" - }, - { - "name": "jcisio", - "homepage": "https://www.drupal.org/user/210762" - }, - { - "name": "katzilla", - "homepage": "https://www.drupal.org/user/260398" - }, - { - "name": "phenaproxima", - "homepage": "https://www.drupal.org/user/205645" - }, - { - "name": "seanB", - "homepage": "https://www.drupal.org/user/545912" - }, - { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], - "description": "Provides a lean and simple way to store media on Drupal 8 sites.", - "homepage": "https://www.drupal.org/project/media_entity", - "keywords": [ - "Drupal" - ], - "support": { - "source": "https://www.drupal.org/project/media_entity", - "issues": "https://www.drupal.org/project/issues/media_entity" - } + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths." }, { - "name": "drupal/video_embed_field", - "version": "1.4.0", - "version_normalized": "1.4.0.0", + "name": "consolidation/annotated-command", + "version": "2.4.8", + "version_normalized": "2.4.8.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/video_embed_field", - "reference": "8.x-1.4" + "url": "https://github.com/consolidation/annotated-command.git", + "reference": "6672ea38212f8bffb71fec7eadc8b3372154b17e" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/video_embed_field-8.x-1.4.zip", - "reference": "8.x-1.4", - "shasum": "7bf93a52e2e8d639b4dbefd65f0ee2b170d73f43" + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/6672ea38212f8bffb71fec7eadc8b3372154b17e", + "reference": "6672ea38212f8bffb71fec7eadc8b3372154b17e", + "shasum": "" }, "require": { - "drupal/core": "*" + "consolidation/output-formatters": "^3.1.5", + "php": ">=5.4.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "psr/log": "^1", + "symfony/console": "^2.8|~3", + "symfony/event-dispatcher": "^2.5|^3", + "symfony/finder": "^2.5|^3" }, "require-dev": { - "drupal/colorbox": "*", - "drupal/media_entity": "*", - "drupal/media_entity_embeddable_video": "*" + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "^2.7" }, - "type": "drupal-module", + "time": "2017-04-03T22:37:00+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.x", - "datestamp": "1484253183", - "package": "Field types" + "dev-master": "2.x-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Consolidation\\AnnotatedCommand\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Sam152", - "homepage": "https://www.drupal.org/user/1485048" - }, - { - "name": "jec006", - "homepage": "https://www.drupal.org/user/855980" - }, - { - "name": "plopesc", - "homepage": "https://www.drupal.org/user/282415" + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" } ], - "description": "A pluggable field type for storing videos from external video hosts such as Vimeo and YouTube.", - "homepage": "https://www.drupal.org/project/video_embed_field", - "support": { - "source": "http://cgit.drupalcode.org/video_embed_field" - } + "description": "Initialize Symfony Console commands from annotated command class methods." }, { - "name": "drupal/video_embed_media", - "version": "1.4.0", - "version_normalized": "1.4.0.0", + "name": "drupal/redirect", + "version": "1.0.0-alpha5", + "version_normalized": "1.0.0.0-alpha5", + "source": { + "type": "git", + "url": "https://git.drupal.org/project/redirect", + "reference": "8.x-1.0-alpha5" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/redirect-8.x-1.0-alpha5.zip", + "reference": "8.x-1.0-alpha5", + "shasum": "927aa4c8d8b40b0cd2442bee86f2f386d25e53ca" + }, "require": { - "drupal/core": "~8.0", - "drupal/media_entity": "*", - "drupal/video_embed_field": "self.version" + "drupal/core": "~8" }, - "type": "metapackage", + "type": "drupal-module", "extra": { "branch-alias": { "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.4", - "datestamp": "1484253183" + "version": "8.x-1.0-alpha5", + "datestamp": "1492182542" } }, + "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Sam152", - "homepage": "https://www.drupal.org/user/1485048" - }, - { - "name": "jec006", - "homepage": "https://www.drupal.org/user/855980" + "name": "Berdir", + "homepage": "https://www.drupal.org/user/214652" }, { - "name": "plopesc", - "homepage": "https://www.drupal.org/user/282415" + "name": "Dave Reid", + "homepage": "https://www.drupal.org/user/53892" } ], - "description": "Integrates video_embed_field with the media_entity module, creating a new media type tailored to display embedded videos. Useful for websites which are using the media suite of modules.", - "homepage": "https://www.drupal.org/project/video_embed_field", + "description": "Allows users to redirect from old URLs to new URLs.", + "homepage": "https://www.drupal.org/project/redirect", "support": { - "source": "http://cgit.drupalcode.org/video_embed_field" + "source": "http://cgit.drupalcode.org/redirect" } }, { - "name": "drupal/blazy", - "version": "1.0.0-rc1", - "version_normalized": "1.0.0.0-RC1", + "name": "geedmo/yamm3", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/blazy", - "reference": "8.x-1.0-rc1" + "url": "https://github.com/geedmo/yamm3.git", + "reference": "5aa11451340187cce1bc195a4437937b19535508" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/blazy-8.x-1.0-rc1.zip", - "reference": "8.x-1.0-rc1", - "shasum": "0502916f2cb5b6237f13e5216e12063b8d56ce42" - }, - "require": { - "drupal/core": "*" - }, - "type": "drupal-module", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0-rc1", - "datestamp": "1485193983" - } + "url": "https://api.github.com/repos/geedmo/yamm3/zipball/5aa11451340187cce1bc195a4437937b19535508", + "reference": "5aa11451340187cce1bc195a4437937b19535508", + "shasum": "" }, + "time": "2015-04-04T12:59:29+00:00", + "type": "library", "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Gaus Surahman", - "homepage": "https://www.drupal.org/u/gausarts", - "role": "Maintainer" - }, - { - "name": "Contributors", - "homepage": "https://www.drupal.org/node/2663268/committers", - "role": "Contributor" + "name": "German Morales", + "email": "geedmo.ds@gmail.com", + "homepage": "http://geedmo.com" } ], - "description": "Provides basic bLazy integration for lazy loading and multi-serving images.", - "homepage": "https://drupal.org/project/blazy", + "description": "Yet another megamenu for Bootstrap 3.x", + "homepage": "http://geedmo.github.io/yamm3/", "keywords": [ - "Drupal", - "bLazy", - "lazyload" - ], - "support": { - "source": "http://cgit.drupalcode.org/blazy", - "issues": "https://drupal.org/project/issues/blazy" - } + "bootstrap", + "megadropdown", + "megamenu" + ] }, { - "name": "drupal/slick", - "version": "1.0.0-rc3", - "version_normalized": "1.0.0.0-RC3", + "name": "grom358/pharborist", + "version": "dev-master", + "version_normalized": "9999999-dev", "source": { "type": "git", - "url": "https://git.drupal.org/project/slick", - "reference": "8.x-1.0-rc3" + "url": "https://github.com/grom358/pharborist.git", + "reference": "0db9e51299a80e95b06857ed1809f59bbbab1af6" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/slick-8.x-1.0-rc3.zip", - "reference": "8.x-1.0-rc3", - "shasum": "e47be5189e3d03e2824a6ecfd41f14c45eea9a55" + "url": "https://api.github.com/repos/grom358/pharborist/zipball/0db9e51299a80e95b06857ed1809f59bbbab1af6", + "reference": "0db9e51299a80e95b06857ed1809f59bbbab1af6", + "shasum": "" }, "require": { - "drupal/blazy": "~1.0", - "drupal/core": "~8.0" + "php": ">=5.4", + "phpdocumentor/reflection-docblock": "2.0.*" }, - "type": "drupal-module", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0-rc3", - "datestamp": "1490295783" + "require-dev": { + "apigen/apigen": "2.8.*", + "phpunit/phpunit": "4.2.*" + }, + "time": "2015-09-20T22:14:29+00:00", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-4": { + "Pharborist\\": "src/" } }, - "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "GPL" ], "authors": [ { - "name": "arshadcn", - "homepage": "https://www.drupal.org/user/571032" - }, - { - "name": "gausarts", - "homepage": "https://www.drupal.org/user/159062" + "name": "Cameron Zemek", + "role": "lead" } ], - "description": "Slick carousel, the last carousel you'll ever need.", - "homepage": "https://drupal.org/project/slick", + "description": "Pharborist builds a syntax tree for PHP that can be traversed and manipulated.", "keywords": [ - "Drupal", - "carousel", - "slideshow" - ], - "support": { - "source": "http://cgit.drupalcode.org/slick", - "issues": "https://drupal.org/project/issues/slick" - } + "standards", + "syntax" + ] }, { - "name": "drupal/media_entity_image", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "name": "drupal/drupalmoduleupgrader", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://git.drupal.org/project/media_entity_image", - "reference": "8.x-1.2" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/media_entity_image-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "d02d1d793a50ea3b9cb5a3219472fdd27980f4f3" + "url": "https://git.drupal.org/project/drupalmoduleupgrader", + "reference": "8bf2d9c140d4a315f267ff511fc69ea1595b62b8" }, "require": { - "drupal/core": "~8.1", - "drupal/media_entity": "~1.0 || ~8.1.0" + "cebe/markdown": "1.0.*@dev", + "drupal/core": "~8.0", + "grom358/pharborist": "dev-master", + "symfony/filesystem": "^2.6.0", + "symfony/finder": "^2.6.0" }, "require-dev": { - "drupal/entity_browser": "*" + "mikey179/vfsstream": "^1.5", + "phpunit/phpunit": "^4.8" }, "type": "drupal-module", "extra": { @@ -6071,70 +5826,107 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1470170939" + "version": "8.x-1.2+9-dev", + "datestamp": "1490452983" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "Drupal\\drupalmoduleupgrader\\": "src/" } }, - "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" + "name": "Gábor Hojtsy", + "homepage": "https://www.drupal.org/user/4166" }, { - "name": "Primsi", - "homepage": "https://www.drupal.org/user/282629" + "name": "Wim Leers", + "homepage": "https://www.drupal.org/user/99777" }, { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "dstol", + "homepage": "https://www.drupal.org/user/329570" + }, + { + "name": "eshta", + "homepage": "https://www.drupal.org/user/1951462" + }, + { + "name": "japerry", + "homepage": "https://www.drupal.org/user/45640" + }, + { + "name": "jcnventura", + "homepage": "https://www.drupal.org/user/122464" + }, + { + "name": "pfrenssen", + "homepage": "https://www.drupal.org/user/382067" + }, + { + "name": "phenaproxima", + "homepage": "https://www.drupal.org/user/205645" + }, + { + "name": "tim.plunkett", + "homepage": "https://www.drupal.org/user/241634" + }, + { + "name": "webchick", + "homepage": "https://www.drupal.org/user/24967" + }, + { + "name": "xjm", + "homepage": "https://www.drupal.org/user/65776" } ], - "description": "Local images integration for Drupal Media entity.", - "homepage": "https://www.drupal.org/project/media_entity_image", + "description": "A Drush command to update Drupal 7 modules to Drupal 8.", + "homepage": "https://www.drupal.org/project/drupalmoduleupgrader", "keywords": [ "Drupal", - "image", - "media" + "PHP_CodeSniffer", + "phpcs", + "standards", + "update", + "upgrade" ], "support": { - "source": "https://www.drupal.org/project/media_entity_image", - "issues": "https://www.drupal.org/project/issues/media_entity_image" + "source": "https://drupal.org/project/drupalmoduleupgrader", + "issues": "https://drupal.org/project/issues/drupalmoduleupgrader" } }, { - "name": "drupal/slick_media", - "version": "1.0.0-rc1", - "version_normalized": "1.0.0.0-RC1", + "name": "drupal/htmlawed", + "version": "3.2.0", + "version_normalized": "3.2.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/slick_media", - "reference": "8.x-1.0-rc1" + "url": "https://git.drupal.org/project/htmLawed", + "reference": "8.x-3.2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/slick_media-8.x-1.0-rc1.zip", - "reference": "8.x-1.0-rc1", - "shasum": "061addb670bc7af541b90880aac1c78da7c96812" + "url": "https://ftp.drupal.org/files/projects/htmlawed-8.x-3.2.zip", + "reference": "8.x-3.2", + "shasum": "9ced09e67458a0efcd7c4cc7e83f05fb4035ddcc" }, "require": { - "drupal/core": "~8.0", - "drupal/media_entity_image": "*", - "drupal/slick": "*", - "drupal/video_embed_media": "*" + "drupal/core": "~8.0" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-3.x": "3.x-dev" }, "drupal": { - "version": "8.x-1.0-rc1", - "datestamp": "1485194885" + "version": "8.x-3.2", + "datestamp": "1480745884" } }, "installation-source": "dist", @@ -6144,96 +5936,42 @@ ], "authors": [ { - "name": "gausarts", - "homepage": "https://www.drupal.org/user/159062" + "name": "alpha2zee", + "homepage": "https://www.drupal.org/user/201451" } ], - "description": "Provides Slick carousel integration with Media entity.", - "homepage": "https://www.drupal.org/project/slick_media", + "description": "Use htmLawed to restrict and correct HTML for compliance with admin. policy and standards and for security", + "homepage": "https://www.drupal.org/project/htmlawed", "support": { - "source": "http://cgit.drupalcode.org/slick_media" + "source": "http://cgit.drupalcode.org/htmlawed" } }, { - "name": "j7mbo/twitter-api-php", - "version": "1.0.5", - "version_normalized": "1.0.5.0", - "source": { - "type": "git", - "url": "https://github.com/J7mbo/twitter-api-php.git", - "reference": "a89ce3e294484aad7ae13dbabe45fb3928024ef8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/J7mbo/twitter-api-php/zipball/a89ce3e294484aad7ae13dbabe45fb3928024ef8", - "reference": "a89ce3e294484aad7ae13dbabe45fb3928024ef8", - "shasum": "" - }, - "require": { - "ext-curl": "*" - }, - "require-dev": { - "phpunit/phpunit": "~4.5,>=4.5.1" - }, - "time": "2015-08-03T21:35:18+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "TwitterAPIExchange.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GNU Public License" - ], - "authors": [ - { - "name": "James Mallison", - "homepage": "https://github.com/j7mbo/twitter-api-php" - } - ], - "description": "Simple PHP Wrapper for Twitter API v1.1 calls", - "homepage": "https://github.com/j7mbo/twitter-api-php", - "keywords": [ - "api", - "php", - "twitter" - ] - }, - { - "name": "drupal/media_entity_twitter", - "version": "1.3.0", - "version_normalized": "1.3.0.0", + "name": "drupal/ctools", + "version": "3.0.0", + "version_normalized": "3.0.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/media_entity_twitter", - "reference": "8.x-1.3" + "url": "https://git.drupal.org/project/ctools", + "reference": "8.x-3.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/media_entity_twitter-8.x-1.3.zip", - "reference": "8.x-1.3", - "shasum": "280406ba63e2c00befa9bb1434ad2d4d3113b239" + "url": "https://ftp.drupal.org/files/projects/ctools-8.x-3.0.zip", + "reference": "8.x-3.0", + "shasum": "302e869ecd1e59fe55663673999fee2ccac5daa8" }, "require": { - "drupal/core": "~8.0", - "drupal/media_entity": "*", - "j7mbo/twitter-api-php": "~1.0" + "drupal/core": "~8.0" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-3.x": "3.x-dev" }, "drupal": { - "version": "8.x-1.3", - "datestamp": "1478549339" + "version": "8.x-3.0", + "datestamp": "1493401742" } }, "installation-source": "dist", @@ -6243,42 +5981,78 @@ ], "authors": [ { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" + "name": "Kris Vanderwater (EclipseGc)", + "homepage": "https://www.drupal.org/u/eclipsegc", + "role": "Maintainer" }, { - "name": "Primsi", - "homepage": "https://www.drupal.org/user/282629" + "name": "Jakob Perry (japerry)", + "homepage": "https://www.drupal.org/u/japerry", + "role": "Maintainer" }, { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "Tim Plunkett (tim.plunkett)", + "homepage": "https://www.drupal.org/u/timplunkett", + "role": "Maintainer" + }, + { + "name": "James Gilliland (neclimdul)", + "homepage": "https://www.drupal.org/u/neclimdul", + "role": "Maintainer" + }, + { + "name": "Daniel Wehner (dawehner)", + "homepage": "https://www.drupal.org/u/dawehner", + "role": "Maintainer" + }, + { + "name": "merlinofchaos", + "homepage": "https://www.drupal.org/user/26979" + }, + { + "name": "neclimdul", + "homepage": "https://www.drupal.org/user/48673" + }, + { + "name": "sdboyer", + "homepage": "https://www.drupal.org/user/146719" + }, + { + "name": "sun", + "homepage": "https://www.drupal.org/user/54136" + }, + { + "name": "tim.plunkett", + "homepage": "https://www.drupal.org/user/241634" } ], - "description": "Media entity Twitter provider.", - "homepage": "https://www.drupal.org/project/media_entity_twitter", + "description": "Provides a number of utility and helper APIs for Drupal developers and site builders.", + "homepage": "https://www.drupal.org/project/ctools", "support": { - "source": "http://cgit.drupalcode.org/media_entity_twitter" + "source": "http://cgit.drupalcode.org/ctools", + "issues": "https://www.drupal.org/project/issues/ctools" } }, { - "name": "drupal/media_entity_slideshow", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "name": "drupal/devel", + "version": "1.0.0-rc2", + "version_normalized": "1.0.0.0-RC2", "source": { "type": "git", - "url": "https://git.drupal.org/project/media_entity_slideshow", - "reference": "8.x-1.2" + "url": "https://git.drupal.org/project/devel", + "reference": "8.x-1.0-rc2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/media_entity_slideshow-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "c9d49eb6be7de0ea8e500554b89842842287cd1f" + "url": "https://ftp.drupal.org/files/projects/devel-8.x-1.0-rc2.zip", + "reference": "8.x-1.0-rc2", + "shasum": "011322bf9c263dab29f94640829f4b654e9c5632" }, "require": { - "drupal/core": "~8.0", - "drupal/media_entity": "*" + "drupal/core": "~8.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available" }, "type": "drupal-module", "extra": { @@ -6286,8 +6060,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1470687839" + "version": "8.x-1.0-rc2", + "datestamp": "1492989244" } }, "installation-source": "dist", @@ -6297,83 +6071,132 @@ ], "authors": [ { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" + "name": "Moshe Weitzman", + "homepage": "https://github.com/weitzman", + "email": "weitzman@tejasa.com", + "role": "Maintainer" }, { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "Hans Salvisberg", + "homepage": "https://www.drupal.org/u/salvis", + "email": "drupal@salvisberg.com", + "role": "Maintainer" + }, + { + "name": "Luca Lusso", + "homepage": "https://www.drupal.org/u/lussoluca", + "role": "Maintainer" + }, + { + "name": "Marco (willzyx)", + "homepage": "https://www.drupal.org/u/willzyx", + "role": "Maintainer" + }, + { + "name": "See contributors", + "homepage": "https://www.drupal.org/node/3236/committers" + }, + { + "name": "salvis", + "homepage": "https://www.drupal.org/user/82964" + }, + { + "name": "willzyx", + "homepage": "https://www.drupal.org/user/1043862" } ], - "description": "Media entity slideshow provider.", - "homepage": "https://www.drupal.org/project/media_entity_slideshow", + "description": "Various blocks, pages, and functions for developers.", + "homepage": "http://drupal.org/project/devel", "support": { - "source": "http://cgit.drupalcode.org/media_entity_slideshow" + "source": "http://cgit.drupalcode.org/devel", + "issues": "http://drupal.org/project/devel", + "irc": "irc://irc.freenode.org/drupal-contribute" } }, { - "name": "php-instagram-api/php-instagram-api", - "version": "dev-master", - "version_normalized": "9999999-dev", + "name": "drupal/token", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://github.com/galen/PHP-Instagram-API.git", - "reference": "7a796fdae715fcdccc00590933ce482437342c35" + "url": "https://git.drupal.org/project/token", + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/galen/PHP-Instagram-API/zipball/7a796fdae715fcdccc00590933ce482437342c35", - "reference": "7a796fdae715fcdccc00590933ce482437342c35", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/token-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "d24c7f1ffddbd0fc56bc92bacae1c4ff769a4442" }, "require": { - "php": ">=5.3.0" + "drupal/core": "~8.0" }, - "time": "2013-11-13T23:10:03+00:00", - "type": "library", - "installation-source": "source", - "autoload": { - "psr-0": { - "Instagram": "." + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0", + "datestamp": "1493466843" } }, - "notification-url": "https://packagist.org/downloads/", + "installation-source": "dist", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Galen Grover", - "email": "galenjr@gmail.com", - "homepage": "http://www.galengrover.com", - "role": "Developer" + "name": "Berdir", + "homepage": "https://www.drupal.org/user/214652" + }, + { + "name": "Dave Reid", + "homepage": "https://www.drupal.org/user/53892" + }, + { + "name": "eaton", + "homepage": "https://www.drupal.org/user/16496" + }, + { + "name": "fago", + "homepage": "https://www.drupal.org/user/16747" + }, + { + "name": "greggles", + "homepage": "https://www.drupal.org/user/36762" + }, + { + "name": "mikeryan", + "homepage": "https://www.drupal.org/user/4420" } ], - "description": "PHP Instagram API for PHP 5.3+", - "homepage": "https://github.com/galen/PHP-Instagram-API", - "keywords": [ - "instagram" - ] + "description": "Provides a user interface for the Token API and some missing core tokens.", + "homepage": "https://www.drupal.org/project/token", + "support": { + "source": "http://cgit.drupalcode.org/token" + } }, { - "name": "drupal/media_entity_instagram", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "name": "drupal/pathauto", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/media_entity_instagram", - "reference": "8.x-1.2" + "url": "https://git.drupal.org/project/pathauto", + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/media_entity_instagram-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "1183314bbfed2dfeaeabdc7e970521b394c5e337" + "url": "https://ftp.drupal.org/files/projects/pathauto-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "4c82a5689a18421c8c73fcc8be7b333bb21ae02a" }, "require": { - "drupal/core": "~8.0", - "drupal/media_entity": "*", - "php-instagram-api/php-instagram-api": "dev-master" + "drupal/core": "*", + "drupal/ctools": "*", + "drupal/token": "*" }, "type": "drupal-module", "extra": { @@ -6381,8 +6204,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1470169139" + "version": "8.x-1.0", + "datestamp": "1493468044" } }, "installation-source": "dist", @@ -6392,162 +6215,145 @@ ], "authors": [ { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" + "name": "Berdir", + "homepage": "https://www.drupal.org/user/214652" }, { - "name": "Primsi", - "homepage": "https://www.drupal.org/user/282629" + "name": "Dave Reid", + "homepage": "https://www.drupal.org/user/53892" }, { - "name": "designesse", - "homepage": "https://www.drupal.org/user/854012" + "name": "Freso", + "homepage": "https://www.drupal.org/user/27504" }, { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "greggles", + "homepage": "https://www.drupal.org/user/36762" } ], - "description": "Provides a media entity instagram.", - "homepage": "https://www.drupal.org/project/media_entity_instagram", + "description": "Provides a mechanism for modules to automatically generate aliases for the content they manage.", + "homepage": "https://www.drupal.org/project/pathauto", "support": { - "source": "http://cgit.drupalcode.org/media_entity_instagram" + "source": "http://cgit.drupalcode.org/pathauto" } }, { - "name": "drupal/media_entity_document", - "version": "1.1.0", - "version_normalized": "1.1.0.0", + "name": "drupal/views_bootstrap", + "version": "dev-3.x", + "version_normalized": "dev-3.x", "source": { "type": "git", - "url": "https://git.drupal.org/project/media_entity_document", - "reference": "8.x-1.1" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/media_entity_document-8.x-1.1.zip", - "reference": "8.x-1.1", - "shasum": "88a45820cf0aeb5f8a3ade3338007771191508e4" + "url": "https://git.drupal.org/project/views_bootstrap", + "reference": "ef95dac8dfeb8f2d61b0e5d40075a0a6e23e53ca" }, "require": { - "drupal/core": "~8.1", - "drupal/media_entity": "~1.0 || ~8.1.0" + "drupal/core": "*" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-3.x": "3.x-dev" }, "drupal": { - "version": "8.x-1.1", - "datestamp": "1470211995" + "version": "8.x-3.x-dev", + "datestamp": "1490369283" } }, - "installation-source": "dist", + "installation-source": "source", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "NerOcrO", - "homepage": "https://www.drupal.org/user/1728164", - "role": "Maintainer" - } - ], - "description": "Local documents integration for Drupal Media entity.", - "homepage": "https://www.drupal.org/project/media_entity_document", - "keywords": [ - "Drupal", - "document", - "media" - ], + "name": "aburrows", + "homepage": "https://www.drupal.org/user/577844" + }, + { + "name": "ericpugh", + "homepage": "https://www.drupal.org/user/130084" + }, + { + "name": "ikeigenwijs", + "homepage": "https://www.drupal.org/user/583238" + }, + { + "name": "mrded", + "homepage": "https://www.drupal.org/user/556088" + } + ], + "description": "Integrate the Bootstrap framework with Views.", + "homepage": "https://www.drupal.org/project/views_bootstrap", + "keywords": [ + "Drupal" + ], "support": { - "source": "https://www.drupal.org/project/media_entity_document", - "issues": "https://www.drupal.org/project/issues/media_entity_document" + "source": "http://cgit.drupalcode.org/views_bootstrap" } }, { - "name": "drupal/inline_entity_form", - "version": "1.0.0-beta1", - "version_normalized": "1.0.0.0-beta1", + "name": "drupal/views_responsive_grid", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://git.drupal.org/project/inline_entity_form", - "reference": "8.x-1.0-beta1" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/inline_entity_form-8.x-1.0-beta1.zip", - "reference": "8.x-1.0-beta1", - "shasum": "185ffc28a7b68d19cce057855d1c111f1741a3ea" + "url": "https://git.drupal.org/project/views_responsive_grid", + "reference": "b8478ccf4cb6dc6837a0c1170a848e418499a357" }, "require": { "drupal/core": "~8.0" }, - "require-dev": { - "drupal/entity_reference_revisions": "*" - }, "type": "drupal-module", "extra": { "branch-alias": { "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-beta1", - "datestamp": "1477868343" + "version": "8.x-1.x-dev", + "datestamp": "1373985289" } }, - "installation-source": "dist", + "installation-source": "source", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "bojanz", - "homepage": "https://www.drupal.org/user/86106" - }, - { - "name": "dawehner", - "homepage": "https://www.drupal.org/user/99340" - }, - { - "name": "rszrama", - "homepage": "https://www.drupal.org/user/49344" + "name": "iwhitcomb", + "homepage": "https://www.drupal.org/user/771654" }, { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "kyletaylored", + "homepage": "https://www.drupal.org/user/2207088" }, { - "name": "webflo", - "homepage": "https://www.drupal.org/user/254778" + "name": "markcarver", + "homepage": "https://www.drupal.org/user/501638" } ], - "description": "Provides a widget for inline management (creation, modification, removal) of referenced entities.", - "homepage": "https://www.drupal.org/project/inline_entity_form", + "homepage": "https://www.drupal.org/project/views_responsive_grid", "support": { - "source": "http://cgit.drupalcode.org/inline_entity_form" + "source": "http://cgit.drupalcode.org/views_responsive_grid" } }, { - "name": "drupal/embed", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "name": "drupal/imagemagick", + "version": "1.0.0-alpha6", + "version_normalized": "1.0.0.0-alpha6", "source": { "type": "git", - "url": "https://git.drupal.org/project/embed", - "reference": "8.x-1.0" + "url": "https://git.drupal.org/project/imagemagick", + "reference": "8.x-1.0-alpha6" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/embed-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "cc746ad807260e01c7788dd82110dcebbb4d678a" + "url": "https://ftp.drupal.org/files/projects/imagemagick-8.x-1.0-alpha6.zip", + "reference": "8.x-1.0-alpha6", + "shasum": "9631b407762076b2f5d9bf3b50b40c28976ddbb7" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "^8.1.0" }, "type": "drupal-module", "extra": { @@ -6555,8 +6361,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1490755685" + "version": "8.x-1.0-alpha6", + "datestamp": "1488787683" } }, "installation-source": "dist", @@ -6566,64 +6372,78 @@ ], "authors": [ { - "name": "Dave Reid", - "homepage": "https://www.drupal.org/user/53892" + "name": "chx", + "homepage": "https://www.drupal.org/user/9446" }, { - "name": "Devin Carlson", - "homepage": "https://www.drupal.org/user/290182" + "name": "claudiu.cristea", + "homepage": "https://www.drupal.org/user/56348" }, { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" + "name": "dman", + "homepage": "https://www.drupal.org/user/33240" }, { - "name": "cs_shadow", - "homepage": "https://www.drupal.org/user/2828287" + "name": "dopry", + "homepage": "https://www.drupal.org/user/22202" }, { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "drewish", + "homepage": "https://www.drupal.org/user/34869" + }, + { + "name": "gdl", + "homepage": "https://www.drupal.org/user/507326" + }, + { + "name": "mondrake", + "homepage": "https://www.drupal.org/user/1307444" + }, + { + "name": "quicksketch", + "homepage": "https://www.drupal.org/user/35821" + }, + { + "name": "sun", + "homepage": "https://www.drupal.org/user/54136" + }, + { + "name": "walkah", + "homepage": "https://www.drupal.org/user/1531" } ], - "description": "Provide a framework for various different types of embeds in WYSIWYG editors, common functionality, interfaces, and standards.", - "homepage": "https://www.drupal.org/project/embed", + "description": "Provides ImageMagick integration.", + "homepage": "https://www.drupal.org/project/imagemagick", "support": { - "source": "http://cgit.drupalcode.org/embed", - "issues": "https://www.drupal.org/project/issues/embed", - "irc": "irc://irc.freenode.org/drupal-media" + "source": "http://cgit.drupalcode.org/imagemagick" } }, { - "name": "drupal/entity_embed", - "version": "1.0.0-beta2", - "version_normalized": "1.0.0.0-beta2", + "name": "drupal/bootstrap", + "version": "3.5.0", + "version_normalized": "3.5.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/entity_embed", - "reference": "8.x-1.0-beta2" + "url": "https://git.drupal.org/project/bootstrap", + "reference": "8.x-3.5" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/entity_embed-8.x-1.0-beta2.zip", - "reference": "8.x-1.0-beta2", - "shasum": "21cdeb2b058efce461683aed9a8951053512dca7" + "url": "https://ftp.drupal.org/files/projects/bootstrap-8.x-3.5.zip", + "reference": "8.x-3.5", + "shasum": "569f8a243ad6a2e04a86123a0b2a594783a09860" }, "require": { - "drupal/core": "*", - "drupal/embed": "*" - }, - "require-dev": { - "drupal/entity_browser": "*" + "drupal/core": "~8.0" }, - "type": "drupal-module", + "type": "drupal-theme", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-3.x": "3.x-dev" }, "drupal": { - "version": "8.x-1.0-beta2", - "datestamp": "1476698339" + "version": "8.x-3.5", + "datestamp": "1495040301" } }, "installation-source": "dist", @@ -6633,207 +6453,229 @@ ], "authors": [ { - "name": "Dave Reid", - "homepage": "https://www.drupal.org/user/53892" - }, - { - "name": "Devin Carlson", - "homepage": "https://www.drupal.org/user/290182" + "name": "markcarver", + "homepage": "https://www.drupal.org/user/501638" }, { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" + "name": "neardark", + "homepage": "https://www.drupal.org/user/661076" }, { - "name": "cs_shadow", - "homepage": "https://www.drupal.org/user/2828287" + "name": "sylus", + "homepage": "https://www.drupal.org/user/339714" }, { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "wundo", + "homepage": "https://www.drupal.org/user/25523" } ], - "description": "Allows any entity to be embedded within a text area using a WYSIWYG editor.", - "homepage": "https://www.drupal.org/project/entity_embed", + "homepage": "https://www.drupal.org/project/bootstrap", "support": { - "source": "http://cgit.drupalcode.org/entity_embed", - "issues": "https://www.drupal.org/project/issues/entity_embed", - "irc": "irc://irc.freenode.org/drupal-media" + "source": "http://cgit.drupalcode.org/bootstrap" } }, { - "name": "drupal/entity_browser", - "version": "1.0.0-rc2", - "version_normalized": "1.0.0.0-RC2", + "name": "sunra/php-simple-html-dom-parser", + "version": "v1.5.2", + "version_normalized": "1.5.2.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/entity_browser", - "reference": "8.x-1.0-rc2" + "url": "https://github.com/sunra/php-simple-html-dom-parser.git", + "reference": "75b9b1cb64502d8f8c04dc11b5906b969af247c6" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/entity_browser-8.x-1.0-rc2.zip", - "reference": "8.x-1.0-rc2", - "shasum": "7954668b9134a8ec2dac2604c482d6521e43ee91" + "url": "https://api.github.com/repos/sunra/php-simple-html-dom-parser/zipball/75b9b1cb64502d8f8c04dc11b5906b969af247c6", + "reference": "75b9b1cb64502d8f8c04dc11b5906b969af247c6", + "shasum": "" }, "require": { - "drupal/core": "~8.0" - }, - "require-dev": { - "drupal/ctools": "*", - "drupal/inline_entity_form": "*", - "drupal/media_entity": "*", - "drupal/paragraphs": "*", - "drupal/token": "*" + "ext-mbstring": "*", + "php": ">=5.3.2" }, - "type": "drupal-module", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev", - "dev-8.x-1.x": "8.1.x-dev" - }, - "drupal": { - "version": "8.x-1.0-rc2", - "datestamp": "1487581984" + "time": "2016-11-22T22:57:47+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Sunra\\PhpSimple\\HtmlDomParser": "Src/" } }, - "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Janez Urevc", - "homepage": "https://github.com/slashrsm", - "role": "Maintainer" - }, - { - "name": "Primoz Hmeljak", - "homepage": "https://github.com/primsi", - "role": "Maintainer" + "name": "Sunra", + "email": "sunra@yandex.ru", + "homepage": "https://github.com/sunra" }, { - "name": "See other contributors", - "homepage": "https://www.drupal.org/node/1943336/committers", - "role": "contributor" - }, - { - "name": "Primsi", - "homepage": "https://www.drupal.org/user/282629" - }, - { - "name": "marcingy", - "homepage": "https://www.drupal.org/user/77320" - }, - { - "name": "samuel.mortenson", - "homepage": "https://www.drupal.org/user/2582268" - }, - { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "S.C. Chen", + "homepage": "http://sourceforge.net/projects/simplehtmldom/" } ], - "description": "Entity browsing and selecting component.", - "homepage": "http://drupal.org/project/entity_browser", - "support": { - "source": "http://cgit.drupalcode.org/entity_browser", - "issues": "http://drupal.org/project/issues/entity_browser", - "irc": "irc://irc.freenode.org/drupal-contribute" - } + "description": "Composer adaptation of: A HTML DOM parser written in PHP5+ let you manipulate HTML in a very easy way! Require PHP 5+. Supports invalid HTML. Find tags on an HTML page with selectors just like jQuery. Extract contents from HTML in a single line.", + "homepage": "https://github.com/sunra/php-simple-html-dom-parser", + "keywords": [ + "dom", + "html", + "parser" + ] }, { - "name": "drupal/entity_browser_entity_form", - "version": "1.0.0-rc2", - "version_normalized": "1.0.0.0-RC2", + "name": "mkalkbrenner/php-htmldiff-advanced", + "version": "0.0.8", + "version_normalized": "0.0.8.0", + "source": { + "type": "git", + "url": "https://github.com/mkalkbrenner/php-htmldiff.git", + "reference": "3a714b48c9c3d3730baaf6d3949691e654cd37c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mkalkbrenner/php-htmldiff/zipball/3a714b48c9c3d3730baaf6d3949691e654cd37c9", + "reference": "3a714b48c9c3d3730baaf6d3949691e654cd37c9", + "shasum": "" + }, + "require": { + "caxy/php-htmldiff": ">=0.0.6", + "php": ">=5.5.0" + }, + "time": "2016-07-25T17:07:32+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/HtmlDiffAdvancedInterface.php", + "src/HtmlDiffAdvanced.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GNU General Public License V2" + ], + "description": "An add-on for the php-htmldiff library for comparing two HTML files/snippets and highlighting the differences using simple HTML.", + "homepage": "https://github.com/mkalkbrenner/php-htmldiff", + "keywords": [ + "diff", + "html" + ] + }, + { + "name": "drupal/diff", + "version": "1.0.0-rc1", + "version_normalized": "1.0.0.0-RC1", + "source": { + "type": "git", + "url": "https://git.drupal.org/project/diff", + "reference": "8.x-1.0-rc1" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/diff-8.x-1.0-rc1.zip", + "reference": "8.x-1.0-rc1", + "shasum": "4945154c2c07444195a7ae07011a3b3db941c72a" + }, "require": { "drupal/core": "~8.0", - "drupal/entity_browser": "self.version", - "drupal/inline_entity_form": "*" + "mkalkbrenner/php-htmldiff-advanced": "~0.0.8" }, - "type": "metapackage", + "type": "drupal-module", "extra": { "branch-alias": { "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-rc2", - "datestamp": "1487581984" + "version": "8.x-1.0-rc1", + "datestamp": "1484566683" } }, + "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Dave Reid", - "homepage": "https://www.drupal.org/user/53892" + "name": "Miro Dietiker (miro_dietiker)", + "homepage": "https://www.drupal.org/u/miro_dietiker", + "role": "Maintainer" }, { - "name": "Devin Carlson", - "homepage": "https://www.drupal.org/user/290182" + "name": "Juampy NR (juampynr)", + "homepage": "https://www.drupal.org/u/juampynr", + "role": "Maintainer" }, { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" + "name": "Lucian Hangea (lhangea)", + "homepage": "https://www.drupal.org/u/lhangea", + "role": "Maintainer" }, { - "name": "Primsi", - "homepage": "https://www.drupal.org/user/282629" + "name": "Alan D.", + "homepage": "https://www.drupal.org/u/alan-d.", + "role": "Maintainer" }, { - "name": "marcingy", - "homepage": "https://www.drupal.org/user/77320" + "name": "Brian Gilbert (realityloop).", + "homepage": "https://www.drupal.org/u/realityloop", + "role": "Maintainer" }, { - "name": "samuel.mortenson", - "homepage": "https://www.drupal.org/user/2582268" + "name": "miro_dietiker", + "homepage": "https://www.drupal.org/user/227761" }, { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "realityloop", + "homepage": "https://www.drupal.org/user/139189" + }, + { + "name": "rötzi", + "homepage": "https://www.drupal.org/user/73064" + }, + { + "name": "yhahn", + "homepage": "https://www.drupal.org/user/264833" } ], - "description": "Entity browser inline entity form integration.", - "homepage": "https://www.drupal.org/project/entity_browser", + "description": "Compares two entity revisions", + "homepage": "https://www.drupal.org/project/diff", "support": { - "source": "http://cgit.drupalcode.org/entity_browser" + "source": "http://cgit.drupalcode.org/diff", + "issues": "https://www.drupal.org/project/issues/diff" } }, { - "name": "drupal/dropzonejs", - "version": "1.0.0-alpha6", - "version_normalized": "1.0.0.0-alpha6", + "name": "drupal/hacked", + "version": "2.0.0-beta1", + "version_normalized": "2.0.0.0-beta1", "source": { "type": "git", - "url": "https://git.drupal.org/project/dropzonejs", - "reference": "8.x-1.0-alpha6" + "url": "https://git.drupal.org/project/hacked", + "reference": "8.x-2.0-beta1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/dropzonejs-8.x-1.0-alpha6.zip", - "reference": "8.x-1.0-alpha6", - "shasum": "7cc19398eed42b584c06e442f57c4da64b4c4bbb" + "url": "https://ftp.drupal.org/files/projects/hacked-8.x-2.0-beta1.zip", + "reference": "8.x-2.0-beta1", + "shasum": "97b091470b83b3bdfe9a13673c5c676b3ce0414a" }, "require": { "drupal/core": "*" }, - "require-dev": { - "drupal/entity_browser": "*" - }, - "suggest": { - "enyo/dropzone": "Required to user drupal/dropzonejs. Dropzone is an easy to use drag'n'drop library." - }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-2.x": "2.x-dev" }, "drupal": { - "version": "8.x-1.0-alpha6", - "datestamp": "1490199183" + "version": "8.x-2.0-beta1", + "datestamp": "1453154039" + }, + "patches_applied": { + "Compatibility with diff module API change: Turn EntityComparisonBase into a service": "https://www.drupal.org/files/issues/hacked-diff-diff-service-2800645-2.patch" } }, "installation-source": "dist", @@ -6843,152 +6685,130 @@ ], "authors": [ { - "name": "Janez Urevc", - "homepage": "https://drupal.org/u/slashrsm", - "role": "Maintainer" - }, - { - "name": "Christian Fritsch", - "homepage": "https://drupal.org/u/chrfritsch", - "role": "Maintainer" - }, - { - "name": "Primoz Hmeljak", - "homepage": "https://drupal.org/u/Primsi", - "role": "Maintainer" - }, - { - "name": "See other contributors", - "homepage": "https://www.drupal.org/node/1998478/committers", - "role": "contributor" - }, - { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" - }, - { - "name": "wouters_f", - "homepage": "https://www.drupal.org/user/721548" + "name": "Deciphered", + "homepage": "https://www.drupal.org/user/103796" }, { - "name": "zkday", - "homepage": "https://www.drupal.org/user/888644" + "name": "Steven Jones", + "homepage": "https://www.drupal.org/user/99644" } ], - "description": "Drupal integration for DropzoneJS - An open source library that provides drag’n’drop file uploads with image previews.", - "homepage": "https://www.drupal.org/project/dropzonejs", - "keywords": [ - "DropzoneJS", - "Drupal" - ], + "description": "Shows if drupal or any of its modules have been changed", + "homepage": "https://www.drupal.org/project/hacked", "support": { - "source": "https://www.drupal.org/project/dropzonejs", - "issues": "https://www.drupal.org/project/issues/dropzonejs", - "irc": "irc://irc.freenode.org/drupal-contribute" + "source": "http://cgit.drupalcode.org/hacked" } }, { - "name": "drupal/dropzonejs_eb_widget", - "version": "1.0.0-alpha6", - "version_normalized": "1.0.0.0-alpha6", + "name": "drupal/permissions_by_term", + "version": "1.19.0", + "version_normalized": "1.19.0.0", + "source": { + "type": "git", + "url": "https://git.drupal.org/project/permissions_by_term", + "reference": "8.x-1.19" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/permissions_by_term-8.x-1.19.zip", + "reference": "8.x-1.19", + "shasum": "87ecf60dda39138f648ee57fe4e3ce334b187100" + }, "require": { - "drupal/core": "*", - "drupal/dropzonejs": "self.version", - "drupal/entity_browser": "*" + "drupal/core": "*" }, - "type": "metapackage", + "type": "drupal-module", "extra": { "branch-alias": { "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-alpha6", - "datestamp": "1490199183" + "version": "8.x-1.19", + "datestamp": "1494360188" } }, + "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" - }, - { - "name": "Drupal media CI", - "homepage": "https://www.drupal.org/user/3057985" - }, - { - "name": "Primsi", - "homepage": "https://www.drupal.org/user/282629" - }, - { - "name": "chr.fritsch", - "homepage": "https://www.drupal.org/user/2103716" - }, - { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" - }, - { - "name": "wouters_f", - "homepage": "https://www.drupal.org/user/721548" + "name": "Peter Majmesku", + "homepage": "https://www.drupal.org/user/786132" + } + ], + "description": "Limits the selection of specific taxonomy terms by users or roles. Prevents users to display nodes and nodes on views pages, for which which they do not have access by taxonomy term restriction.", + "homepage": "https://www.drupal.org/project/permissions_by_term", + "support": { + "source": "http://cgit.drupalcode.org/permissions_by_term" + } + }, + { + "name": "drupal/linkit", + "version": "4.3.0", + "version_normalized": "4.3.0.0", + "source": { + "type": "git", + "url": "https://git.drupal.org/project/linkit", + "reference": "8.x-4.3" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/linkit-8.x-4.3.zip", + "reference": "8.x-4.3", + "shasum": "e624ea2f18a6100b76a8337e24f7c08df6e2235e" + }, + "require": { + "drupal/core": "~8.0" + }, + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-4.x": "4.x-dev" }, + "drupal": { + "version": "8.x-4.3", + "datestamp": "1490205830" + } + }, + "installation-source": "dist", + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ { - "name": "zkday", - "homepage": "https://www.drupal.org/user/888644" + "name": "Emil Stjerneman", + "homepage": "https://stjerneman.com", + "email": "emil@stjerneman.com", + "role": "Maintainer" } ], - "description": "DropzoneJS Entity browser widget", - "homepage": "https://www.drupal.org/project/dropzonejs", + "description": "Linkit - Enriched linking experience", + "homepage": "http://drupal.org/project/linkit", "support": { - "source": "http://cgit.drupalcode.org/dropzonejs" + "source": "http://cgit.drupalcode.org/linkit", + "issues": "http://drupal.org/project/linkit" } }, { - "name": "drupal/media", - "version": "dev-1.x", - "version_normalized": "dev-1.x", + "name": "drupal/toc_formatter", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/media", - "reference": "b9d72f21ea20c583ec4b83081720eba65670a8da" + "url": "https://git.drupal.org/project/toc_formatter", + "reference": "8.x-1.1" }, - "require": { - "drupal/core": "*", - "drupal/dropzonejs_eb_widget": "*", - "drupal/entity_browser": "*", - "drupal/entity_browser_entity_form": "*", - "drupal/entity_embed": "*", - "drupal/image_widget_crop": "*", - "drupal/inline_entity_form": "*", - "drupal/media_entity": "*", - "drupal/media_entity_document": "*", - "drupal/media_entity_image": "*", - "drupal/media_entity_instagram": "*", - "drupal/media_entity_slideshow": "*", - "drupal/media_entity_twitter": "*", - "drupal/slick_media": "*", - "drupal/video_embed_field": "*", - "drupal/video_embed_media": "*" + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/toc_formatter-8.x-1.1.zip", + "reference": "8.x-1.1", + "shasum": "7da3ef22b5d2e3e93b48fe97cd17ce607a264a9e" }, - "require-dev": { - "drupal/dropzonejs_eb_widget": "*", - "drupal/entity_browser": "*", - "drupal/entity_browser_entity_form": "*", - "drupal/entity_embed": "*", - "drupal/image_widget_crop": "*", - "drupal/inline_entity_form": "*", - "drupal/media_entity": "*", - "drupal/media_entity_document": "*", - "drupal/media_entity_image": "*", - "drupal/media_entity_instagram": "*", - "drupal/media_entity_slideshow": "*", - "drupal/media_entity_twitter": "*", - "drupal/slick_media": "*", - "drupal/video_embed_field": "*", - "drupal/video_embed_media": "*" + "require": { + "drupal/core": "~8.0" }, "type": "drupal-module", "extra": { @@ -6996,1007 +6816,1071 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.x-dev", - "datestamp": "1476811139" + "version": "8.x-1.1", + "datestamp": "1398611927" } }, - "installation-source": "source", + "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Dave Reid", - "homepage": "https://www.drupal.org/user/53892" - }, - { - "name": "David_Rothstein", - "homepage": "https://www.drupal.org/user/124982" - }, - { - "name": "Devin Carlson", - "homepage": "https://www.drupal.org/user/290182" - }, - { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" - }, - { - "name": "ParisLiakos", - "homepage": "https://www.drupal.org/user/1011436" + "name": "Robert Castelo", + "homepage": "https://www.drupal.org/user/3555" }, { - "name": "arthurf", - "homepage": "https://www.drupal.org/user/27259" + "name": "neilt17", + "homepage": "https://www.drupal.org/user/324142" + } + ], + "description": "Display formatter that adds a TOC to the top of a text area field.", + "homepage": "https://www.drupal.org/project/toc_formatter", + "support": { + "source": "http://cgit.drupalcode.org/toc_formatter" + } + }, + { + "name": "drupal/advagg", + "version": "2.4.0", + "version_normalized": "2.4.0.0", + "source": { + "type": "git", + "url": "https://git.drupal.org/project/advagg", + "reference": "8.x-2.4" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/advagg-8.x-2.4.zip", + "reference": "8.x-2.4", + "shasum": "b3a0eb8739d940b7171718227ec30e8ef4ccbb1b" + }, + "require": { + "drupal/core": "~8.0" + }, + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" }, + "drupal": { + "version": "8.x-2.4", + "datestamp": "1493949188" + } + }, + "installation-source": "dist", + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ { - "name": "becw", - "homepage": "https://www.drupal.org/user/81067" + "name": "Mike Carper (mikeytown2)", + "homepage": "https://www.drupal.org/u/mikeytown2", + "role": "Creator, Maintainer" }, { - "name": "effulgentsia", - "homepage": "https://www.drupal.org/user/78040" + "name": "Nick Wilde (nickwilde)", + "homepage": "https://www.drupal.org/u/nickwilde", + "email": "design@briarmoon.ca", + "role": "Drupal 8 Port/maintainer" }, { - "name": "joseph.olstad", - "homepage": "https://www.drupal.org/user/1321830" + "name": "doublejosh", + "homepage": "https://www.drupal.org/user/199720" }, { - "name": "ksenzee", - "homepage": "https://www.drupal.org/user/139855" + "name": "iamcarrico", + "homepage": "https://www.drupal.org/user/1300542" }, { - "name": "paul.lovvik", - "homepage": "https://www.drupal.org/user/289213" + "name": "markcarver", + "homepage": "https://www.drupal.org/user/501638" }, { - "name": "robeano", - "homepage": "https://www.drupal.org/user/67660" + "name": "mikeytown2", + "homepage": "https://www.drupal.org/user/282446" }, { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "rupl", + "homepage": "https://www.drupal.org/user/411999" } ], - "description": "Media module for Drupal", - "homepage": "https://github.com/drupal-media/media/", + "description": "Improved aggregation of CSS/JS files to speed up page load times.", + "homepage": "https://drupal.org/project/advagg", "support": { - "source": "http://cgit.drupalcode.org/media", + "source": "https://cgit.drupalcode.org/advagg", + "issues": "https://drupal.org/project/issues/advagg", "irc": "irc://irc.freenode.org/drupal-contribute" } }, { - "name": "zendframework/zend-feed", - "version": "2.8.0", - "version_normalized": "2.8.0.0", + "name": "drupal/videojs", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://github.com/zendframework/zend-feed.git", - "reference": "94579e805dd108683209fe14b3b5d4276de3de6e" + "url": "https://git.drupal.org/project/videojs", + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-feed/zipball/94579e805dd108683209fe14b3b5d4276de3de6e", - "reference": "94579e805dd108683209fe14b3b5d4276de3de6e", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/videojs-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "daf810898fbae1cf608ad45fd4e836bd6935949d" }, "require": { - "php": "^5.6 || ^7.0", - "zendframework/zend-escaper": "^2.5", - "zendframework/zend-stdlib": "^2.7 || ^3.1" + "drupal/core": "~8.0" }, - "require-dev": { - "phpunit/phpunit": "^6.0.8 || ^5.7.15", - "psr/http-message": "^1.0", - "zendframework/zend-cache": "^2.6", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-db": "^2.7", - "zendframework/zend-http": "^2.5.4", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-validator": "^2.6" - }, - "suggest": { - "psr/http-message": "PSR-7 ^1.0, if you wish to use Zend\\Feed\\Reader\\Http\\Psr7ResponseDecorator", - "zendframework/zend-cache": "Zend\\Cache component, for optionally caching feeds between requests", - "zendframework/zend-db": "Zend\\Db component, for use with PubSubHubbub", - "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for easily extending ExtensionManager implementations", - "zendframework/zend-validator": "Zend\\Validator component, for validating email addresses used in Atom feeds and entries ehen using the Writer subcomponent" - }, - "time": "2017-04-01T15:03:14+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "2.8-dev", - "dev-develop": "2.9-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0", + "datestamp": "1454344739" + }, + "patches_applied": { + "videojs-isapplicable": "https://www.drupal.org/files/issues/videojs-isapplicable.patch" } }, "installation-source": "dist", - "autoload": { - "psr-4": { - "Zend\\Feed\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "BSD-3-Clause" + "GPL-2.0+" ], - "description": "provides functionality for consuming RSS and Atom feeds", - "homepage": "https://github.com/zendframework/zend-feed", - "keywords": [ - "feed", - "zf2" - ] + "authors": [ + { + "name": "Jorrit", + "homepage": "https://www.drupal.org/user/161217" + }, + { + "name": "heshanlk", + "homepage": "https://www.drupal.org/user/199102" + } + ], + "description": "Video.js is an HTML5 Video Player.", + "homepage": "https://www.drupal.org/project/videojs", + "support": { + "source": "http://cgit.drupalcode.org/videojs" + } }, { - "name": "enyo/dropzone", - "version": "v4.3.0", - "version_normalized": "4.3.0.0", + "name": "drupal/ckeditor_widgets", + "version": "dev-1.x", + "version_normalized": "dev-1.x", "source": { "type": "git", - "url": "https://github.com/enyo/dropzone.git", - "reference": "d8ef7a82e6ab5447c1f2d9512c8e1bfd4de5ac9e" + "url": "https://git.drupal.org/project/ckeditor_widgets", + "reference": "2d462637f8804b6d0b530604d0376e97a23a3b7f" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/enyo/dropzone/zipball/d8ef7a82e6ab5447c1f2d9512c8e1bfd4de5ac9e", - "reference": "d8ef7a82e6ab5447c1f2d9512c8e1bfd4de5ac9e", - "shasum": "" + "require": { + "drupal/core": "*" }, - "time": "2016-02-14T04:19:41+00:00", - "type": "library", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.x-dev", + "datestamp": "1472798939" + } + }, + "installation-source": "source", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Matias Meno", - "email": "m@tias.me", - "homepage": "http://www.matiasmeno.com" + "name": "jlyon", + "homepage": "https://www.drupal.org/user/256444" } ], - "description": "Handles drag and drop of files for you.", - "homepage": "http://www.dropzonejs.com", - "keywords": [ - "drag and drop", - "dragndrop", - "file upload", - "upload" - ] + "description": "Adds widgets and an Insert Template menu to CKEditor", + "homepage": "https://www.drupal.org/project/ckeditor_widgets", + "support": { + "source": "http://cgit.drupalcode.org/ckeditor_widgets" + } }, { - "name": "symfony/debug", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "drupal/layout_plugin", + "version": "1.0.0-alpha23", + "version_normalized": "1.0.0.0-alpha23", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "e90099a2958d4833a02d05b504cc06e1c234abcc" + "url": "https://git.drupal.org/project/layout_plugin", + "reference": "8.x-1.0-alpha23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/e90099a2958d4833a02d05b504cc06e1c234abcc", - "reference": "e90099a2958d4833a02d05b504cc06e1c234abcc", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/layout_plugin-8.x-1.0-alpha23.zip", + "reference": "8.x-1.0-alpha23", + "shasum": "c79992e2f52ac6a7c8dc0706512f2c70fc9f5e11" }, "require": { - "php": ">=5.3.9", - "psr/log": "~1.0" - }, - "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" - }, - "require-dev": { - "symfony/class-loader": "~2.2|~3.0.0", - "symfony/http-kernel": "~2.3.24|~2.5.9|^2.6.2|~3.0.0" + "drupal/core": "~8.0" }, - "time": "2017-02-18T19:13:35+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0-alpha23", + "datestamp": "1476269960" } }, "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "David Snopek", + "homepage": "https://www.drupal.org/user/172527" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Bram Goffings", + "homepage": "https://www.drupal.org/user/266527" + }, + { + "name": "Fredrik Lassen", + "homepage": "https://www.drupal.org/user/243377" } ], - "description": "Symfony Debug Component", - "homepage": "https://symfony.com" + "description": "An API module to hold the Drupal 8 plugin manager for layouts.", + "homepage": "https://www.drupal.org/project/layout_plugin", + "keywords": [ + "layout", + "php" + ], + "support": { + "source": "http://cgit.drupalcode.org/layout_plugin" + } }, { - "name": "symfony/console", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "drupal/bootstrap_layouts", + "version": "4.1.0", + "version_normalized": "4.1.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "86407ff20855a5eaa2a7219bd815e9c40a88633e" + "url": "https://git.drupal.org/project/bootstrap_layouts", + "reference": "8.x-4.1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/86407ff20855a5eaa2a7219bd815e9c40a88633e", - "reference": "86407ff20855a5eaa2a7219bd815e9c40a88633e", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/bootstrap_layouts-8.x-4.1.zip", + "reference": "8.x-4.1", + "shasum": "3f1e7598e9a476e4d396ddc1e49cd2851e948a2c" }, "require": { - "php": ">=5.3.9", - "symfony/debug": "^2.7.2|~3.0.0", - "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": "" + "drupal/core": "~8.0", + "drupal/layout_plugin": "*" }, - "time": "2017-04-03T20:37:06+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-4.x": "4.x-dev" + }, + "drupal": { + "version": "8.x-4.1", + "datestamp": "1481413087" } }, "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "darol100", + "homepage": "https://www.drupal.org/user/2667123" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "hctom", + "homepage": "https://www.drupal.org/user/112790" + }, + { + "name": "markcarver", + "homepage": "https://www.drupal.org/user/501638" } ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com" + "description": "This module is going to generate layouts with Bootstrap grid system.", + "homepage": "https://www.drupal.org/project/bootstrap_layouts", + "support": { + "source": "http://cgit.drupalcode.org/bootstrap_layouts" + } }, { - "name": "symfony/event-dispatcher", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "drupal/tocify", + "version": "1.2.0", + "version_normalized": "1.2.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "88b65f0ac25355090e524aba4ceb066025df8bd2" + "url": "https://git.drupal.org/project/tocify", + "reference": "8.x-1.2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/88b65f0ac25355090e524aba4ceb066025df8bd2", - "reference": "88b65f0ac25355090e524aba4ceb066025df8bd2", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/tocify-8.x-1.2.zip", + "reference": "8.x-1.2", + "shasum": "687ea298fa66b6e79addd8af25204917acfd0209" }, "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^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" + "drupal/core": "*" }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "time": "2017-04-03T20:37:06+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.2", + "datestamp": "1493816586" } }, "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com" - }, - { - "name": "symfony/yaml", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "286d84891690b0e2515874717e49360d1c98a703" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/286d84891690b0e2515874717e49360d1c98a703", - "reference": "286d84891690b0e2515874717e49360d1c98a703", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "time": "2017-03-20T09:41:44+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" + "name": "Hydra", + "homepage": "https://www.drupal.org/user/647364" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "dawehner", + "homepage": "https://www.drupal.org/user/99340" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "sanduhrs", + "homepage": "https://www.drupal.org/user/28074" } ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com" + "description": "Tocify your content", + "homepage": "https://www.drupal.org/project/tocify", + "keywords": [ + "Drupal" + ], + "support": { + "source": "http://cgit.drupalcode.org/tocify", + "issues": "http://drupal.org/project/issues/tocify" + } }, { - "name": "symfony/finder", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "drupal/ckeditor_templates", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "7131327eb95d86d72039fd1216226c28f36fd02a" + "url": "https://git.drupal.org/project/ckeditor_templates", + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/7131327eb95d86d72039fd1216226c28f36fd02a", - "reference": "7131327eb95d86d72039fd1216226c28f36fd02a", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/ckeditor_templates-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "706be94033bb2babf6fd0fb499c6aa326914b7ff" }, "require": { - "php": ">=5.3.9" + "drupal/core": "*" }, - "time": "2017-03-20T08:46:40+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0", + "datestamp": "1490206982" } }, "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "lucaslg", + "homepage": "https://www.drupal.org/user/3128975" } ], - "description": "Symfony Finder Component", - "homepage": "https://symfony.com" + "description": "Integrates the CKEdito templates plugin", + "homepage": "https://www.drupal.org/project/ckeditor_templates", + "support": { + "source": "http://cgit.drupalcode.org/ckeditor_templates" + } }, { - "name": "drush/config-extra", - "version": "1.0.1", - "version_normalized": "1.0.1.0", + "name": "drupal/layouter", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://github.com/drush-ops/config-extra.git", - "reference": "6bd3d5aa3ca7625115683f6e687285a3f1c48a54" + "url": "https://git.drupal.org/project/layouter", + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drush-ops/config-extra/zipball/6bd3d5aa3ca7625115683f6e687285a3f1c48a54", - "reference": "6bd3d5aa3ca7625115683f6e687285a3f1c48a54", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/layouter-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "c9bc5f4c178acabc06bdec71662f7c7c3df614ce" }, "require": { - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": ">=3.5" + "drupal/core": "*" }, - "time": "2015-10-16T21:32:27+00:00", - "type": "library", + "type": "drupal-module", "extra": { "branch-alias": { - "dev-master": "8.0.x-dev" + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.0", + "datestamp": "1470121439" } }, "installation-source": "dist", - "autoload": { - "psr-0": { - "Drush": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0+" + "GPL 2.0+" ], "authors": [ { - "name": "Moshe Weitzman", - "email": "weitzman@tejasa.com" + "name": "adci_contributor", + "homepage": "https://www.drupal.org/user/1830536" }, { - "name": "Greg Anderson", - "email": "greg.1.anderson@greenknowe.org" - } - ], - "description": "Drush config-extra contains additional configuration Drush commands, notably config-merge.", - "keywords": [ - "Drush" - ] - }, - { - "name": "symfony/filesystem", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "31ab6827a696244094e6e20d77e7d404f8eb4252" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/31ab6827a696244094e6e20d77e7d404f8eb4252", - "reference": "31ab6827a696244094e6e20d77e7d404f8eb4252", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "time": "2017-03-26T15:40:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" + "name": "adcillc", + "homepage": "https://www.drupal.org/user/366450" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "antongp", + "homepage": "https://www.drupal.org/user/1060446" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "kinosura", + "homepage": "https://www.drupal.org/user/383326" + }, + { + "name": "usdv", + "homepage": "https://www.drupal.org/user/2476206" } ], - "description": "Symfony Filesystem Component", - "homepage": "https://symfony.com" + "description": "Allows to choose one of predefined layouts which is applied to the content that you want to put into textarea fields.", + "homepage": "https://www.drupal.org/project/layouter", + "support": { + "source": "http://cgit.drupalcode.org/layouter" + } }, { - "name": "symfony/config", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "drupal/core", + "version": "8.3.4", + "version_normalized": "8.3.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "35b7dfa089d7605eb1fdd46281b3070fb9f38750" + "url": "https://github.com/drupal/core.git", + "reference": "f34eee7255142ab5416107972ef13d011f11e163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/35b7dfa089d7605eb1fdd46281b3070fb9f38750", - "reference": "35b7dfa089d7605eb1fdd46281b3070fb9f38750", + "url": "https://api.github.com/repos/drupal/core/zipball/f34eee7255142ab5416107972ef13d011f11e163", + "reference": "f34eee7255142ab5416107972ef13d011f11e163", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/filesystem": "~2.3|~3.0.0" - }, - "require-dev": { - "symfony/yaml": "~2.7|~3.0.0" - }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" + "asm89/stack-cors": "~1.0", + "composer/semver": "~1.0", + "doctrine/annotations": "1.2.*", + "doctrine/common": "^2.5", + "easyrdf/easyrdf": "0.9.*", + "egulias/email-validator": "1.2.*", + "guzzlehttp/guzzle": "^6.2.1", + "masterminds/html5": "~2.1", + "paragonie/random_compat": "^1.0|^2.0", + "php": ">=5.5.9", + "stack/builder": "1.0.*", + "symfony-cmf/routing": "~1.4", + "symfony/class-loader": "~2.8", + "symfony/console": "~2.8", + "symfony/dependency-injection": "~2.8", + "symfony/event-dispatcher": "~2.8", + "symfony/http-foundation": "~2.8", + "symfony/http-kernel": "~2.8", + "symfony/polyfill-iconv": "~1.0", + "symfony/process": "~2.8", + "symfony/psr-http-message-bridge": "^1.0", + "symfony/routing": "~2.8", + "symfony/serializer": "~2.8", + "symfony/translation": "~2.8", + "symfony/validator": "~2.8", + "symfony/yaml": "~2.8", + "twig/twig": "^1.23.1", + "zendframework/zend-diactoros": "~1.1", + "zendframework/zend-feed": "~2.4" }, - "time": "2017-04-04T15:24:26+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } + "conflict": { + "drush/drush": "<8.1.10" + }, + "replace": { + "drupal/action": "self.version", + "drupal/aggregator": "self.version", + "drupal/automated_cron": "self.version", + "drupal/ban": "self.version", + "drupal/bartik": "self.version", + "drupal/basic_auth": "self.version", + "drupal/big_pipe": "self.version", + "drupal/block": "self.version", + "drupal/block_content": "self.version", + "drupal/block_place": "self.version", + "drupal/book": "self.version", + "drupal/breakpoint": "self.version", + "drupal/ckeditor": "self.version", + "drupal/classy": "self.version", + "drupal/color": "self.version", + "drupal/comment": "self.version", + "drupal/config": "self.version", + "drupal/config_translation": "self.version", + "drupal/contact": "self.version", + "drupal/content_moderation": "self.version", + "drupal/content_translation": "self.version", + "drupal/contextual": "self.version", + "drupal/core-annotation": "self.version", + "drupal/core-assertion": "self.version", + "drupal/core-bridge": "self.version", + "drupal/core-datetime": "self.version", + "drupal/core-dependency-injection": "self.version", + "drupal/core-diff": "self.version", + "drupal/core-discovery": "self.version", + "drupal/core-event-dispatcher": "self.version", + "drupal/core-file-cache": "self.version", + "drupal/core-filesystem": "self.version", + "drupal/core-gettext": "self.version", + "drupal/core-graph": "self.version", + "drupal/core-http-foundation": "self.version", + "drupal/core-php-storage": "self.version", + "drupal/core-plugin": "self.version", + "drupal/core-proxy-builder": "self.version", + "drupal/core-render": "self.version", + "drupal/core-serialization": "self.version", + "drupal/core-transliteration": "self.version", + "drupal/core-utility": "self.version", + "drupal/core-uuid": "self.version", + "drupal/datetime": "self.version", + "drupal/datetime_range": "self.version", + "drupal/dblog": "self.version", + "drupal/dynamic_page_cache": "self.version", + "drupal/editor": "self.version", + "drupal/entity_reference": "self.version", + "drupal/field": "self.version", + "drupal/field_layout": "self.version", + "drupal/field_ui": "self.version", + "drupal/file": "self.version", + "drupal/filter": "self.version", + "drupal/forum": "self.version", + "drupal/hal": "self.version", + "drupal/help": "self.version", + "drupal/history": "self.version", + "drupal/image": "self.version", + "drupal/inline_form_errors": "self.version", + "drupal/language": "self.version", + "drupal/layout_discovery": "self.version", + "drupal/link": "self.version", + "drupal/locale": "self.version", + "drupal/menu_link_content": "self.version", + "drupal/menu_ui": "self.version", + "drupal/migrate": "self.version", + "drupal/migrate_drupal": "self.version", + "drupal/migrate_drupal_ui": "self.version", + "drupal/minimal": "self.version", + "drupal/node": "self.version", + "drupal/options": "self.version", + "drupal/outside_in": "self.version", + "drupal/page_cache": "self.version", + "drupal/path": "self.version", + "drupal/quickedit": "self.version", + "drupal/rdf": "self.version", + "drupal/responsive_image": "self.version", + "drupal/rest": "self.version", + "drupal/search": "self.version", + "drupal/serialization": "self.version", + "drupal/seven": "self.version", + "drupal/shortcut": "self.version", + "drupal/simpletest": "self.version", + "drupal/standard": "self.version", + "drupal/stark": "self.version", + "drupal/statistics": "self.version", + "drupal/syslog": "self.version", + "drupal/system": "self.version", + "drupal/taxonomy": "self.version", + "drupal/telephone": "self.version", + "drupal/text": "self.version", + "drupal/toolbar": "self.version", + "drupal/tour": "self.version", + "drupal/tracker": "self.version", + "drupal/update": "self.version", + "drupal/user": "self.version", + "drupal/views": "self.version", + "drupal/views_ui": "self.version", + "drupal/workflows": "self.version" + }, + "require-dev": { + "behat/mink": "1.7.x-dev", + "behat/mink-goutte-driver": "~1.2", + "drupal/coder": "8.2.12", + "jcalderonzumba/gastonjs": "~1.0.2", + "jcalderonzumba/mink-phantomjs-driver": "~0.3.1", + "mikey179/vfsstream": "~1.2", + "phpunit/phpunit": ">=4.8.28 <5", + "symfony/browser-kit": ">=2.8.13 <3.0", + "symfony/css-selector": "~2.8" }, + "time": "2017-06-21T18:13:27+00:00", + "type": "drupal-core", "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\Config\\": "" + "Drupal\\Core\\": "lib/Drupal/Core", + "Drupal\\Component\\": "lib/Drupal/Component", + "Drupal\\Driver\\": "../drivers/lib/Drupal/Driver" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "lib/Drupal.php", + "lib/Drupal/Component/Utility/Timer.php", + "lib/Drupal/Component/Utility/Unicode.php", + "lib/Drupal/Core/Database/Database.php", + "lib/Drupal/Core/DrupalKernel.php", + "lib/Drupal/Core/DrupalKernelInterface.php", + "lib/Drupal/Core/Site/Settings.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } + "GPL-2.0+" ], - "description": "Symfony Config Component", - "homepage": "https://symfony.com" + "description": "Drupal is an open source content management platform powering millions of websites and applications." }, { - "name": "pear/console_table", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", + "name": "drupal-composer/drupal-scaffold", + "version": "2.3.0", + "version_normalized": "2.3.0.0", "source": { "type": "git", - "url": "https://github.com/pear/Console_Table.git", - "reference": "64100b9ee81852f4fa17823e55d0b385a544f976" + "url": "https://github.com/drupal-composer/drupal-scaffold.git", + "reference": "1374e1031b98beb502abea3854f361304965c628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pear/Console_Table/zipball/64100b9ee81852f4fa17823e55d0b385a544f976", - "reference": "64100b9ee81852f4fa17823e55d0b385a544f976", + "url": "https://api.github.com/repos/drupal-composer/drupal-scaffold/zipball/1374e1031b98beb502abea3854f361304965c628", + "reference": "1374e1031b98beb502abea3854f361304965c628", "shasum": "" }, "require": { - "php": ">=5.2.0" + "composer-plugin-api": "^1.0.0", + "php": ">=5.4.5" }, - "suggest": { - "pear/Console_Color2": ">=0.1.2" + "require-dev": { + "composer/composer": "dev-master", + "phpunit/phpunit": "^4.4.0" + }, + "time": "2017-05-05T21:26:28+00:00", + "type": "composer-plugin", + "extra": { + "class": "DrupalComposer\\DrupalScaffold\\Plugin", + "branch-alias": { + "dev-master": "2.0.x-dev" + } }, - "time": "2016-01-21T16:14:31+00:00", - "type": "library", "installation-source": "dist", "autoload": { - "classmap": [ - "Table.php" - ] + "psr-4": { + "DrupalComposer\\DrupalScaffold\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Jan Schneider", - "homepage": "http://pear.php.net/user/yunosh" - }, - { - "name": "Tal Peer", - "homepage": "http://pear.php.net/user/tal" - }, - { - "name": "Xavier Noguer", - "homepage": "http://pear.php.net/user/xnoguer" - }, - { - "name": "Richard Heyes", - "homepage": "http://pear.php.net/user/richard" - } + "GPL-2.0+" ], - "description": "Library that makes it easy to build console style tables.", - "homepage": "http://pear.php.net/package/Console_Table/", - "keywords": [ - "console" - ] + "description": "Composer Plugin for updating the Drupal scaffold files when using drupal/core" }, { - "name": "drupal/http2_server_push", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "name": "composer/installers", + "version": "v1.3.0", + "version_normalized": "1.3.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/http2_server_push", - "reference": "8.x-1.0" + "url": "https://github.com/composer/installers.git", + "reference": "79ad876c7498c0bbfe7eed065b8651c93bfd6045" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/http2_server_push-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "cc2df591201313f1407e55424cfe7cf35127fa47" + "url": "https://api.github.com/repos/composer/installers/zipball/79ad876c7498c0bbfe7eed065b8651c93bfd6045", + "reference": "79ad876c7498c0bbfe7eed065b8651c93bfd6045", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "composer-plugin-api": "^1.0" }, - "type": "drupal-module", + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "phpunit/phpunit": "4.1.*" + }, + "time": "2017-04-24T06:37:16+00:00", + "type": "composer-plugin", "extra": { + "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0", - "datestamp": "1489057084" + "dev-master": "1.0-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Wim Leers", - "homepage": "https://www.drupal.org/user/99777" + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" } ], - "description": "Pushes CSS & JS files to the client on servers using HTTP/2.", - "homepage": "https://www.drupal.org/project/http2_server_push", - "support": { - "source": "http://cgit.drupalcode.org/http2_server_push" - } + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "MODX Evo", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "mako", + "mediawiki", + "modulework", + "moodle", + "phpbb", + "piwik", + "ppi", + "puppet", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ] }, { - "name": "drupal/admin_toolbar", - "version": "1.19.0", - "version_normalized": "1.19.0.0", + "name": "symfony/polyfill-php55", + "version": "v1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/admin_toolbar", - "reference": "8.x-1.19" + "url": "https://github.com/symfony/polyfill-php55.git", + "reference": "94566239a7720cde0820f15f0cc348ddb51ba51d" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/admin_toolbar-8.x-1.19.zip", - "reference": "8.x-1.19", - "shasum": "87de41eab3c5cd49d4e1b5b764cb3b9d5ad683a0" + "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/94566239a7720cde0820f15f0cc348ddb51ba51d", + "reference": "94566239a7720cde0820f15f0cc348ddb51ba51d", + "shasum": "" }, "require": { - "drupal/core": "*" + "ircmaxell/password-compat": "~1.0", + "php": ">=5.3.3" }, - "type": "drupal-module", + "time": "2017-06-09T08:25:21+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.19", - "datestamp": "1491487683" + "dev-master": "1.4-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php55\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Mohamed Anis Taktak", - "homepage": "https://www.drupal.org/u/matio89" - }, - { - "name": "eme", - "homepage": "https://www.drupal.org/user/542492" - }, - { - "name": "fethi.krout", - "homepage": "https://www.drupal.org/user/3206765" - }, - { - "name": "matio89", - "homepage": "https://www.drupal.org/user/2320090" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "romainj", - "homepage": "https://www.drupal.org/user/370706" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Admin Toolbar improve the default Drupal Toolbar, it lets the hover of sub menus.", - "homepage": "http://drupal.org/project/admin_toolbar", - "support": { - "source": "http://cgit.drupalcode.org/admin_toolbar", - "issues": "https://www.drupal.org/project/issues/admin_toolbar" - } + "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ] }, { - "name": "drupal/crop", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "name": "symfony/polyfill-php54", + "version": "v1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/crop", - "reference": "8.x-1.2" + "url": "https://github.com/symfony/polyfill-php54.git", + "reference": "7dd1a8b9f0442273fdfeb1c4f5eaff6890a82789" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/crop-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "0ad542254940c844f8a22c1b386131f06c665b4f" + "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/7dd1a8b9f0442273fdfeb1c4f5eaff6890a82789", + "reference": "7dd1a8b9f0442273fdfeb1c4f5eaff6890a82789", + "shasum": "" }, "require": { - "drupal/core": "*" - }, - "require-dev": { - "drupal/media_entity": "*" + "php": ">=5.3.3" }, - "type": "drupal-module", + "time": "2017-06-09T08:25:21+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.2", - "datestamp": "1491032884" + "dev-master": "1.4-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php54\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Drupal Media Team", - "homepage": "https://www.drupal.org/user/3260690" - }, - { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "woprrr", - "homepage": "https://www.drupal.org/user/858604" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides storage and API for image crops.", - "homepage": "https://www.drupal.org/project/crop", - "support": { - "source": "http://cgit.drupalcode.org/crop", - "issues": "https://www.drupal.org/project/issues/crop" - } + "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ] }, { - "name": "drupal/image_widget_crop", - "version": "1.5.0", - "version_normalized": "1.5.0.0", + "name": "symfony/polyfill-mbstring", + "version": "v1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/image_widget_crop", - "reference": "8.x-1.5" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "f29dca382a6485c3cbe6379f0c61230167681937" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/image_widget_crop-8.x-1.5.zip", - "reference": "8.x-1.5", - "shasum": "1f0a3de727d22a675c8be2e7af49ea22592d9d19" + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f29dca382a6485c3cbe6379f0c61230167681937", + "reference": "f29dca382a6485c3cbe6379f0c61230167681937", + "shasum": "" }, "require": { - "drupal/core": "*", - "drupal/crop": "1.x" + "php": ">=5.3.3" }, - "require-dev": { - "drupal/crop": "*", - "drupal/file_entity": "*", - "drupal/inline_entity_form": "*", - "drupal/media_entity": "*", - "drupal/media_entity_image": "*" + "suggest": { + "ext-mbstring": "For best performance" }, - "type": "drupal-module", + "time": "2017-06-09T14:24:12+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.5", - "datestamp": "1491393484" + "dev-master": "1.4-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", - "license": [ - "GPL-2.0+" + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" ], "authors": [ { - "name": "Alexandre Mallet", - "homepage": "https://github.com/woprrr", - "role": "Maintainer" - }, - { - "name": "Drupal media CI", - "homepage": "https://www.drupal.org/user/3057985" - }, - { - "name": "slashrsm", - "homepage": "https://www.drupal.org/user/744628" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "woprrr", - "homepage": "https://www.drupal.org/user/858604" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides an interface for using the features of the Crop API.", - "homepage": "https://www.drupal.org/project/image_widget_crop", + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", "keywords": [ - "Crop", - "Drupal", - "Drupal Media" - ], - "support": { - "source": "https://www.drupal.org/project/image_widget_crop", - "issues": "https://www.drupal.org/project/issues/image_widget_crop", - "irc": "irc://irc.freenode.org/drupal-contribute" - } + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ] }, { - "name": "zendframework/zend-diactoros", - "version": "1.4.0", - "version_normalized": "1.4.0.0", + "name": "symfony/http-foundation", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "b03f285a333f51e58c95cce54109a4a9ed691436" + "url": "https://github.com/symfony/http-foundation.git", + "reference": "de8d8e83b9ec898e14ef8db84cee5919753b2ae5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/b03f285a333f51e58c95cce54109a4a9ed691436", - "reference": "b03f285a333f51e58c95cce54109a4a9ed691436", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/de8d8e83b9ec898e14ef8db84cee5919753b2ae5", + "reference": "de8d8e83b9ec898e14ef8db84cee5919753b2ae5", "shasum": "" }, "require": { - "php": "^5.4 || ^7.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php54": "~1.0", + "symfony/polyfill-php55": "~1.0" }, "require-dev": { - "ext-dom": "*", - "ext-libxml": "*", - "phpunit/phpunit": "^4.6 || ^5.5", - "zendframework/zend-coding-standard": "~1.0.0" + "symfony/expression-language": "~2.4|~3.0.0" }, - "time": "2017-04-06T16:18:34+00:00", + "time": "2017-06-01T20:52:29+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev", - "dev-develop": "1.5-dev" + "dev-master": "2.8-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Zend\\Diactoros\\": "src/" - } + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-2-Clause" + "MIT" ], - "description": "PSR HTTP Message implementations", - "homepage": "https://github.com/zendframework/zend-diactoros", - "keywords": [ - "http", - "psr", - "psr-7" - ] + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com" }, { - "name": "symfony/translation", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "symfony/expression-language", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "047e97a64d609778cadfc76e3a09793696bb19f1" + "url": "https://github.com/symfony/expression-language.git", + "reference": "2b8394d92f012fe3410e55e28c24fd90c9864a01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/047e97a64d609778cadfc76e3a09793696bb19f1", - "reference": "047e97a64d609778cadfc76e3a09793696bb19f1", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/2b8394d92f012fe3410e55e28c24fd90c9864a01", + "reference": "2b8394d92f012fe3410e55e28c24fd90c9864a01", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/config": "<2.7" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.8", - "symfony/intl": "~2.7.25|^2.8.18|~3.2.5", - "symfony/yaml": "~2.2|~3.0.0" - }, - "suggest": { - "psr/log": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" + "php": ">=5.3.9" }, - "time": "2017-03-21T21:39:01+00:00", + "time": "2017-06-01T20:52:29+00:00", "type": "library", "extra": { "branch-alias": { @@ -8006,7 +7890,7 @@ "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\Translation\\": "" + "Symfony\\Component\\ExpressionLanguage\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -8026,62 +7910,45 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Translation Component", + "description": "Symfony ExpressionLanguage Component", "homepage": "https://symfony.com" }, { - "name": "symfony/validator", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "symfony/dom-crawler", + "version": "v3.2.9", + "version_normalized": "3.2.9.0", "source": { "type": "git", - "url": "https://github.com/symfony/validator.git", - "reference": "43f617ee200af4f4dedbb0782c6c689e06994286" + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "3d0e66d86f5eeaffa44edc884ce09322be8f4716" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/43f617ee200af4f4dedbb0782c6c689e06994286", - "reference": "43f617ee200af4f4dedbb0782c6c689e06994286", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/3d0e66d86f5eeaffa44edc884ce09322be8f4716", + "reference": "3d0e66d86f5eeaffa44edc884ce09322be8f4716", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-mbstring": "~1.0", - "symfony/translation": "~2.4|~3.0.0" + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/cache": "~1.0", - "egulias/email-validator": "^1.2.1", - "symfony/config": "~2.2|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/http-foundation": "~2.3|~3.0.0", - "symfony/intl": "~2.7.25|^2.8.18|~3.2.5", - "symfony/property-access": "~2.3|~3.0.0", - "symfony/yaml": "^2.0.5|~3.0.0" + "symfony/css-selector": "~2.8|~3.0" }, "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", - "egulias/email-validator": "Strict (RFC compliant) email validation", - "symfony/config": "", - "symfony/expression-language": "For using the 2.4 Expression validator", - "symfony/http-foundation": "", - "symfony/intl": "", - "symfony/property-access": "For using the 2.4 Validator API", - "symfony/yaml": "" + "symfony/css-selector": "" }, - "time": "2017-03-23T16:08:03+00:00", + "time": "2017-05-25T22:59:05+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\Validator\\": "" + "Symfony\\Component\\DomCrawler\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -8101,43 +7968,28 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Validator Component", + "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com" }, { - "name": "symfony/serializer", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "symfony/css-selector", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/serializer.git", - "reference": "d1c3d68daee29bbf0b4600745899a7000c215642" + "url": "https://github.com/symfony/css-selector.git", + "reference": "ba3204654efa779691fac9e948a96b4a7067e4ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/d1c3d68daee29bbf0b4600745899a7000c215642", - "reference": "d1c3d68daee29bbf0b4600745899a7000c215642", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/ba3204654efa779691fac9e948a96b4a7067e4ab", + "reference": "ba3204654efa779691fac9e948a96b4a7067e4ab", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-php55": "~1.0" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/cache": "~1.0", - "symfony/config": "~2.2|~3.0.0", - "symfony/property-access": "~2.3|~3.0.0", - "symfony/yaml": "^2.0.5|~3.0.0" - }, - "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", - "symfony/config": "For using the XML mapping loader.", - "symfony/property-access": "For using the ObjectNormalizer.", - "symfony/yaml": "For using the default YAML mapping loader." + "php": ">=5.3.9" }, - "time": "2017-03-21T22:47:17+00:00", + "time": "2017-05-01T14:31:55+00:00", "type": "library", "extra": { "branch-alias": { @@ -8147,7 +7999,7 @@ "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\Serializer\\": "" + "Symfony\\Component\\CssSelector\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -8158,6 +8010,10 @@ "MIT" ], "authors": [ + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" @@ -8167,48 +8023,40 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Serializer Component", + "description": "Symfony CssSelector Component", "homepage": "https://symfony.com" }, { - "name": "symfony/routing", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "symfony/var-dumper", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "d145cd396f702c497cb24b21785ddac90a23fe71" + "url": "https://github.com/symfony/var-dumper.git", + "reference": "8108f6200e8a1cf999df2691431a2d71e6db1152" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/d145cd396f702c497cb24b21785ddac90a23fe71", - "reference": "d145cd396f702c497cb24b21785ddac90a23fe71", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/8108f6200e8a1cf999df2691431a2d71e6db1152", + "reference": "8108f6200e8a1cf999df2691431a2d71e6db1152", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/config": "<2.7" + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/common": "~2.2", - "psr/log": "~1.0", - "symfony/config": "~2.7|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/http-foundation": "~2.3|~3.0.0", - "symfony/yaml": "^2.0.5|~3.0.0" + "ext-iconv": "*", + "twig/twig": "~1.34|~2.4" }, "suggest": { - "doctrine/annotations": "For using the annotation loader", - "symfony/config": "For using the all-in-one router or any loader", - "symfony/dependency-injection": "For loading routes from a service", - "symfony/expression-language": "For using expression matching", - "symfony/http-foundation": "For using a Symfony Request object", - "symfony/yaml": "For using the YAML loader" + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-symfony_debug": "" }, - "time": "2017-03-02T15:56:34+00:00", + "time": "2017-06-02T08:28:06+00:00", "type": "library", "extra": { "branch-alias": { @@ -8217,8 +8065,11 @@ }, "installation-source": "dist", "autoload": { + "files": [ + "Resources/functions/dump.php" + ], "psr-4": { - "Symfony\\Component\\Routing\\": "" + "Symfony\\Component\\VarDumper\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -8230,48 +8081,48 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Routing Component", + "description": "Symfony mechanism for exploring and dumping PHP variables", "homepage": "https://symfony.com", "keywords": [ - "router", - "routing", - "uri", - "url" + "debug", + "dump" ] }, { - "name": "symfony/http-foundation", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "symfony/debug", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "0717efd2f2264dbd3d8e1bc69a0418c2fd6295d2" + "url": "https://github.com/symfony/debug.git", + "reference": "8470d7701177a88edeb0cec59b44d50ef4477e9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/0717efd2f2264dbd3d8e1bc69a0418c2fd6295d2", - "reference": "0717efd2f2264dbd3d8e1bc69a0418c2fd6295d2", + "url": "https://api.github.com/repos/symfony/debug/zipball/8470d7701177a88edeb0cec59b44d50ef4477e9b", + "reference": "8470d7701177a88edeb0cec59b44d50ef4477e9b", "shasum": "" }, "require": { "php": ">=5.3.9", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php54": "~1.0", - "symfony/polyfill-php55": "~1.0" + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" }, "require-dev": { - "symfony/expression-language": "~2.4|~3.0.0" + "symfony/class-loader": "~2.2|~3.0.0", + "symfony/http-kernel": "~2.3.24|~2.5.9|^2.6.2|~3.0.0" }, - "time": "2017-04-04T15:24:26+00:00", + "time": "2017-06-01T20:52:29+00:00", "type": "library", "extra": { "branch-alias": { @@ -8281,7 +8132,7 @@ "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" + "Symfony\\Component\\Debug\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -8301,104 +8152,126 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony HttpFoundation Component", + "description": "Symfony Debug Component", "homepage": "https://symfony.com" }, { - "name": "symfony/psr-http-message-bridge", - "version": "v1.0.0", - "version_normalized": "1.0.0.0", + "name": "symfony/console", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "66085f246d3893cbdbcec5f5ad15ac60546cf0de" + "url": "https://github.com/symfony/console.git", + "reference": "3ef6ef64abecd566d551d9e7f6393ac6e93b2462" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/66085f246d3893cbdbcec5f5ad15ac60546cf0de", - "reference": "66085f246d3893cbdbcec5f5ad15ac60546cf0de", + "url": "https://api.github.com/repos/symfony/console/zipball/3ef6ef64abecd566d551d9e7f6393ac6e93b2462", + "reference": "3ef6ef64abecd566d551d9e7f6393ac6e93b2462", "shasum": "" }, "require": { - "php": ">=5.3.3", - "psr/http-message": "~1.0", - "symfony/http-foundation": "~2.3|~3.0" + "php": ">=5.3.9", + "symfony/debug": "^2.7.2|~3.0.0", + "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/phpunit-bridge": "~2.7|~3.0" + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" }, "suggest": { - "psr/http-message-implementation": "To use the HttpFoundation factory", - "zendframework/zend-diactoros": "To use the Zend Diactoros factory" + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" }, - "time": "2016-09-14T18:37:20+00:00", - "type": "symfony-bridge", + "time": "2017-06-02T14:36:56+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.8-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Bridge\\PsrHttpMessage\\": "" - } + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "PSR HTTP message bridge", - "homepage": "http://symfony.com", - "keywords": [ - "http", - "http-message", - "psr-7" - ] + "description": "Symfony Console Component", + "homepage": "https://symfony.com" }, { - "name": "symfony/process", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "psy/psysh", + "version": "v0.8.7", + "version_normalized": "0.8.7.0", "source": { "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "41336b20b52f5fd5b42a227e394e673c8071118f" + "url": "https://github.com/bobthecow/psysh.git", + "reference": "be969b9dc89dcaefdb9a3117fa91fa38bca19f50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/41336b20b52f5fd5b42a227e394e673c8071118f", - "reference": "41336b20b52f5fd5b42a227e394e673c8071118f", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/be969b9dc89dcaefdb9a3117fa91fa38bca19f50", + "reference": "be969b9dc89dcaefdb9a3117fa91fa38bca19f50", "shasum": "" }, "require": { - "php": ">=5.3.9" + "dnoegel/php-xdg-base-dir": "0.1", + "jakub-onderka/php-console-highlighter": "0.3.*", + "nikic/php-parser": "~1.3|~2.0|~3.0", + "php": ">=5.3.9", + "symfony/console": "~2.3.10|^2.4.2|~3.0", + "symfony/var-dumper": "~2.7|~3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~1.11", + "hoa/console": "~3.16|~1.14", + "phpunit/phpunit": "~4.4|~5.0", + "symfony/finder": "~2.1|~3.0" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", + "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." }, - "time": "2017-03-04T12:20:59+00:00", + "time": "2017-06-20T12:51:31+00:00", + "bin": [ + "bin/psysh" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-develop": "0.8.x-dev" } }, "installation-source": "dist", "autoload": { + "files": [ + "src/Psy/functions.php" + ], "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Psy\\": "src/Psy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -8406,134 +8279,82 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" } ], - "description": "Symfony Process Component", - "homepage": "https://symfony.com" + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ] }, { - "name": "symfony/http-kernel", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "gabordemooij/redbean", + "version": "v4.3.4", + "version_normalized": "4.3.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "3256e9e554f02ba2dd49cff253f15df69c36cf40" + "url": "https://github.com/gabordemooij/redbean.git", + "reference": "d0944d7f966d7f45a0d973981fe3f64aff0050f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3256e9e554f02ba2dd49cff253f15df69c36cf40", - "reference": "3256e9e554f02ba2dd49cff253f15df69c36cf40", + "url": "https://api.github.com/repos/gabordemooij/redbean/zipball/d0944d7f966d7f45a0d973981fe3f64aff0050f0", + "reference": "d0944d7f966d7f45a0d973981fe3f64aff0050f0", "shasum": "" }, "require": { - "php": ">=5.3.9", - "psr/log": "~1.0", - "symfony/debug": "^2.6.2", - "symfony/event-dispatcher": "^2.6.7|~3.0.0", - "symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6" - }, - "conflict": { - "symfony/config": "<2.7" - }, - "require-dev": { - "symfony/browser-kit": "~2.3|~3.0.0", - "symfony/class-loader": "~2.1|~3.0.0", - "symfony/config": "~2.8", - "symfony/console": "~2.3|~3.0.0", - "symfony/css-selector": "^2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.8|~3.0.0", - "symfony/dom-crawler": "^2.0.5|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/finder": "^2.0.5|~3.0.0", - "symfony/process": "^2.0.5|~3.0.0", - "symfony/routing": "~2.8|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0", - "symfony/templating": "~2.2|~3.0.0", - "symfony/translation": "^2.0.5|~3.0.0", - "symfony/var-dumper": "~2.6|~3.0.0" - }, - "suggest": { - "symfony/browser-kit": "", - "symfony/class-loader": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "", - "symfony/finder": "", - "symfony/var-dumper": "" + "php": ">=5.3.4" }, - "time": "2017-04-05T04:04:34+00:00", + "time": "2017-03-07T22:26:54+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "RedBeanPHP\\": "RedBeanPHP" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "New BSD and GPLv2" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Gabor de Mooij", + "email": "gabor@redbeanphp.com", + "homepage": "http://redbeanphp.com" } ], - "description": "Symfony HttpKernel Component", - "homepage": "https://symfony.com" + "description": "RedBeanPHP ORM", + "homepage": "http://redbeanphp.com/", + "keywords": [ + "orm" + ] }, { - "name": "symfony/dependency-injection", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "symfony/yaml", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/dependency-injection.git", - "reference": "14b9d8ae69ac4c74e8f05fee7e0a57039b99c81e" + "url": "https://github.com/symfony/yaml.git", + "reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/14b9d8ae69ac4c74e8f05fee7e0a57039b99c81e", - "reference": "14b9d8ae69ac4c74e8f05fee7e0a57039b99c81e", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5", + "reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5", "shasum": "" }, "require": { "php": ">=5.3.9" }, - "conflict": { - "symfony/expression-language": "<2.6" - }, - "require-dev": { - "symfony/config": "~2.2|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7" - }, - "suggest": { - "symfony/config": "", - "symfony/expression-language": "For using expressions in service container configuration", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" - }, - "time": "2017-04-03T22:14:48+00:00", + "time": "2017-06-01T20:52:29+00:00", "type": "library", "extra": { "branch-alias": { @@ -8543,7 +8364,7 @@ "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\DependencyInjection\\": "" + "Symfony\\Component\\Yaml\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -8563,32 +8384,28 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony DependencyInjection Component", + "description": "Symfony Yaml Component", "homepage": "https://symfony.com" }, { - "name": "symfony/class-loader", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "symfony/finder", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/class-loader.git", - "reference": "2c8de07a8a4cc4da9c018ab7a81888b80e762f93" + "url": "https://github.com/symfony/finder.git", + "reference": "4f4e84811004e065a3bb5ceeb1d9aa592630f9ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/2c8de07a8a4cc4da9c018ab7a81888b80e762f93", - "reference": "2c8de07a8a4cc4da9c018ab7a81888b80e762f93", + "url": "https://api.github.com/repos/symfony/finder/zipball/4f4e84811004e065a3bb5ceeb1d9aa592630f9ad", + "reference": "4f4e84811004e065a3bb5ceeb1d9aa592630f9ad", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-apcu": "~1.1" - }, - "require-dev": { - "symfony/finder": "^2.0.5|~3.0.0" + "php": ">=5.3.9" }, - "time": "2017-02-18T19:13:35+00:00", + "time": "2017-06-01T20:52:29+00:00", "type": "library", "extra": { "branch-alias": { @@ -8598,7 +8415,7 @@ "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\ClassLoader\\": "" + "Symfony\\Component\\Finder\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -8618,225 +8435,206 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony ClassLoader Component", + "description": "Symfony Finder Component", "homepage": "https://symfony.com" }, { - "name": "doctrine/common", - "version": "v2.7.2", - "version_normalized": "2.7.2.0", + "name": "drupal/console-extend-plugin", + "version": "0.8.0", + "version_normalized": "0.8.0.0", "source": { "type": "git", - "url": "https://github.com/doctrine/common.git", - "reference": "930297026c8009a567ac051fd545bf6124150347" + "url": "https://github.com/hechoendrupal/drupal-console-extend-plugin.git", + "reference": "d69ffe413259781c4257ab42bd79c9da9042e87e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/930297026c8009a567ac051fd545bf6124150347", - "reference": "930297026c8009a567ac051fd545bf6124150347", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-extend-plugin/zipball/d69ffe413259781c4257ab42bd79c9da9042e87e", + "reference": "d69ffe413259781c4257ab42bd79c9da9042e87e", "shasum": "" }, "require": { - "doctrine/annotations": "1.*", - "doctrine/cache": "1.*", - "doctrine/collections": "1.*", - "doctrine/inflector": "1.*", - "doctrine/lexer": "1.*", - "php": "~5.6|~7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.4.6" + "composer-plugin-api": "^1.0", + "symfony/finder": ">=2.7 <3.0", + "symfony/yaml": ">=2.7 <3.0" }, - "time": "2017-01-13T14:02:13+00:00", - "type": "library", + "time": "2017-06-08T16:06:59+00:00", + "type": "composer-plugin", "extra": { - "branch-alias": { - "dev-master": "2.7.x-dev" - } + "class": "Drupal\\Console\\Composer\\Plugin\\Extender" }, "installation-source": "dist", "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" + "Drupal\\Console\\Composer\\Plugin\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Jesus Manuel Olivas", + "email": "jesus.olivas@gmail.com" } ], - "description": "Common Library for Doctrine projects", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "collections", - "eventmanager", - "persistence", - "spl" - ] + "description": "Drupal Console Extend Plugin" }, { - "name": "asm89/stack-cors", - "version": "1.1.0", - "version_normalized": "1.1.0.0", + "name": "webflo/drupal-finder", + "version": "0.3.0", + "version_normalized": "0.3.0.0", "source": { "type": "git", - "url": "https://github.com/asm89/stack-cors.git", - "reference": "65ccbd455370f043c2e3b93482a3813603d68731" + "url": "https://github.com/webflo/drupal-finder.git", + "reference": "6ef150707aad1755d91f9b0d2108bcc16661e76b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/asm89/stack-cors/zipball/65ccbd455370f043c2e3b93482a3813603d68731", - "reference": "65ccbd455370f043c2e3b93482a3813603d68731", + "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/6ef150707aad1755d91f9b0d2108bcc16661e76b", + "reference": "6ef150707aad1755d91f9b0d2108bcc16661e76b", "shasum": "" }, - "require": { - "php": ">=5.5.9", - "symfony/http-foundation": "~2.7|~3.0", - "symfony/http-kernel": "~2.7|~3.0" - }, "require-dev": { - "phpunit/phpunit": "^5.0 || ^4.8.10", - "squizlabs/php_codesniffer": "^2.3" + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^4.8" }, - "time": "2017-04-11T20:03:41+00:00", + "time": "2017-05-04T08:54:02+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, "installation-source": "dist", "autoload": { - "psr-4": { - "Asm89\\Stack\\": "src/Asm89/Stack/" - } + "classmap": [ + "src/DrupalFinder.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Alexander", - "email": "iam.asm89@gmail.com" + "name": "Florian Weber", + "email": "florian@webflo.org" } ], - "description": "Cross-origin resource sharing library and stack middleware", - "homepage": "https://github.com/asm89/stack-cors", - "keywords": [ - "cors", - "stack" - ] + "description": "Helper class to locate a Drupal installation from a given path." }, { - "name": "webmozart/assert", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "name": "twig/twig", + "version": "v1.34.3", + "version_normalized": "1.34.3.0", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + "url": "https://github.com/twigphp/Twig.git", + "reference": "451c6f4197e113e24c1c85bc3fc8c2d77adeff2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/451c6f4197e113e24c1c85bc3fc8c2d77adeff2e", + "reference": "451c6f4197e113e24c1c85bc3fc8c2d77adeff2e", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "psr/container": "^1.0", + "symfony/debug": "~2.7", + "symfony/phpunit-bridge": "~3.3@dev" }, - "time": "2016-11-23T20:04:58+00:00", + "time": "2017-06-07T18:45:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.34-dev" } }, "installation-source": "dist", "autoload": { + "psr-0": { + "Twig_": "lib/" + }, "psr-4": { - "Webmozart\\Assert\\": "src/" + "Twig\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + }, + { + "name": "Twig Team", + "homepage": "http://twig.sensiolabs.org/contributors", + "role": "Contributors" } ], - "description": "Assertions to validate method input/output with nice error messages.", + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", "keywords": [ - "assert", - "check", - "validate" + "templating" ] }, { - "name": "webmozart/path-util", - "version": "2.3.0", - "version_normalized": "2.3.0.0", + "name": "symfony/translation", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/webmozart/path-util.git", - "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + "url": "https://github.com/symfony/translation.git", + "reference": "14db4cc1172a722aaa3b558bfa8eff593b43cd46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", - "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "url": "https://api.github.com/repos/symfony/translation/zipball/14db4cc1172a722aaa3b558bfa8eff593b43cd46", + "reference": "14db4cc1172a722aaa3b558bfa8eff593b43cd46", "shasum": "" }, "require": { - "php": ">=5.3.3", - "webmozart/assert": "~1.0" + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<2.7" }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "psr/log": "~1.0", + "symfony/config": "~2.8", + "symfony/intl": "~2.7.25|^2.8.18|~3.2.5", + "symfony/yaml": "~2.2|~3.0.0" }, - "time": "2015-12-17T08:42:14+00:00", + "suggest": { + "psr/log": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "time": "2017-06-01T20:52:29+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "2.8-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Webmozart\\PathUtil\\": "src/" - } + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -8844,41 +8642,36 @@ ], "authors": [ { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths." + "description": "Symfony Translation Component", + "homepage": "https://symfony.com" }, { - "name": "symfony/var-dumper", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "symfony/process", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "f8ff23ad5352f96e66c1df5468d492d2f37f3ac4" + "url": "https://github.com/symfony/process.git", + "reference": "d54232f5682fda2f8bbebff7c81b864646867ab9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f8ff23ad5352f96e66c1df5468d492d2f37f3ac4", - "reference": "f8ff23ad5352f96e66c1df5468d492d2f37f3ac4", + "url": "https://api.github.com/repos/symfony/process/zipball/d54232f5682fda2f8bbebff7c81b864646867ab9", + "reference": "d54232f5682fda2f8bbebff7c81b864646867ab9", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" - }, - "require-dev": { - "twig/twig": "~1.20|~2.0" - }, - "suggest": { - "ext-symfony_debug": "" + "php": ">=5.3.9" }, - "time": "2017-03-12T16:01:59+00:00", + "time": "2017-05-08T01:19:21+00:00", "type": "library", "extra": { "branch-alias": { @@ -8887,11 +8680,8 @@ }, "installation-source": "dist", "autoload": { - "files": [ - "Resources/functions/dump.php" - ], "psr-4": { - "Symfony\\Component\\VarDumper\\": "" + "Symfony\\Component\\Process\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -8903,59 +8693,50 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony mechanism for exploring and dumping PHP variables", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ] + "description": "Symfony Process Component", + "homepage": "https://symfony.com" }, { - "name": "consolidation/output-formatters", - "version": "3.1.8", - "version_normalized": "3.1.8.0", + "name": "symfony/filesystem", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/consolidation/output-formatters.git", - "reference": "0b50ba1134d581fd55376f3e21508dab009ced47" + "url": "https://github.com/symfony/filesystem.git", + "reference": "19c11158da8d110cc5289c063bf2ec4cc1ce9e7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/0b50ba1134d581fd55376f3e21508dab009ced47", - "reference": "0b50ba1134d581fd55376f3e21508dab009ced47", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/19c11158da8d110cc5289c063bf2ec4cc1ce9e7c", + "reference": "19c11158da8d110cc5289c063bf2ec4cc1ce9e7c", "shasum": "" }, "require": { - "php": ">=5.4.0", - "symfony/console": "^2.8|~3", - "symfony/finder": "~2.5|~3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8", - "satooshi/php-coveralls": "^1.0", - "squizlabs/php_codesniffer": "^2.7", - "victorjonsson/markdowndocs": "^1.3" + "php": ">=5.3.9" }, - "time": "2017-03-01T20:54:45+00:00", + "time": "2017-05-28T14:07:33+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "2.8-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Consolidation\\OutputFormatters\\": "src" - } + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -8963,202 +8744,57 @@ ], "authors": [ { - "name": "Greg Anderson", - "email": "greg.1.anderson@greenknowe.org" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Format text by applying transformations provided by plug-in formatters." + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com" }, { - "name": "consolidation/annotated-command", - "version": "2.4.8", - "version_normalized": "2.4.8.0", + "name": "symfony/event-dispatcher", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/consolidation/annotated-command.git", - "reference": "6672ea38212f8bffb71fec7eadc8b3372154b17e" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "1377400fd641d7d1935981546aaef780ecd5bf6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/6672ea38212f8bffb71fec7eadc8b3372154b17e", - "reference": "6672ea38212f8bffb71fec7eadc8b3372154b17e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1377400fd641d7d1935981546aaef780ecd5bf6d", + "reference": "1377400fd641d7d1935981546aaef780ecd5bf6d", "shasum": "" }, "require": { - "consolidation/output-formatters": "^3.1.5", - "php": ">=5.4.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", - "psr/log": "^1", - "symfony/console": "^2.8|~3", - "symfony/event-dispatcher": "^2.5|^3", - "symfony/finder": "^2.5|^3" + "php": ">=5.3.9" }, "require-dev": { - "phpunit/phpunit": "^4.8", - "satooshi/php-coveralls": "^1.0", - "squizlabs/php_codesniffer": "^2.7" + "psr/log": "~1.0", + "symfony/config": "^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" }, - "time": "2017-04-03T22:37:00+00:00", + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "time": "2017-06-02T07:47:27+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "2.8-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Consolidation\\AnnotatedCommand\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Greg Anderson", - "email": "greg.1.anderson@greenknowe.org" - } - ], - "description": "Initialize Symfony Console commands from annotated command class methods." - }, - { - "name": "drush/drush", - "version": "8.1.10", - "version_normalized": "8.1.10.0", - "source": { - "type": "git", - "url": "https://github.com/drush-ops/drush.git", - "reference": "2192496b80aa9cdb0581a2d308623f950f747e94" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/drush-ops/drush/zipball/2192496b80aa9cdb0581a2d308623f950f747e94", - "reference": "2192496b80aa9cdb0581a2d308623f950f747e94", - "shasum": "" - }, - "require": { - "consolidation/annotated-command": "~2", - "consolidation/output-formatters": "~3", - "pear/console_table": "~1.3.0", - "php": ">=5.4.5", - "phpdocumentor/reflection-docblock": "^2.0", - "psr/log": "~1.0", - "psy/psysh": "~0.6", - "symfony/console": "~2.7", - "symfony/event-dispatcher": "~2.7", - "symfony/finder": "~2.7", - "symfony/var-dumper": "~2.7", - "symfony/yaml": "~2.3", - "webmozart/path-util": "~2" - }, - "require-dev": { - "phpunit/phpunit": "4.*", - "symfony/process": "2.7.*" - }, - "suggest": { - "drush/config-extra": "Provides configuration workflow commands, such as config-merge.", - "ext-pcntl": "*" - }, - "time": "2017-02-23T20:46:12+00:00", - "bin": [ - "drush", - "drush.launcher", - "drush.php", - "drush.complete.sh" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "8.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Drush": "lib/", - "Consolidation": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0+" - ], - "authors": [ - { - "name": "Moshe Weitzman", - "email": "weitzman@tejasa.com" - }, - { - "name": "Owen Barton", - "email": "drupal@owenbarton.com" - }, - { - "name": "Mark Sonnabaum", - "email": "marksonnabaum@gmail.com" - }, - { - "name": "Antoine Beaupré", - "email": "anarcat@koumbit.org" - }, - { - "name": "Greg Anderson", - "email": "greg.1.anderson@greenknowe.org" - }, - { - "name": "Jonathan Araña Cruz", - "email": "jonhattan@faita.net" - }, - { - "name": "Jonathan Hedstrom", - "email": "jhedstrom@gmail.com" - }, - { - "name": "Christopher Gervais", - "email": "chris@ergonlogic.com" - }, - { - "name": "Dave Reid", - "email": "dave@davereid.net" - }, - { - "name": "Damian Lee", - "email": "damiankloip@googlemail.com" - } - ], - "description": "Drush is a command line shell and scripting interface for Drupal, a veritable Swiss Army knife designed to make life easier for those of us who spend some of our working hours hacking away at the command prompt.", - "homepage": "http://www.drush.org" - }, - { - "name": "symfony/css-selector", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "742bd688bd778dde8991ba696cb372570610afcd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/742bd688bd778dde8991ba696cb372570610afcd", - "reference": "742bd688bd778dde8991ba696cb372570610afcd", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "time": "2017-02-21T08:33:48+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" + "Symfony\\Component\\EventDispatcher\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -9169,10 +8805,6 @@ "MIT" ], "authors": [ - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" @@ -9182,28 +8814,42 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony CssSelector Component", + "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com" }, { - "name": "symfony/expression-language", - "version": "v2.8.19", - "version_normalized": "2.8.19.0", + "name": "symfony/dependency-injection", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/expression-language.git", - "reference": "269a0a751f07a58b315f74899a253ead71747f06" + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "b4a4b8f6ae1d69a6b2c0c31623bbc474121ee075" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/269a0a751f07a58b315f74899a253ead71747f06", - "reference": "269a0a751f07a58b315f74899a253ead71747f06", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b4a4b8f6ae1d69a6b2c0c31623bbc474121ee075", + "reference": "b4a4b8f6ae1d69a6b2c0c31623bbc474121ee075", "shasum": "" }, "require": { "php": ">=5.3.9" }, - "time": "2017-04-03T23:11:44+00:00", + "conflict": { + "symfony/expression-language": "<2.6" + }, + "require-dev": { + "symfony/config": "~2.2|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "time": "2017-06-02T14:36:56+00:00", "type": "library", "extra": { "branch-alias": { @@ -9213,7 +8859,7 @@ "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\ExpressionLanguage\\": "" + "Symfony\\Component\\DependencyInjection\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -9233,45 +8879,45 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony ExpressionLanguage Component", + "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com" }, { - "name": "symfony/dom-crawler", - "version": "v3.2.7", - "version_normalized": "3.2.7.0", + "name": "symfony/config", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee" + "url": "https://github.com/symfony/config.git", + "reference": "0b8541d18507d10204a08384640ff6df3c739ebe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/403944e294cf4ceb3b8447f54cbad88ea7b99cee", - "reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee", + "url": "https://api.github.com/repos/symfony/config/zipball/0b8541d18507d10204a08384640ff6df3c739ebe", + "reference": "0b8541d18507d10204a08384640ff6df3c739ebe", "shasum": "" }, "require": { - "php": ">=5.5.9", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=5.3.9", + "symfony/filesystem": "~2.3|~3.0.0" }, "require-dev": { - "symfony/css-selector": "~2.8|~3.0" + "symfony/yaml": "~2.7|~3.0.0" }, "suggest": { - "symfony/css-selector": "" + "symfony/yaml": "To use the yaml reference dumper" }, - "time": "2017-02-21T09:12:04+00:00", + "time": "2017-04-12T14:07:15+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "2.8-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" + "Symfony\\Component\\Config\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -9291,921 +8937,1026 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony DomCrawler Component", + "description": "Symfony Config Component", "homepage": "https://symfony.com" }, { - "name": "symfony/browser-kit", - "version": "v3.2.7", - "version_normalized": "3.2.7.0", + "name": "drupal/console-en", + "version": "1.0.0-rc21", + "version_normalized": "1.0.0.0-RC21", "source": { "type": "git", - "url": "https://github.com/symfony/browser-kit.git", - "reference": "2fe0caa60c1a1dfeefd0425741182687a9b382b8" + "url": "https://github.com/hechoendrupal/drupal-console-en.git", + "reference": "b6f563b8760c3b19aad22dd213a9cfba2f2c75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/2fe0caa60c1a1dfeefd0425741182687a9b382b8", - "reference": "2fe0caa60c1a1dfeefd0425741182687a9b382b8", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-en/zipball/b6f563b8760c3b19aad22dd213a9cfba2f2c75d0", + "reference": "b6f563b8760c3b19aad22dd213a9cfba2f2c75d0", "shasum": "" }, - "require": { - "php": ">=5.5.9", - "symfony/dom-crawler": "~2.8|~3.0" - }, - "require-dev": { - "symfony/css-selector": "~2.8|~3.0", - "symfony/process": "~2.8|~3.0" - }, - "suggest": { - "symfony/process": "" - }, - "time": "2017-02-21T09:12:04+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, + "time": "2017-05-20T23:29:05+00:00", + "type": "drupal-console-language", "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\BrowserKit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "David Flores", + "email": "dmousex@gmail.com", + "homepage": "http://dmouse.net" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Jesus Manuel Olivas", + "email": "jesus.olivas@gmail.com", + "homepage": "http://jmolivas.com" + }, + { + "name": "Drupal Console Contributors", + "homepage": "https://github.com/hechoendrupal/DrupalConsole/graphs/contributors" + }, + { + "name": "Eduardo Garcia", + "email": "enzo@enzolutions.com", + "homepage": "http://enzolutions.com/" + }, + { + "name": "Omar Aguirre", + "email": "omersguchigu@gmail.com" } ], - "description": "Symfony BrowserKit Component", - "homepage": "https://symfony.com" + "description": "Drupal Console English Language", + "homepage": "http://drupalconsole.com/", + "keywords": [ + "console", + "development", + "drupal", + "symfony" + ] }, { - "name": "drupal/redirect", - "version": "1.0.0-alpha5", - "version_normalized": "1.0.0.0-alpha5", + "name": "drupal/console-core", + "version": "1.0.0-rc21", + "version_normalized": "1.0.0.0-RC21", "source": { "type": "git", - "url": "https://git.drupal.org/project/redirect", - "reference": "8.x-1.0-alpha5" + "url": "https://github.com/hechoendrupal/drupal-console-core.git", + "reference": "a473a27292110e5f50e0ae8df36d38449ce55903" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/redirect-8.x-1.0-alpha5.zip", - "reference": "8.x-1.0-alpha5", - "shasum": "927aa4c8d8b40b0cd2442bee86f2f386d25e53ca" + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-core/zipball/a473a27292110e5f50e0ae8df36d38449ce55903", + "reference": "a473a27292110e5f50e0ae8df36d38449ce55903", + "shasum": "" }, "require": { - "drupal/core": "~8" + "dflydev/dot-access-configuration": "1.0.1", + "drupal/console-en": "1.0.0-rc21", + "php": "^5.5.9 || ^7.0", + "stecman/symfony-console-completion": "~0.7", + "symfony/config": ">=2.7 <3.0", + "symfony/console": ">=2.7 <3.0", + "symfony/debug": ">=2.6 <3.0", + "symfony/dependency-injection": ">=2.7 <3.0", + "symfony/event-dispatcher": ">=2.7 <3.0", + "symfony/filesystem": ">=2.7 <3.0", + "symfony/finder": ">=2.7 <3.0", + "symfony/process": ">=2.7 <3.0", + "symfony/translation": ">=2.7 <3.0", + "symfony/yaml": ">=2.7 <3.0", + "twig/twig": "^1.23.1", + "webflo/drupal-finder": "^0.3.0" }, - "type": "drupal-module", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0-alpha5", - "datestamp": "1492182542" + "time": "2017-06-07T15:57:23+00:00", + "type": "project", + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Drupal\\Console\\Core\\": "src" } }, - "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "notification-url": "https://packagist.org/downloads/", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Berdir", - "homepage": "https://www.drupal.org/user/214652" + "name": "David Flores", + "email": "dmousex@gmail.com", + "homepage": "http://dmouse.net" }, { - "name": "Dave Reid", - "homepage": "https://www.drupal.org/user/53892" + "name": "Jesus Manuel Olivas", + "email": "jesus.olivas@gmail.com", + "homepage": "http://jmolivas.com" + }, + { + "name": "Drupal Console Contributors", + "homepage": "https://github.com/hechoendrupal/DrupalConsole/graphs/contributors" + }, + { + "name": "Eduardo Garcia", + "email": "enzo@enzolutions.com", + "homepage": "http://enzolutions.com/" + }, + { + "name": "Omar Aguirre", + "email": "omersguchigu@gmail.com" } ], - "description": "Allows users to redirect from old URLs to new URLs.", - "homepage": "https://www.drupal.org/project/redirect", - "support": { - "source": "http://cgit.drupalcode.org/redirect" - } + "description": "Drupal Console Core", + "homepage": "http://drupalconsole.com/", + "keywords": [ + "console", + "development", + "drupal", + "symfony" + ] }, { - "name": "geedmo/yamm3", - "version": "1.1.0", - "version_normalized": "1.1.0.0", + "name": "doctrine/collections", + "version": "v1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", - "url": "https://github.com/geedmo/yamm3.git", - "reference": "5aa11451340187cce1bc195a4437937b19535508" + "url": "https://github.com/doctrine/collections.git", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/geedmo/yamm3/zipball/5aa11451340187cce1bc195a4437937b19535508", - "reference": "5aa11451340187cce1bc195a4437937b19535508", + "url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba", "shasum": "" }, - "time": "2015-04-04T12:59:29+00:00", + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/coding-standard": "~0.1@dev", + "phpunit/phpunit": "^5.7" + }, + "time": "2017-01-03T10:49:41+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, "installation-source": "dist", + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "German Morales", - "email": "geedmo.ds@gmail.com", - "homepage": "http://geedmo.com" + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "Yet another megamenu for Bootstrap 3.x", - "homepage": "http://geedmo.github.io/yamm3/", + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", "keywords": [ - "bootstrap", - "megadropdown", - "megamenu" + "array", + "collections", + "iterator" ] }, { - "name": "grom358/pharborist", - "version": "dev-master", - "version_normalized": "9999999-dev", + "name": "drupal/console", + "version": "1.0.0-rc21", + "version_normalized": "1.0.0.0-RC21", "source": { "type": "git", - "url": "https://github.com/grom358/pharborist.git", - "reference": "0db9e51299a80e95b06857ed1809f59bbbab1af6" + "url": "https://github.com/hechoendrupal/drupal-console.git", + "reference": "e01db040db734b2f8b30921ababc53ce51d01896" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/grom358/pharborist/zipball/0db9e51299a80e95b06857ed1809f59bbbab1af6", - "reference": "0db9e51299a80e95b06857ed1809f59bbbab1af6", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console/zipball/e01db040db734b2f8b30921ababc53ce51d01896", + "reference": "e01db040db734b2f8b30921ababc53ce51d01896", "shasum": "" }, "require": { - "php": ">=5.4", - "phpdocumentor/reflection-docblock": "2.0.*" - }, - "require-dev": { - "apigen/apigen": "2.8.*", - "phpunit/phpunit": "4.2.*" + "alchemy/zippy": "0.4.3", + "composer/installers": "~1.0", + "doctrine/annotations": "1.2.*", + "doctrine/collections": "~1.3", + "drupal/console-core": "1.0.0-rc21", + "drupal/console-extend-plugin": "~0", + "gabordemooij/redbean": "~4.3", + "guzzlehttp/guzzle": "~6.1", + "php": "^5.5.9 || ^7.0", + "psy/psysh": "0.6.* || ~0.8", + "symfony/css-selector": ">=2.7 <3.0", + "symfony/dom-crawler": ">=2.7 <3.3", + "symfony/expression-language": ">=2.7 <3.0", + "symfony/http-foundation": ">=2.7 <3.0" }, - "time": "2015-09-20T22:14:29+00:00", - "type": "library", - "installation-source": "source", + "time": "2017-06-07T16:21:12+00:00", + "bin": [ + "bin/drupal" + ], + "type": "project", + "installation-source": "dist", "autoload": { "psr-4": { - "Pharborist\\": "src/" + "Drupal\\Console\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL" + "GPL-2.0+" ], "authors": [ { - "name": "Cameron Zemek", - "role": "lead" + "name": "David Flores", + "email": "dmousex@gmail.com", + "homepage": "http://dmouse.net" + }, + { + "name": "Jesus Manuel Olivas", + "email": "jesus.olivas@gmail.com", + "homepage": "http://jmolivas.com" + }, + { + "name": "Drupal Console Contributors", + "homepage": "https://github.com/hechoendrupal/DrupalConsole/graphs/contributors" + }, + { + "name": "Eduardo Garcia", + "email": "enzo@enzolutions.com", + "homepage": "http://enzolutions.com/" + }, + { + "name": "Omar Aguirre", + "email": "omersguchigu@gmail.com" } ], - "description": "Pharborist builds a syntax tree for PHP that can be traversed and manipulated.", + "description": "The Drupal CLI. A tool to generate boilerplate code, interact with and debug Drupal.", + "homepage": "http://drupalconsole.com/", "keywords": [ - "standards", - "syntax" + "console", + "development", + "drupal", + "symfony" ] }, { - "name": "drupal/drupalmoduleupgrader", - "version": "dev-1.x", - "version_normalized": "dev-1.x", + "name": "symfony/http-kernel", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/drupalmoduleupgrader", - "reference": "8bf2d9c140d4a315f267ff511fc69ea1595b62b8" + "url": "https://github.com/symfony/http-kernel.git", + "reference": "03ca9421948142df8b9d3ffaeb3bfe8ddee02ca4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/03ca9421948142df8b9d3ffaeb3bfe8ddee02ca4", + "reference": "03ca9421948142df8b9d3ffaeb3bfe8ddee02ca4", + "shasum": "" }, "require": { - "cebe/markdown": "1.0.*@dev", - "drupal/core": "~8.0", - "grom358/pharborist": "dev-master", - "symfony/filesystem": "^2.6.0", - "symfony/finder": "^2.6.0" + "php": ">=5.3.9", + "psr/log": "~1.0", + "symfony/debug": "^2.6.2", + "symfony/event-dispatcher": "^2.6.7|~3.0.0", + "symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6" + }, + "conflict": { + "symfony/config": "<2.7", + "twig/twig": "<1.34|<2.4,>=2" }, "require-dev": { - "mikey179/vfsstream": "^1.5", - "phpunit/phpunit": "^4.8" + "symfony/browser-kit": "~2.3|~3.0.0", + "symfony/class-loader": "~2.1|~3.0.0", + "symfony/config": "~2.8", + "symfony/console": "~2.3|~3.0.0", + "symfony/css-selector": "^2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.8|~3.0.0", + "symfony/dom-crawler": "^2.0.5|~3.0.0", + "symfony/expression-language": "~2.4|~3.0.0", + "symfony/finder": "^2.0.5|~3.0.0", + "symfony/process": "^2.0.5|~3.0.0", + "symfony/routing": "~2.8|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0", + "symfony/templating": "~2.2|~3.0.0", + "symfony/translation": "^2.0.5|~3.0.0", + "symfony/var-dumper": "~2.6|~3.0.0" }, - "type": "drupal-module", + "suggest": { + "symfony/browser-kit": "", + "symfony/class-loader": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "", + "symfony/var-dumper": "" + }, + "time": "2017-06-07T20:12:31+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.2+9-dev", - "datestamp": "1490452983" + "dev-master": "2.8-dev" } }, - "installation-source": "source", + "installation-source": "dist", "autoload": { "psr-4": { - "Drupal\\drupalmoduleupgrader\\": "src/" - } + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, - "notification-url": "https://packages.drupal.org/8/downloads", + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Gábor Hojtsy", - "homepage": "https://www.drupal.org/user/4166" - }, - { - "name": "Wim Leers", - "homepage": "https://www.drupal.org/user/99777" - }, - { - "name": "dstol", - "homepage": "https://www.drupal.org/user/329570" - }, - { - "name": "eshta", - "homepage": "https://www.drupal.org/user/1951462" - }, - { - "name": "japerry", - "homepage": "https://www.drupal.org/user/45640" - }, - { - "name": "jcnventura", - "homepage": "https://www.drupal.org/user/122464" - }, - { - "name": "pfrenssen", - "homepage": "https://www.drupal.org/user/382067" - }, - { - "name": "phenaproxima", - "homepage": "https://www.drupal.org/user/205645" - }, - { - "name": "tim.plunkett", - "homepage": "https://www.drupal.org/user/241634" - }, - { - "name": "webchick", - "homepage": "https://www.drupal.org/user/24967" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "xjm", - "homepage": "https://www.drupal.org/user/65776" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "A Drush command to update Drupal 7 modules to Drupal 8.", - "homepage": "https://www.drupal.org/project/drupalmoduleupgrader", - "keywords": [ - "Drupal", - "PHP_CodeSniffer", - "phpcs", - "standards", - "update", - "upgrade" - ], - "support": { - "source": "https://drupal.org/project/drupalmoduleupgrader", - "issues": "https://drupal.org/project/issues/drupalmoduleupgrader" - } + "description": "Symfony HttpKernel Component", + "homepage": "https://symfony.com" }, { - "name": "drupal/htmlawed", - "version": "3.2.0", - "version_normalized": "3.2.0.0", + "name": "symfony/routing", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/htmLawed", - "reference": "8.x-3.2" + "url": "https://github.com/symfony/routing.git", + "reference": "d428588038f13a0e5771a2a8ccbc9de46bba9a19" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/htmlawed-8.x-3.2.zip", - "reference": "8.x-3.2", - "shasum": "9ced09e67458a0efcd7c4cc7e83f05fb4035ddcc" + "url": "https://api.github.com/repos/symfony/routing/zipball/d428588038f13a0e5771a2a8ccbc9de46bba9a19", + "reference": "d428588038f13a0e5771a2a8ccbc9de46bba9a19", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "php": ">=5.3.9" }, - "type": "drupal-module", + "conflict": { + "symfony/config": "<2.7" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.2", + "psr/log": "~1.0", + "symfony/config": "~2.7|~3.0.0", + "symfony/expression-language": "~2.4|~3.0.0", + "symfony/http-foundation": "~2.3|~3.0.0", + "symfony/yaml": "^2.0.5|~3.0.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/dependency-injection": "For loading routes from a service", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "time": "2017-06-01T20:52:29+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev" - }, - "drupal": { - "version": "8.x-3.2", - "datestamp": "1480745884" + "dev-master": "2.8-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "alpha2zee", - "homepage": "https://www.drupal.org/user/201451" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Use htmLawed to restrict and correct HTML for compliance with admin. policy and standards and for security", - "homepage": "https://www.drupal.org/project/htmlawed", - "support": { - "source": "http://cgit.drupalcode.org/htmlawed" - } + "description": "Symfony Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ] }, { - "name": "mehrpadin/superfish", - "version": "2.0", - "version_normalized": "2.0.0.0", + "name": "symfony-cmf/routing", + "version": "1.4.1", + "version_normalized": "1.4.1.0", "source": { "type": "git", - "url": "https://github.com/mehrpadin/Superfish-for-Drupal.git", - "reference": "af9cb4ef91062a9ab1847595516a73bddf4cde6d" + "url": "https://github.com/symfony-cmf/routing.git", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mehrpadin/Superfish-for-Drupal/zipball/af9cb4ef91062a9ab1847595516a73bddf4cde6d", - "reference": "af9cb4ef91062a9ab1847595516a73bddf4cde6d", + "url": "https://api.github.com/repos/symfony-cmf/routing/zipball/fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", "shasum": "" }, - "time": "2017-01-28T20:31:57+00:00", + "require": { + "php": "^5.3.9|^7.0", + "psr/log": "1.*", + "symfony/http-kernel": "^2.2|3.*", + "symfony/routing": "^2.2|3.*" + }, + "require-dev": { + "friendsofsymfony/jsrouting-bundle": "^1.1", + "symfony-cmf/testing": "^1.3", + "symfony/config": "^2.2|3.*", + "symfony/dependency-injection": "^2.0.5|3.*", + "symfony/event-dispatcher": "^2.1|3.*" + }, + "suggest": { + "symfony/event-dispatcher": "DynamicRouter can optionally trigger an event at the start of matching. Minimal version (~2.1)" + }, + "time": "2017-05-09T08:10:41+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Cmf\\Component\\Routing\\": "" + } + }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Superfish library for the Drupal Superfish module.", - "homepage": "https://github.com/mehrpadin/Superfish-for-Drupal", + "authors": [ + { + "name": "Symfony CMF Community", + "homepage": "https://github.com/symfony-cmf/Routing/contributors" + } + ], + "description": "Extends the Symfony2 routing component for dynamic routes and chaining several routers", + "homepage": "http://cmf.symfony.com", "keywords": [ - "jquery", - "plugin" + "database", + "routing" ] }, { - "name": "drupal/superfish", - "version": "1.0.0-rc6", - "version_normalized": "1.0.0.0-RC6", + "name": "symfony/polyfill-apcu", + "version": "v1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/superfish", - "reference": "8.x-1.0-rc6" + "url": "https://github.com/symfony/polyfill-apcu.git", + "reference": "2e7965b8cdfbba50d0092d3f6dca97dddec409e2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/superfish-8.x-1.0-rc6.zip", - "reference": "8.x-1.0-rc6", - "shasum": "0e9ca0b25eef5cb6c0beaab233b3062a51e87699" + "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/2e7965b8cdfbba50d0092d3f6dca97dddec409e2", + "reference": "2e7965b8cdfbba50d0092d3f6dca97dddec409e2", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "php": ">=5.3.3" }, - "type": "drupal-module", + "time": "2017-06-09T08:25:21+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0-rc6", - "datestamp": "1486319283" + "dev-master": "1.4-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "mehrpadin", - "homepage": "https://www.drupal.org/u/mehrpadin", - "role": "Maintainer" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Adds jQuery Superfish plugin to menu blocks.", - "homepage": "https://www.drupal.org/project/superfish", - "support": { - "source": "https://cgit.drupalcode.org/superfish", - "issues": "https://www.drupal.org/project/superfish" - } + "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "apcu", + "compatibility", + "polyfill", + "portable", + "shim" + ] }, { - "name": "drupal/ctools", - "version": "3.0.0", - "version_normalized": "3.0.0.0", + "name": "symfony/class-loader", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/ctools", - "reference": "8.x-3.0" + "url": "https://github.com/symfony/class-loader.git", + "reference": "48b96f2fa9bf394cb428aced8efb28709ab54cfc" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/ctools-8.x-3.0.zip", - "reference": "8.x-3.0", - "shasum": "302e869ecd1e59fe55663673999fee2ccac5daa8" + "url": "https://api.github.com/repos/symfony/class-loader/zipball/48b96f2fa9bf394cb428aced8efb28709ab54cfc", + "reference": "48b96f2fa9bf394cb428aced8efb28709ab54cfc", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "php": ">=5.3.9", + "symfony/polyfill-apcu": "~1.1" }, - "type": "drupal-module", + "require-dev": { + "symfony/finder": "^2.0.5|~3.0.0" + }, + "time": "2017-06-01T20:52:29+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev" - }, - "drupal": { - "version": "8.x-3.0", - "datestamp": "1493401742" + "dev-master": "2.8-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Symfony\\Component\\ClassLoader\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Kris Vanderwater (EclipseGc)", - "homepage": "https://www.drupal.org/u/eclipsegc", - "role": "Maintainer" - }, - { - "name": "Jakob Perry (japerry)", - "homepage": "https://www.drupal.org/u/japerry", - "role": "Maintainer" - }, - { - "name": "Tim Plunkett (tim.plunkett)", - "homepage": "https://www.drupal.org/u/timplunkett", - "role": "Maintainer" - }, - { - "name": "James Gilliland (neclimdul)", - "homepage": "https://www.drupal.org/u/neclimdul", - "role": "Maintainer" - }, - { - "name": "Daniel Wehner (dawehner)", - "homepage": "https://www.drupal.org/u/dawehner", - "role": "Maintainer" - }, - { - "name": "merlinofchaos", - "homepage": "https://www.drupal.org/user/26979" - }, - { - "name": "neclimdul", - "homepage": "https://www.drupal.org/user/48673" - }, - { - "name": "sdboyer", - "homepage": "https://www.drupal.org/user/146719" - }, - { - "name": "sun", - "homepage": "https://www.drupal.org/user/54136" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "tim.plunkett", - "homepage": "https://www.drupal.org/user/241634" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a number of utility and helper APIs for Drupal developers and site builders.", - "homepage": "https://www.drupal.org/project/ctools", - "support": { - "source": "http://cgit.drupalcode.org/ctools", - "issues": "https://www.drupal.org/project/issues/ctools" - } + "description": "Symfony ClassLoader Component", + "homepage": "https://symfony.com" }, { - "name": "drupal/devel", - "version": "1.0.0-rc2", - "version_normalized": "1.0.0.0-RC2", + "name": "symfony/polyfill-iconv", + "version": "v1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/devel", - "reference": "8.x-1.0-rc2" + "url": "https://github.com/symfony/polyfill-iconv.git", + "reference": "ae1347fa81423b67dbc232c8c111facb367ff8b9" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/devel-8.x-1.0-rc2.zip", - "reference": "8.x-1.0-rc2", - "shasum": "011322bf9c263dab29f94640829f4b654e9c5632" + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/ae1347fa81423b67dbc232c8c111facb367ff8b9", + "reference": "ae1347fa81423b67dbc232c8c111facb367ff8b9", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "php": ">=5.3.3" }, "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available" + "ext-iconv": "For best performance" }, - "type": "drupal-module", + "time": "2017-06-09T08:25:21+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0-rc2", - "datestamp": "1492989244" + "dev-master": "1.4-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Iconv\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Moshe Weitzman", - "homepage": "https://github.com/weitzman", - "email": "weitzman@tejasa.com", - "role": "Maintainer" - }, - { - "name": "Hans Salvisberg", - "homepage": "https://www.drupal.org/u/salvis", - "email": "drupal@salvisberg.com", - "role": "Maintainer" - }, - { - "name": "Luca Lusso", - "homepage": "https://www.drupal.org/u/lussoluca", - "role": "Maintainer" - }, - { - "name": "Marco (willzyx)", - "homepage": "https://www.drupal.org/u/willzyx", - "role": "Maintainer" - }, - { - "name": "See contributors", - "homepage": "https://www.drupal.org/node/3236/committers" - }, - { - "name": "salvis", - "homepage": "https://www.drupal.org/user/82964" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "willzyx", - "homepage": "https://www.drupal.org/user/1043862" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Various blocks, pages, and functions for developers.", - "homepage": "http://drupal.org/project/devel", - "support": { - "source": "http://cgit.drupalcode.org/devel", - "issues": "http://drupal.org/project/devel", - "irc": "irc://irc.freenode.org/drupal-contribute" - } + "description": "Symfony polyfill for the Iconv extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "iconv", + "polyfill", + "portable", + "shim" + ] }, { - "name": "drupal/token", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "name": "symfony/serializer", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/token", - "reference": "8.x-1.0" + "url": "https://github.com/symfony/serializer.git", + "reference": "c6ccf71a899711efa21b0a98150b2c0af08f3cb2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/token-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "d24c7f1ffddbd0fc56bc92bacae1c4ff769a4442" + "url": "https://api.github.com/repos/symfony/serializer/zipball/c6ccf71a899711efa21b0a98150b2c0af08f3cb2", + "reference": "c6ccf71a899711efa21b0a98150b2c0af08f3cb2", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "php": ">=5.3.9", + "symfony/polyfill-php55": "~1.0" }, - "type": "drupal-module", + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "symfony/config": "~2.2|~3.0.0", + "symfony/property-access": "~2.3|~3.0.0", + "symfony/yaml": "^2.0.5|~3.0.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "symfony/config": "For using the XML mapping loader.", + "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/yaml": "For using the default YAML mapping loader." + }, + "time": "2017-06-01T20:52:29+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0", - "datestamp": "1493466843" + "dev-master": "2.8-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Berdir", - "homepage": "https://www.drupal.org/user/214652" - }, - { - "name": "Dave Reid", - "homepage": "https://www.drupal.org/user/53892" - }, - { - "name": "eaton", - "homepage": "https://www.drupal.org/user/16496" - }, - { - "name": "fago", - "homepage": "https://www.drupal.org/user/16747" - }, - { - "name": "greggles", - "homepage": "https://www.drupal.org/user/36762" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "mikeryan", - "homepage": "https://www.drupal.org/user/4420" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a user interface for the Token API and some missing core tokens.", - "homepage": "https://www.drupal.org/project/token", - "support": { - "source": "http://cgit.drupalcode.org/token" - } + "description": "Symfony Serializer Component", + "homepage": "https://symfony.com" }, { - "name": "drupal/pathauto", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "name": "symfony/validator", + "version": "v2.8.22", + "version_normalized": "2.8.22.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/pathauto", - "reference": "8.x-1.0" + "url": "https://github.com/symfony/validator.git", + "reference": "9f323f762ad21bfb9df7c1afacbdd8addf0f8c50" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/pathauto-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "4c82a5689a18421c8c73fcc8be7b333bb21ae02a" + "url": "https://api.github.com/repos/symfony/validator/zipball/9f323f762ad21bfb9df7c1afacbdd8addf0f8c50", + "reference": "9f323f762ad21bfb9df7c1afacbdd8addf0f8c50", + "shasum": "" }, "require": { - "drupal/core": "*", - "drupal/ctools": "*", - "drupal/token": "*" - }, - "type": "drupal-module", + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation": "~2.4|~3.0.0" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "egulias/email-validator": "^1.2.1", + "symfony/config": "~2.2|~3.0.0", + "symfony/expression-language": "~2.4|~3.0.0", + "symfony/http-foundation": "~2.3|~3.0.0", + "symfony/intl": "~2.7.25|^2.8.18|~3.2.5", + "symfony/property-access": "~2.3|~3.0.0", + "symfony/yaml": "^2.0.5|~3.0.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "egulias/email-validator": "Strict (RFC compliant) email validation", + "symfony/config": "", + "symfony/expression-language": "For using the 2.4 Expression validator", + "symfony/http-foundation": "", + "symfony/intl": "", + "symfony/property-access": "For using the 2.4 Validator API", + "symfony/yaml": "" + }, + "time": "2017-06-02T14:36:56+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0", - "datestamp": "1493468044" + "dev-master": "2.8-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-4": { + "Symfony\\Component\\Validator\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "Berdir", - "homepage": "https://www.drupal.org/user/214652" - }, - { - "name": "Dave Reid", - "homepage": "https://www.drupal.org/user/53892" - }, - { - "name": "Freso", - "homepage": "https://www.drupal.org/user/27504" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "greggles", - "homepage": "https://www.drupal.org/user/36762" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a mechanism for modules to automatically generate aliases for the content they manage.", - "homepage": "https://www.drupal.org/project/pathauto", - "support": { - "source": "http://cgit.drupalcode.org/pathauto" - } + "description": "Symfony Validator Component", + "homepage": "https://symfony.com" }, { - "name": "drupal/views_bootstrap", - "version": "dev-3.x", - "version_normalized": "dev-3.x", + "name": "sebastian/diff", + "version": "1.4.3", + "version_normalized": "1.4.3.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/views_bootstrap", - "reference": "ef95dac8dfeb8f2d61b0e5d40075a0a6e23e53ca" + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" }, "require": { - "drupal/core": "*" + "php": "^5.3.3 || ^7.0" }, - "type": "drupal-module", + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "time": "2017-05-22T07:24:03+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev" - }, - "drupal": { - "version": "8.x-3.x-dev", - "datestamp": "1490369283" + "dev-master": "1.4-dev" } }, - "installation-source": "source", - "notification-url": "https://packages.drupal.org/8/downloads", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "BSD-3-Clause" ], "authors": [ { - "name": "aburrows", - "homepage": "https://www.drupal.org/user/577844" - }, - { - "name": "ericpugh", - "homepage": "https://www.drupal.org/user/130084" - }, - { - "name": "ikeigenwijs", - "homepage": "https://www.drupal.org/user/583238" + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" }, { - "name": "mrded", - "homepage": "https://www.drupal.org/user/556088" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Integrate the Bootstrap framework with Views.", - "homepage": "https://www.drupal.org/project/views_bootstrap", + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "Drupal" - ], - "support": { - "source": "http://cgit.drupalcode.org/views_bootstrap" - } + "diff" + ] }, { - "name": "drupal/views_responsive_grid", - "version": "dev-1.x", - "version_normalized": "dev-1.x", + "name": "symfony/browser-kit", + "version": "v3.3.2", + "version_normalized": "3.3.2.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/views_responsive_grid", - "reference": "b8478ccf4cb6dc6837a0c1170a848e418499a357" + "url": "https://github.com/symfony/browser-kit.git", + "reference": "c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1", + "reference": "c2c8ceb1aa9dab9eae54e9150e6a588ce3e53be1", + "shasum": "" }, "require": { - "drupal/core": "~8.0" + "php": ">=5.5.9", + "symfony/dom-crawler": "~2.8|~3.0" }, - "type": "drupal-module", + "require-dev": { + "symfony/css-selector": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0" + }, + "suggest": { + "symfony/process": "" + }, + "time": "2017-04-12T14:14:56+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.x-dev", - "datestamp": "1373985289" + "dev-master": "3.3-dev" } }, - "installation-source": "source", - "notification-url": "https://packages.drupal.org/8/downloads", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "iwhitcomb", - "homepage": "https://www.drupal.org/user/771654" - }, - { - "name": "kyletaylored", - "homepage": "https://www.drupal.org/user/2207088" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "markcarver", - "homepage": "https://www.drupal.org/user/501638" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "homepage": "https://www.drupal.org/project/views_responsive_grid", - "support": { - "source": "http://cgit.drupalcode.org/views_responsive_grid" - } + "description": "Symfony BrowserKit Component", + "homepage": "https://symfony.com" }, { - "name": "drupal/imagemagick", - "version": "1.0.0-alpha6", - "version_normalized": "1.0.0.0-alpha6", + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.5", + "version_normalized": "2.0.5.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/imagemagick", - "reference": "8.x-1.0-alpha6" + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/imagemagick-8.x-1.0-alpha6.zip", - "reference": "8.x-1.0-alpha6", - "shasum": "9631b407762076b2f5d9bf3b50b40c28976ddbb7" + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", + "shasum": "" }, "require": { - "drupal/core": "^8.1.0" + "php": ">=5.3.3" }, - "type": "drupal-module", + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "time": "2016-01-25T08:17:30+00:00", + "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0-alpha6", - "datestamp": "1488787683" + "dev-master": "2.0.x-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "MIT" ], "authors": [ { - "name": "chx", - "homepage": "https://www.drupal.org/user/9446" - }, - { - "name": "claudiu.cristea", - "homepage": "https://www.drupal.org/user/56348" - }, - { - "name": "dman", - "homepage": "https://www.drupal.org/user/33240" - }, - { - "name": "dopry", - "homepage": "https://www.drupal.org/user/22202" - }, - { - "name": "drewish", - "homepage": "https://www.drupal.org/user/34869" - }, - { - "name": "gdl", - "homepage": "https://www.drupal.org/user/507326" - }, - { - "name": "mondrake", - "homepage": "https://www.drupal.org/user/1307444" - }, - { - "name": "quicksketch", - "homepage": "https://www.drupal.org/user/35821" - }, - { - "name": "sun", - "homepage": "https://www.drupal.org/user/54136" - }, - { - "name": "walkah", - "homepage": "https://www.drupal.org/user/1531" + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" } - ], - "description": "Provides ImageMagick integration.", - "homepage": "https://www.drupal.org/project/imagemagick", - "support": { - "source": "http://cgit.drupalcode.org/imagemagick" - } + ] }, { - "name": "drupal/bootstrap", - "version": "3.5.0", - "version_normalized": "3.5.0.0", + "name": "drupal/metatag", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/bootstrap", - "reference": "8.x-3.5" + "url": "https://git.drupal.org/project/metatag", + "reference": "8.x-1.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/bootstrap-8.x-3.5.zip", - "reference": "8.x-3.5", - "shasum": "569f8a243ad6a2e04a86123a0b2a594783a09860" + "url": "https://ftp.drupal.org/files/projects/metatag-8.x-1.1.zip", + "reference": null, + "shasum": "bb9b608879e2f7d8086a0e6606286086f5009d71" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "*", + "drupal/token": "*" }, - "type": "drupal-theme", + "require-dev": { + "drupal/metatag_dc": "*", + "drupal/metatag_open_graph": "*" + }, + "type": "drupal-module", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev" + "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-3.5", - "datestamp": "1495040301" + "version": "8.x-1.1", + "datestamp": "1496428672" } }, "installation-source": "dist", @@ -10215,241 +9966,325 @@ ], "authors": [ { - "name": "markcarver", - "homepage": "https://www.drupal.org/user/501638" - }, - { - "name": "neardark", - "homepage": "https://www.drupal.org/user/661076" - }, - { - "name": "sylus", - "homepage": "https://www.drupal.org/user/339714" + "name": "See contributors", + "homepage": "https://www.drupal.org/node/640498/committers", + "role": "Developer" }, { - "name": "wundo", - "homepage": "https://www.drupal.org/user/25523" + "name": "Dave Reid", + "homepage": "https://www.drupal.org/user/53892" } ], - "homepage": "https://www.drupal.org/project/bootstrap", + "description": "Manage meta tags for all entities.", + "homepage": "https://www.drupal.org/project/metatag", + "keywords": [ + "php", + "seo" + ], "support": { - "source": "http://cgit.drupalcode.org/bootstrap" + "source": "http://cgit.drupalcode.org/metatag", + "issues": "http://drupal.org/project/issues/metatag" } }, { - "name": "sunra/php-simple-html-dom-parser", - "version": "v1.5.2", - "version_normalized": "1.5.2.0", + "name": "drupal/memcache", + "version": "2.0.0-alpha3", + "version_normalized": "2.0.0.0-alpha3", "source": { "type": "git", - "url": "https://github.com/sunra/php-simple-html-dom-parser.git", - "reference": "75b9b1cb64502d8f8c04dc11b5906b969af247c6" + "url": "https://git.drupal.org/project/memcache", + "reference": "8.x-2.0-alpha3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sunra/php-simple-html-dom-parser/zipball/75b9b1cb64502d8f8c04dc11b5906b969af247c6", - "reference": "75b9b1cb64502d8f8c04dc11b5906b969af247c6", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/memcache-8.x-2.0-alpha3.zip", + "reference": null, + "shasum": "21db65a220e2a71227fa7a88f4033559fec5c9ff" }, "require": { - "ext-mbstring": "*", - "php": ">=5.3.2" + "drupal/core": "~8.0" }, - "time": "2016-11-22T22:57:47+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-0": { - "Sunra\\PhpSimple\\HtmlDomParser": "Src/" + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + }, + "drupal": { + "version": "8.x-2.0-alpha3", + "datestamp": "1492523944" } }, - "notification-url": "https://packagist.org/downloads/", + "installation-source": "dist", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "MIT" + "GPL-2.0+" ], "authors": [ { - "name": "Sunra", - "email": "sunra@yandex.ru", - "homepage": "https://github.com/sunra" + "name": "Jeremy", + "homepage": "https://www.drupal.org/user/409" }, { - "name": "S.C. Chen", - "homepage": "http://sourceforge.net/projects/simplehtmldom/" + "name": "catch", + "homepage": "https://www.drupal.org/user/35733" + }, + { + "name": "damiankloip", + "homepage": "https://www.drupal.org/user/1037976" + }, + { + "name": "jvandyk", + "homepage": "https://www.drupal.org/user/2375" + }, + { + "name": "robertDouglass", + "homepage": "https://www.drupal.org/user/5449" } ], - "description": "Composer adaptation of: A HTML DOM parser written in PHP5+ let you manipulate HTML in a very easy way! Require PHP 5+. Supports invalid HTML. Find tags on an HTML page with selectors just like jQuery. Extract contents from HTML in a single line.", - "homepage": "https://github.com/sunra/php-simple-html-dom-parser", - "keywords": [ - "dom", - "html", - "parser" - ] + "description": "High performance integration with memcache.", + "homepage": "http://drupal.org/project/memcache", + "support": { + "source": "http://cgit.drupalcode.org/memcache", + "issues": "https://www.drupal.org/project/issues/memcache" + } }, { - "name": "ezyang/htmlpurifier", - "version": "v4.9.2", - "version_normalized": "4.9.2.0", + "name": "consolidation/output-formatters", + "version": "3.1.10", + "version_normalized": "3.1.10.0", "source": { "type": "git", - "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "6d50e5282afdfdfc3e0ff6d192aff56c5629b3d4" + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "3872f19517bfc9da0e14c9e5b6fe0f8c7439ea3a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/6d50e5282afdfdfc3e0ff6d192aff56c5629b3d4", - "reference": "6d50e5282afdfdfc3e0ff6d192aff56c5629b3d4", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/3872f19517bfc9da0e14c9e5b6fe0f8c7439ea3a", + "reference": "3872f19517bfc9da0e14c9e5b6fe0f8c7439ea3a", "shasum": "" }, "require": { - "php": ">=5.2" + "php": ">=5.4.0", + "symfony/console": "^2.8|~3", + "symfony/finder": "~2.5|~3.0" }, "require-dev": { - "simpletest/simpletest": "^1.1" + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "^2.7", + "victorjonsson/markdowndocs": "^1.3" }, - "time": "2017-03-13T06:30:53+00:00", + "time": "2017-06-06T19:08:54+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, "installation-source": "dist", "autoload": { - "psr-0": { - "HTMLPurifier": "library/" - }, - "files": [ - "library/HTMLPurifier.composer.php" - ] + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL" + "MIT" ], "authors": [ { - "name": "Edward Z. Yang", - "email": "admin@htmlpurifier.org", - "homepage": "http://ezyang.com" + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" } ], - "description": "Standards compliant HTML filter written in PHP", - "homepage": "http://htmlpurifier.org/", - "keywords": [ - "html" - ] + "description": "Format text by applying transformations provided by plug-in formatters." }, { - "name": "caxy/php-htmldiff", - "version": "v0.1.4", - "version_normalized": "0.1.4.0", + "name": "drush/drush", + "version": "8.1.12", + "version_normalized": "8.1.12.0", "source": { "type": "git", - "url": "https://github.com/caxy/php-htmldiff.git", - "reference": "9b115a83d49c636d6bae8ffce15b0e1962cb2ed7" + "url": "https://github.com/drush-ops/drush.git", + "reference": "a1d3ab0f1d9ce01556d70015906caaed723f7ba7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/caxy/php-htmldiff/zipball/9b115a83d49c636d6bae8ffce15b0e1962cb2ed7", - "reference": "9b115a83d49c636d6bae8ffce15b0e1962cb2ed7", + "url": "https://api.github.com/repos/drush-ops/drush/zipball/a1d3ab0f1d9ce01556d70015906caaed723f7ba7", + "reference": "a1d3ab0f1d9ce01556d70015906caaed723f7ba7", "shasum": "" }, "require": { - "ezyang/htmlpurifier": "^4.7", - "php": ">=5.3.3", - "sunra/php-simple-html-dom-parser": "^1.5" + "consolidation/annotated-command": "~2", + "consolidation/output-formatters": "~3", + "pear/console_table": "~1.3.0", + "php": ">=5.4.5", + "phpdocumentor/reflection-docblock": "^2.0", + "psr/log": "~1.0", + "psy/psysh": "~0.6", + "symfony/console": "~2.7", + "symfony/event-dispatcher": "~2.7", + "symfony/finder": "~2.7", + "symfony/var-dumper": "~2.7", + "symfony/yaml": "~2.3", + "webmozart/path-util": "~2" }, "require-dev": { - "doctrine/cache": "~1.0", - "phpunit/phpunit": "~5.0" + "phpunit/phpunit": "4.*", + "symfony/process": "2.7.*" }, "suggest": { - "doctrine/cache": "Used for caching the calculated diffs using a Doctrine Cache Provider" + "drush/config-extra": "Provides configuration workflow commands, such as config-merge.", + "ext-pcntl": "*" }, - "time": "2017-05-02T21:16:54+00:00", + "time": "2017-06-05T22:51:34+00:00", + "bin": [ + "drush", + "drush.launcher", + "drush.php", + "drush.complete.sh" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "0.1.x-dev" + "dev-master": "8.0.x-dev" } }, "installation-source": "dist", "autoload": { "psr-0": { - "Caxy\\HtmlDiff": "lib/" + "Drush": "lib/", + "Consolidation": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0" + "GPL-2.0+" ], "authors": [ { - "name": "Josh Schroeder", - "email": "jschroeder@caxy.com", - "homepage": "http://www.caxy.com" + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + }, + { + "name": "Owen Barton", + "email": "drupal@owenbarton.com" + }, + { + "name": "Mark Sonnabaum", + "email": "marksonnabaum@gmail.com" + }, + { + "name": "Antoine Beaupré", + "email": "anarcat@koumbit.org" + }, + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Jonathan Araña Cruz", + "email": "jonhattan@faita.net" + }, + { + "name": "Jonathan Hedstrom", + "email": "jhedstrom@gmail.com" + }, + { + "name": "Christopher Gervais", + "email": "chris@ergonlogic.com" + }, + { + "name": "Dave Reid", + "email": "dave@davereid.net" + }, + { + "name": "Damian Lee", + "email": "damiankloip@googlemail.com" } ], - "description": "A library for comparing two HTML files/snippets and highlighting the differences using simple HTML.", - "homepage": "https://github.com/caxy/php-htmldiff", - "keywords": [ - "diff", - "html" - ] + "description": "Drush is a command line shell and scripting interface for Drupal, a veritable Swiss Army knife designed to make life easier for those of us who spend some of our working hours hacking away at the command prompt.", + "homepage": "http://www.drush.org" }, { - "name": "mkalkbrenner/php-htmldiff-advanced", - "version": "0.0.8", - "version_normalized": "0.0.8.0", + "name": "drupal/migrate_plus", + "version": "4.0.0-beta1", + "version_normalized": "4.0.0.0-beta1", "source": { "type": "git", - "url": "https://github.com/mkalkbrenner/php-htmldiff.git", - "reference": "3a714b48c9c3d3730baaf6d3949691e654cd37c9" + "url": "https://git.drupal.org/project/migrate_plus", + "reference": "8.x-4.0-beta1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mkalkbrenner/php-htmldiff/zipball/3a714b48c9c3d3730baaf6d3949691e654cd37c9", - "reference": "3a714b48c9c3d3730baaf6d3949691e654cd37c9", - "shasum": "" + "url": "https://ftp.drupal.org/files/projects/migrate_plus-8.x-4.0-beta1.zip", + "reference": null, + "shasum": "e64bac006e3ef9ae697b0f2c4b3744af0524e208" }, "require": { - "caxy/php-htmldiff": ">=0.0.6", - "php": ">=5.5.0" + "drupal/core": "^8.3" }, - "time": "2016-07-25T17:07:32+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "src/HtmlDiffAdvancedInterface.php", - "src/HtmlDiffAdvanced.php" - ] + "require-dev": { + "drupal/migrate_example_advanced_setup": "*", + "drupal/migrate_example_setup": "*" }, - "notification-url": "https://packagist.org/downloads/", + "suggest": { + "sainsburys/guzzle-oauth2-plugin": "3.0 required for the OAuth2 authentication plugin" + }, + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-4.x": "4.x-dev" + }, + "drupal": { + "version": "8.x-4.0-beta1", + "datestamp": "1494450185" + } + }, + "installation-source": "dist", + "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GNU General Public License V2" + "GPL-2.0+" ], - "description": "An add-on for the php-htmldiff library for comparing two HTML files/snippets and highlighting the differences using simple HTML.", - "homepage": "https://github.com/mkalkbrenner/php-htmldiff", - "keywords": [ - "diff", - "html" - ] + "authors": [ + { + "name": "Mike Ryan", + "homepage": "https://www.drupal.org/u/mikeryan", + "role": "Maintainer" + }, + { + "name": "mikeryan", + "homepage": "https://www.drupal.org/user/4420" + } + ], + "description": "Enhancements to core migration support.", + "homepage": "https://www.drupal.org/project/migrate_plus", + "support": { + "source": "https://cgit.drupalcode.org/migrate_plus", + "issues": "https://www.drupal.org/project/issues/migrate_plus", + "irc": "irc://irc.freenode.org/drupal-migrate" + } }, { - "name": "drupal/diff", - "version": "1.0.0-rc1", - "version_normalized": "1.0.0.0-RC1", + "name": "drupal/entity_reference_revisions", + "version": "1.3.0", + "version_normalized": "1.3.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/diff", - "reference": "8.x-1.0-rc1" + "url": "https://git.drupal.org/project/entity_reference_revisions", + "reference": "8.x-1.3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/diff-8.x-1.0-rc1.zip", - "reference": "8.x-1.0-rc1", - "shasum": "4945154c2c07444195a7ae07011a3b3db941c72a" + "url": "https://ftp.drupal.org/files/projects/entity_reference_revisions-8.x-1.3.zip", + "reference": null, + "shasum": "78aebb58efbbfcbb2faa40a1afc0830312b32631" }, "require": { - "drupal/core": "~8.0", - "mkalkbrenner/php-htmldiff-advanced": "~0.0.8" + "drupal/core": "~8.0" + }, + "require-dev": { + "drupal/diff": "*" }, "type": "drupal-module", "extra": { @@ -10457,8 +10292,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-rc1", - "datestamp": "1484566683" + "version": "8.x-1.3", + "datestamp": "1495814284" } }, "installation-source": "dist", @@ -10468,84 +10303,58 @@ ], "authors": [ { - "name": "Miro Dietiker (miro_dietiker)", - "homepage": "https://www.drupal.org/u/miro_dietiker", - "role": "Maintainer" - }, - { - "name": "Juampy NR (juampynr)", - "homepage": "https://www.drupal.org/u/juampynr", - "role": "Maintainer" - }, - { - "name": "Lucian Hangea (lhangea)", - "homepage": "https://www.drupal.org/u/lhangea", - "role": "Maintainer" - }, - { - "name": "Alan D.", - "homepage": "https://www.drupal.org/u/alan-d.", - "role": "Maintainer" + "name": "Frans", + "homepage": "https://www.drupal.org/user/514222" }, { - "name": "Brian Gilbert (realityloop).", - "homepage": "https://www.drupal.org/u/realityloop", - "role": "Maintainer" + "name": "jeroen.b", + "homepage": "https://www.drupal.org/user/1853532" }, { "name": "miro_dietiker", "homepage": "https://www.drupal.org/user/227761" - }, - { - "name": "realityloop", - "homepage": "https://www.drupal.org/user/139189" - }, - { - "name": "rötzi", - "homepage": "https://www.drupal.org/user/73064" - }, - { - "name": "yhahn", - "homepage": "https://www.drupal.org/user/264833" } ], - "description": "Compares two entity revisions", - "homepage": "https://www.drupal.org/project/diff", + "description": "Adds a Entity Reference field type with revision support.", + "homepage": "https://www.drupal.org/project/entity_reference_revisions", "support": { - "source": "http://cgit.drupalcode.org/diff", - "issues": "https://www.drupal.org/project/issues/diff" + "source": "http://cgit.drupalcode.org/entity_reference_revisions" } }, { - "name": "drupal/draggableviews", + "name": "drupal/entity_browser", "version": "1.0.0", "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/draggableviews", + "url": "https://git.drupal.org/project/entity_browser", "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/draggableviews-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "007082c2621b45bd8cf73fe5fdd4d292ee88a458" + "url": "https://ftp.drupal.org/files/projects/entity_browser-8.x-1.0.zip", + "reference": null, + "shasum": "6bd7bbcda1eebacc3685e9edaad2ad29b525b2ad" }, "require": { - "drupal/core": "*" + "drupal/core": "~8.0" + }, + "require-dev": { + "drupal/ctools": "*", + "drupal/inline_entity_form": "*", + "drupal/media_entity": "*", + "drupal/paragraphs": "*", + "drupal/token": "*" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-1.x": "1.x-dev", + "dev-8.x-1.x": "8.1.x-dev" }, "drupal": { "version": "8.x-1.0", - "datestamp": "1477076039" - }, - "patches_applied": { - "Sort order not saved when using bootstrap theme": "https://www.drupal.org/files/issues/classes-defined-in-array-2729935-2.patch", - "DraggableViews displays multiple node instances when used in multiple views": "https://www.drupal.org/files/issues/2867159_fixed_problems_with_duplicates_0.patch" + "datestamp": "1492678144" } }, "installation-source": "dist", @@ -10555,65 +10364,77 @@ ], "authors": [ { - "name": "dixon_", - "homepage": "https://www.drupal.org/user/239911" + "name": "Janez Urevc", + "homepage": "https://github.com/slashrsm", + "role": "Maintainer" + }, + { + "name": "Primoz Hmeljak", + "homepage": "https://github.com/primsi", + "role": "Maintainer" }, { - "name": "ginc", - "homepage": "https://www.drupal.org/user/332249" + "name": "See other contributors", + "homepage": "https://www.drupal.org/node/1943336/committers", + "role": "contributor" }, { - "name": "iStryker", - "homepage": "https://www.drupal.org/user/303676" + "name": "Primsi", + "homepage": "https://www.drupal.org/user/282629" }, { - "name": "podarok", - "homepage": "https://www.drupal.org/user/116002" + "name": "marcingy", + "homepage": "https://www.drupal.org/user/77320" }, { - "name": "sevi", - "homepage": "https://www.drupal.org/user/199290" + "name": "samuel.mortenson", + "homepage": "https://www.drupal.org/user/2582268" }, { - "name": "ygerasimov", - "homepage": "https://www.drupal.org/user/257311" + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Complete rewrite of D7 draggableviews", - "homepage": "https://www.drupal.org/project/draggableviews", + "description": "Entity browsing and selecting component.", + "homepage": "http://drupal.org/project/entity_browser", "support": { - "source": "http://cgit.drupalcode.org/draggableviews" + "source": "http://cgit.drupalcode.org/entity_browser", + "issues": "http://drupal.org/project/issues/entity_browser", + "irc": "irc://irc.freenode.org/drupal-contribute" } }, { - "name": "drupal/hacked", - "version": "2.0.0-beta1", - "version_normalized": "2.0.0.0-beta1", + "name": "drupal/dropzonejs", + "version": "1.0.0-alpha7", + "version_normalized": "1.0.0.0-alpha7", "source": { "type": "git", - "url": "https://git.drupal.org/project/hacked", - "reference": "8.x-2.0-beta1" + "url": "https://git.drupal.org/project/dropzonejs", + "reference": "8.x-1.0-alpha7" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/hacked-8.x-2.0-beta1.zip", - "reference": "8.x-2.0-beta1", - "shasum": "97b091470b83b3bdfe9a13673c5c676b3ce0414a" + "url": "https://ftp.drupal.org/files/projects/dropzonejs-8.x-1.0-alpha7.zip", + "reference": null, + "shasum": "62fc6d46cee1d5fa9885bab3e65b3638172311f6" }, "require": { "drupal/core": "*" }, + "require-dev": { + "drupal/entity_browser": "*" + }, + "suggest": { + "enyo/dropzone": "Required to user drupal/dropzonejs. Dropzone is an easy to use drag'n'drop library." + }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-2.x": "2.x-dev" + "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-2.0-beta1", - "datestamp": "1453154039" - }, - "patches_applied": { - "Compatibility with diff module API change: Turn EntityComparisonBase into a service": "https://www.drupal.org/files/issues/hacked-diff-diff-service-2800645-2.patch" + "version": "8.x-1.0-alpha7", + "datestamp": "1495200183" } }, "installation-source": "dist", @@ -10623,139 +10444,205 @@ ], "authors": [ { - "name": "Deciphered", - "homepage": "https://www.drupal.org/user/103796" + "name": "Janez Urevc", + "homepage": "https://drupal.org/u/slashrsm", + "role": "Maintainer" }, { - "name": "Steven Jones", - "homepage": "https://www.drupal.org/user/99644" + "name": "Christian Fritsch", + "homepage": "https://drupal.org/u/chrfritsch", + "role": "Maintainer" + }, + { + "name": "Primoz Hmeljak", + "homepage": "https://drupal.org/u/Primsi", + "role": "Maintainer" + }, + { + "name": "See other contributors", + "homepage": "https://www.drupal.org/node/1998478/committers", + "role": "contributor" + }, + { + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" + }, + { + "name": "wouters_f", + "homepage": "https://www.drupal.org/user/721548" + }, + { + "name": "zkday", + "homepage": "https://www.drupal.org/user/888644" } ], - "description": "Shows if drupal or any of its modules have been changed", - "homepage": "https://www.drupal.org/project/hacked", + "description": "Drupal integration for DropzoneJS - An open source library that provides drag’n’drop file uploads with image previews.", + "homepage": "https://www.drupal.org/project/dropzonejs", + "keywords": [ + "DropzoneJS", + "Drupal" + ], "support": { - "source": "http://cgit.drupalcode.org/hacked" + "source": "https://www.drupal.org/project/dropzonejs", + "issues": "https://www.drupal.org/project/issues/dropzonejs", + "irc": "irc://irc.freenode.org/drupal-contribute" } }, { - "name": "drupal/permissions_by_term", - "version": "1.19.0", - "version_normalized": "1.19.0.0", - "source": { - "type": "git", - "url": "https://git.drupal.org/project/permissions_by_term", - "reference": "8.x-1.19" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/permissions_by_term-8.x-1.19.zip", - "reference": "8.x-1.19", - "shasum": "87ecf60dda39138f648ee57fe4e3ce334b187100" - }, + "name": "drupal/dropzonejs_eb_widget", + "version": "1.0.0-alpha7", + "version_normalized": "1.0.0.0-alpha7", "require": { - "drupal/core": "*" + "drupal/core": "*", + "drupal/dropzonejs": "self.version", + "drupal/entity_browser": "*" }, - "type": "drupal-module", + "type": "metapackage", "extra": { "branch-alias": { "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.19", - "datestamp": "1494360188" + "version": "8.x-1.0-alpha7", + "datestamp": "1495200183" } }, - "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Peter Majmesku", - "homepage": "https://www.drupal.org/user/786132" + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" + }, + { + "name": "Drupal media CI", + "homepage": "https://www.drupal.org/user/3057985" + }, + { + "name": "Primsi", + "homepage": "https://www.drupal.org/user/282629" + }, + { + "name": "chr.fritsch", + "homepage": "https://www.drupal.org/user/2103716" + }, + { + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" + }, + { + "name": "wouters_f", + "homepage": "https://www.drupal.org/user/721548" + }, + { + "name": "zkday", + "homepage": "https://www.drupal.org/user/888644" } ], - "description": "Limits the selection of specific taxonomy terms by users or roles. Prevents users to display nodes and nodes on views pages, for which which they do not have access by taxonomy term restriction.", - "homepage": "https://www.drupal.org/project/permissions_by_term", + "description": "DropzoneJS Entity browser widget", + "homepage": "https://www.drupal.org/project/dropzonejs", "support": { - "source": "http://cgit.drupalcode.org/permissions_by_term" + "source": "http://cgit.drupalcode.org/dropzonejs" } }, { - "name": "drupal/linkit", - "version": "4.3.0", - "version_normalized": "4.3.0.0", - "source": { - "type": "git", - "url": "https://git.drupal.org/project/linkit", - "reference": "8.x-4.3" - }, - "dist": { - "type": "zip", - "url": "https://ftp.drupal.org/files/projects/linkit-8.x-4.3.zip", - "reference": "8.x-4.3", - "shasum": "e624ea2f18a6100b76a8337e24f7c08df6e2235e" - }, + "name": "drupal/entity_browser_entity_form", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "require": { - "drupal/core": "~8.0" + "drupal/core": "~8.0", + "drupal/entity_browser": "self.version", + "drupal/inline_entity_form": "*" }, - "type": "drupal-module", + "type": "metapackage", "extra": { "branch-alias": { - "dev-4.x": "4.x-dev" + "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-4.3", - "datestamp": "1490205830" + "version": "8.x-1.0", + "datestamp": "1492678144" } }, - "installation-source": "dist", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "Emil Stjerneman", - "homepage": "https://stjerneman.com", - "email": "emil@stjerneman.com", - "role": "Maintainer" + "name": "Dave Reid", + "homepage": "https://www.drupal.org/user/53892" + }, + { + "name": "Devin Carlson", + "homepage": "https://www.drupal.org/user/290182" + }, + { + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" + }, + { + "name": "Primsi", + "homepage": "https://www.drupal.org/user/282629" + }, + { + "name": "marcingy", + "homepage": "https://www.drupal.org/user/77320" + }, + { + "name": "samuel.mortenson", + "homepage": "https://www.drupal.org/user/2582268" + }, + { + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Linkit - Enriched linking experience", - "homepage": "http://drupal.org/project/linkit", + "description": "Entity browser inline entity form integration.", + "homepage": "https://www.drupal.org/project/entity_browser", "support": { - "source": "http://cgit.drupalcode.org/linkit", - "issues": "http://drupal.org/project/linkit" + "source": "http://cgit.drupalcode.org/entity_browser" } }, { - "name": "drupal/toc_formatter", - "version": "1.1.0", - "version_normalized": "1.1.0.0", + "name": "drupal/image_widget_crop", + "version": "2.0.0", + "version_normalized": "2.0.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/toc_formatter", - "reference": "8.x-1.1" + "url": "https://git.drupal.org/project/image_widget_crop", + "reference": "8.x-2.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/toc_formatter-8.x-1.1.zip", - "reference": "8.x-1.1", - "shasum": "7da3ef22b5d2e3e93b48fe97cd17ce607a264a9e" + "url": "https://ftp.drupal.org/files/projects/image_widget_crop-8.x-2.0.zip", + "reference": null, + "shasum": "2c8e13e0c73d95a3f8dde5392da2ef20c3d17faa" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "*", + "drupal/crop": "1.x" + }, + "require-dev": { + "drupal/crop": "*", + "drupal/ctools": "3.x-dev", + "drupal/entity_browser": "1.x-dev", + "drupal/file_entity": "*", + "drupal/imce": "1.x-dev", + "drupal/inline_entity_form": "*", + "drupal/media_entity": "*", + "drupal/media_entity_image": "1.x-dev" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-2.x": "2.x-dev" }, "drupal": { - "version": "8.x-1.1", - "datestamp": "1398611927" + "version": "8.x-2.0", + "datestamp": "1492618444" } }, "installation-source": "dist", @@ -10765,46 +10652,63 @@ ], "authors": [ { - "name": "Robert Castelo", - "homepage": "https://www.drupal.org/user/3555" + "name": "Alexandre Mallet", + "homepage": "https://github.com/woprrr", + "role": "Maintainer" }, { - "name": "neilt17", - "homepage": "https://www.drupal.org/user/324142" + "name": "Drupal media CI", + "homepage": "https://www.drupal.org/user/3057985" + }, + { + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" + }, + { + "name": "woprrr", + "homepage": "https://www.drupal.org/user/858604" } ], - "description": "Display formatter that adds a TOC to the top of a text area field.", - "homepage": "https://www.drupal.org/project/toc_formatter", + "description": "Provides an interface for using the features of the Crop API.", + "homepage": "https://www.drupal.org/project/image_widget_crop", + "keywords": [ + "Crop", + "Drupal", + "Drupal Media" + ], "support": { - "source": "http://cgit.drupalcode.org/toc_formatter" + "source": "https://www.drupal.org/project/image_widget_crop", + "issues": "https://www.drupal.org/project/issues/image_widget_crop", + "irc": "irc://irc.freenode.org/drupal-contribute" } }, { - "name": "drupal/advagg", - "version": "2.4.0", - "version_normalized": "2.4.0.0", + "name": "drupal/media_entity_instagram", + "version": "1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/advagg", - "reference": "8.x-2.4" + "url": "https://git.drupal.org/project/media_entity_instagram", + "reference": "8.x-1.4" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/advagg-8.x-2.4.zip", - "reference": "8.x-2.4", - "shasum": "b3a0eb8739d940b7171718227ec30e8ef4ccbb1b" + "url": "https://ftp.drupal.org/files/projects/media_entity_instagram-8.x-1.4.zip", + "reference": null, + "shasum": "2b69b90417f3c458b4db3ba890813c313d381f0e" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "~8.0", + "drupal/media_entity": "*" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-2.x": "2.x-dev" + "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-2.4", - "datestamp": "1493949188" + "version": "8.x-1.4", + "datestamp": "1495556283" } }, "installation-source": "dist", @@ -10814,62 +10718,54 @@ ], "authors": [ { - "name": "Mike Carper (mikeytown2)", - "homepage": "https://www.drupal.org/u/mikeytown2", - "role": "Creator, Maintainer" - }, - { - "name": "Nick Wilde (nickwilde)", - "homepage": "https://www.drupal.org/u/nickwilde", - "email": "design@briarmoon.ca", - "role": "Drupal 8 Port/maintainer" - }, - { - "name": "doublejosh", - "homepage": "https://www.drupal.org/user/199720" + "name": "Drupal Media Team", + "homepage": "https://www.drupal.org/user/3260690" }, { - "name": "iamcarrico", - "homepage": "https://www.drupal.org/user/1300542" + "name": "Primsi", + "homepage": "https://www.drupal.org/user/282629" }, { - "name": "markcarver", - "homepage": "https://www.drupal.org/user/501638" + "name": "chr.fritsch", + "homepage": "https://www.drupal.org/user/2103716" }, { - "name": "mikeytown2", - "homepage": "https://www.drupal.org/user/282446" + "name": "designesse", + "homepage": "https://www.drupal.org/user/854012" }, { - "name": "rupl", - "homepage": "https://www.drupal.org/user/411999" + "name": "slashrsm", + "homepage": "https://www.drupal.org/user/744628" } ], - "description": "Improved aggregation of CSS/JS files to speed up page load times.", - "homepage": "https://drupal.org/project/advagg", + "description": "Media entity Instagram provider.", + "homepage": "https://www.drupal.org/project/media_entity_instagram", "support": { - "source": "https://cgit.drupalcode.org/advagg", - "issues": "https://drupal.org/project/issues/advagg", - "irc": "irc://irc.freenode.org/drupal-contribute" + "source": "http://cgit.drupalcode.org/media_entity_instagram" } }, { - "name": "drupal/videojs", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "name": "drupal/video_embed_field", + "version": "1.5.0", + "version_normalized": "1.5.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/videojs", - "reference": "8.x-1.0" + "url": "https://git.drupal.org/project/video_embed_field", + "reference": "8.x-1.5" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/videojs-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "daf810898fbae1cf608ad45fd4e836bd6935949d" + "url": "https://ftp.drupal.org/files/projects/video_embed_field-8.x-1.5.zip", + "reference": null, + "shasum": "f54d470ef7f863604e51e6ae98cd40ef25de5f79" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "*" + }, + "require-dev": { + "drupal/colorbox": "*", + "drupal/media_entity": "*", + "drupal/media_entity_embeddable_video": "*" }, "type": "drupal-module", "extra": { @@ -10877,11 +10773,9 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1454344739" - }, - "patches_applied": { - "videojs-isapplicable": "https://www.drupal.org/files/issues/videojs-isapplicable.patch" + "version": "8.x-1.x", + "datestamp": "1493246342", + "package": "Field types" } }, "installation-source": "dist", @@ -10891,76 +10785,84 @@ ], "authors": [ { - "name": "Jorrit", - "homepage": "https://www.drupal.org/user/161217" + "name": "Sam152", + "homepage": "https://www.drupal.org/user/1485048" }, { - "name": "heshanlk", - "homepage": "https://www.drupal.org/user/199102" + "name": "jec006", + "homepage": "https://www.drupal.org/user/855980" + }, + { + "name": "plopesc", + "homepage": "https://www.drupal.org/user/282415" } ], - "description": "Video.js is an HTML5 Video Player.", - "homepage": "https://www.drupal.org/project/videojs", + "description": "A pluggable field type for storing videos from external video hosts such as Vimeo and YouTube.", + "homepage": "https://www.drupal.org/project/video_embed_field", "support": { - "source": "http://cgit.drupalcode.org/videojs" + "source": "http://cgit.drupalcode.org/video_embed_field" } }, { - "name": "drupal/ckeditor_widgets", - "version": "dev-1.x", - "version_normalized": "dev-1.x", - "source": { - "type": "git", - "url": "https://git.drupal.org/project/ckeditor_widgets", - "reference": "2d462637f8804b6d0b530604d0376e97a23a3b7f" - }, + "name": "drupal/video_embed_media", + "version": "1.5.0", + "version_normalized": "1.5.0.0", "require": { - "drupal/core": "*" + "drupal/core": "~8.0", + "drupal/media_entity": "*", + "drupal/video_embed_field": "self.version" }, - "type": "drupal-module", + "type": "metapackage", "extra": { "branch-alias": { "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.x-dev", - "datestamp": "1472798939" + "version": "8.x-1.5", + "datestamp": "1493246342" } }, - "installation-source": "source", "notification-url": "https://packages.drupal.org/8/downloads", "license": [ "GPL-2.0+" ], "authors": [ { - "name": "jlyon", - "homepage": "https://www.drupal.org/user/256444" + "name": "Sam152", + "homepage": "https://www.drupal.org/user/1485048" + }, + { + "name": "jec006", + "homepage": "https://www.drupal.org/user/855980" + }, + { + "name": "plopesc", + "homepage": "https://www.drupal.org/user/282415" } ], - "description": "Adds widgets and an Insert Template menu to CKEditor", - "homepage": "https://www.drupal.org/project/ckeditor_widgets", + "description": "Integrates video_embed_field with the media_entity module, creating a new media type tailored to display embedded videos. Useful for websites which are using the media suite of modules.", + "homepage": "https://www.drupal.org/project/video_embed_field", "support": { - "source": "http://cgit.drupalcode.org/ckeditor_widgets" + "source": "http://cgit.drupalcode.org/video_embed_field" } }, { - "name": "drupal/layout_plugin", - "version": "1.0.0-alpha23", - "version_normalized": "1.0.0.0-alpha23", + "name": "drupal/blazy", + "version": "1.0.0-rc2", + "version_normalized": "1.0.0.0-RC2", "source": { "type": "git", - "url": "https://git.drupal.org/project/layout_plugin", - "reference": "8.x-1.0-alpha23" + "url": "https://git.drupal.org/project/blazy", + "reference": "8.x-1.0-rc2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/layout_plugin-8.x-1.0-alpha23.zip", - "reference": "8.x-1.0-alpha23", - "shasum": "c79992e2f52ac6a7c8dc0706512f2c70fc9f5e11" + "url": "https://ftp.drupal.org/files/projects/blazy-8.x-1.0-rc2.zip", + "reference": null, + "shasum": "242f3022b039c6fd3b98f6ce1955d295119b4b5a" }, "require": { - "drupal/core": "~8.0" + "drupal/core": "*" }, "type": "drupal-module", "extra": { @@ -10968,8 +10870,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0-alpha23", - "datestamp": "1476269960" + "version": "8.x-1.0-rc2", + "datestamp": "1495745283" } }, "installation-source": "dist", @@ -10979,55 +10881,55 @@ ], "authors": [ { - "name": "David Snopek", - "homepage": "https://www.drupal.org/user/172527" - }, - { - "name": "Bram Goffings", - "homepage": "https://www.drupal.org/user/266527" + "name": "Gaus Surahman", + "homepage": "https://www.drupal.org/u/gausarts", + "role": "Maintainer" }, { - "name": "Fredrik Lassen", - "homepage": "https://www.drupal.org/user/243377" + "name": "Contributors", + "homepage": "https://www.drupal.org/node/2663268/committers", + "role": "Contributor" } ], - "description": "An API module to hold the Drupal 8 plugin manager for layouts.", - "homepage": "https://www.drupal.org/project/layout_plugin", + "description": "Provides basic bLazy integration for lazy loading and multi-serving images.", + "homepage": "https://drupal.org/project/blazy", "keywords": [ - "layout", - "php" + "Drupal", + "bLazy", + "lazyload" ], "support": { - "source": "http://cgit.drupalcode.org/layout_plugin" + "source": "http://cgit.drupalcode.org/blazy", + "issues": "https://drupal.org/project/issues/blazy" } }, { - "name": "drupal/bootstrap_layouts", - "version": "4.1.0", - "version_normalized": "4.1.0.0", + "name": "drupal/slick", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/bootstrap_layouts", - "reference": "8.x-4.1" + "url": "https://git.drupal.org/project/slick", + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/bootstrap_layouts-8.x-4.1.zip", - "reference": "8.x-4.1", - "shasum": "3f1e7598e9a476e4d396ddc1e49cd2851e948a2c" + "url": "https://ftp.drupal.org/files/projects/slick-8.x-1.0.zip", + "reference": null, + "shasum": "14ae69943a07749163ed13900dcd0a6809c54ebd" }, "require": { - "drupal/core": "~8.0", - "drupal/layout_plugin": "*" + "drupal/blazy": "~1.0", + "drupal/core": "~8.0" }, "type": "drupal-module", "extra": { "branch-alias": { - "dev-4.x": "4.x-dev" + "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-4.1", - "datestamp": "1481413087" + "version": "8.x-1.0", + "datestamp": "1495746183" } }, "installation-source": "dist", @@ -11037,41 +10939,46 @@ ], "authors": [ { - "name": "darol100", - "homepage": "https://www.drupal.org/user/2667123" - }, - { - "name": "hctom", - "homepage": "https://www.drupal.org/user/112790" + "name": "arshadcn", + "homepage": "https://www.drupal.org/user/571032" }, { - "name": "markcarver", - "homepage": "https://www.drupal.org/user/501638" + "name": "gausarts", + "homepage": "https://www.drupal.org/user/159062" } ], - "description": "This module is going to generate layouts with Bootstrap grid system.", - "homepage": "https://www.drupal.org/project/bootstrap_layouts", + "description": "Slick carousel, the last carousel you'll ever need.", + "homepage": "https://drupal.org/project/slick", + "keywords": [ + "Drupal", + "carousel", + "slideshow" + ], "support": { - "source": "http://cgit.drupalcode.org/bootstrap_layouts" + "source": "http://cgit.drupalcode.org/slick", + "issues": "https://drupal.org/project/issues/slick" } }, { - "name": "drupal/tocify", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "name": "drupal/slick_media", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/tocify", - "reference": "8.x-1.2" + "url": "https://git.drupal.org/project/slick_media", + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/tocify-8.x-1.2.zip", - "reference": "8.x-1.2", - "shasum": "687ea298fa66b6e79addd8af25204917acfd0209" + "url": "https://ftp.drupal.org/files/projects/slick_media-8.x-1.0.zip", + "reference": null, + "shasum": "b85a9899c53ca2f59f7cdbba044e2f58ae71e092" }, "require": { - "drupal/core": "*" + "drupal/core": "~8.0", + "drupal/media_entity_image": "*", + "drupal/slick": "*", + "drupal/video_embed_media": "*" }, "type": "drupal-module", "extra": { @@ -11079,8 +10986,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.2", - "datestamp": "1493816586" + "version": "8.x-1.0", + "datestamp": "1495747983" } }, "installation-source": "dist", @@ -11090,45 +10997,63 @@ ], "authors": [ { - "name": "Hydra", - "homepage": "https://www.drupal.org/user/647364" - }, - { - "name": "dawehner", - "homepage": "https://www.drupal.org/user/99340" - }, - { - "name": "sanduhrs", - "homepage": "https://www.drupal.org/user/28074" + "name": "gausarts", + "homepage": "https://www.drupal.org/user/159062" } ], - "description": "Tocify your content", - "homepage": "https://www.drupal.org/project/tocify", - "keywords": [ - "Drupal" - ], + "description": "Provides Slick carousel integration with Media entity.", + "homepage": "https://www.drupal.org/project/slick_media", "support": { - "source": "http://cgit.drupalcode.org/tocify", - "issues": "http://drupal.org/project/issues/tocify" + "source": "http://cgit.drupalcode.org/slick_media" } }, { - "name": "drupal/ckeditor_templates", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "name": "mehrpadin/superfish", + "version": "2.1", + "version_normalized": "2.1.0.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/ckeditor_templates", - "reference": "8.x-1.0" + "url": "https://github.com/mehrpadin/Superfish-for-Drupal.git", + "reference": "80a0a484b727e9fbe6b0ee609f80e10e5e158683" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/ckeditor_templates-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "706be94033bb2babf6fd0fb499c6aa326914b7ff" + "url": "https://api.github.com/repos/mehrpadin/Superfish-for-Drupal/zipball/80a0a484b727e9fbe6b0ee609f80e10e5e158683", + "reference": "80a0a484b727e9fbe6b0ee609f80e10e5e158683", + "shasum": "" + }, + "time": "2017-05-30T13:00:18+00:00", + "type": "drupal-library", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Superfish library for the Drupal Superfish module.", + "homepage": "https://github.com/mehrpadin/Superfish-for-Drupal", + "keywords": [ + "jquery", + "plugin" + ] + }, + { + "name": "drupal/superfish", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://git.drupal.org/project/superfish", + "reference": "8.x-1.1" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/superfish-8.x-1.1.zip", + "reference": null, + "shasum": "f5e9e547d1d38588a963b22105dec1deb1e55010" }, "require": { - "drupal/core": "*" + "drupal/core": "~8.0", + "mehrpadin/superfish": "~2.0" }, "type": "drupal-module", "extra": { @@ -11136,8 +11061,8 @@ "dev-1.x": "1.x-dev" }, "drupal": { - "version": "8.x-1.0", - "datestamp": "1490206982" + "version": "8.x-1.1", + "datestamp": "1496335443" } }, "installation-source": "dist", @@ -11147,262 +11072,249 @@ ], "authors": [ { - "name": "lucaslg", - "homepage": "https://www.drupal.org/user/3128975" + "name": "mehrpadin", + "homepage": "https://www.drupal.org/u/mehrpadin", + "role": "Maintainer" } ], - "description": "Integrates the CKEdito templates plugin", - "homepage": "https://www.drupal.org/project/ckeditor_templates", + "description": "Adds jQuery Superfish plugin to menu blocks.", + "homepage": "https://www.drupal.org/project/superfish", "support": { - "source": "http://cgit.drupalcode.org/ckeditor_templates" + "source": "https://cgit.drupalcode.org/superfish", + "issues": "https://www.drupal.org/project/superfish" } }, { - "name": "drupal/layouter", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "name": "phpunit/phpunit", + "version": "4.8.36", + "version_normalized": "4.8.36.0", "source": { "type": "git", - "url": "https://git.drupal.org/project/layouter", - "reference": "8.x-1.0" + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/layouter-8.x-1.0.zip", - "reference": "8.x-1.0", - "shasum": "c9bc5f4c178acabc06bdec71662f7c7c3df614ce" + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", + "shasum": "" }, "require": { - "drupal/core": "*" - }, - "type": "drupal-module", - "extra": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.2.2", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "time": "2017-06-21T08:07:12+00:00", + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" - }, - "drupal": { - "version": "8.x-1.0", - "datestamp": "1470121439" + "dev-master": "4.8.x-dev" } }, "installation-source": "dist", - "notification-url": "https://packages.drupal.org/8/downloads", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL 2.0+" + "BSD-3-Clause" ], "authors": [ { - "name": "adci_contributor", - "homepage": "https://www.drupal.org/user/1830536" - }, - { - "name": "adcillc", - "homepage": "https://www.drupal.org/user/366450" - }, - { - "name": "antongp", - "homepage": "https://www.drupal.org/user/1060446" - }, - { - "name": "kinosura", - "homepage": "https://www.drupal.org/user/383326" - }, - { - "name": "usdv", - "homepage": "https://www.drupal.org/user/2476206" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Allows to choose one of predefined layouts which is applied to the content that you want to put into textarea fields.", - "homepage": "https://www.drupal.org/project/layouter", - "support": { - "source": "http://cgit.drupalcode.org/layouter" - } + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ] }, { - "name": "drupal/core", - "version": "8.3.4", - "version_normalized": "8.3.4.0", + "name": "j7mbo/twitter-api-php", + "version": "1.0.6", + "version_normalized": "1.0.6.0", "source": { "type": "git", - "url": "https://github.com/drupal/core.git", - "reference": "f34eee7255142ab5416107972ef13d011f11e163" + "url": "https://github.com/J7mbo/twitter-api-php.git", + "reference": "443d22c53d621b3cc6b7e0c56daa60c5ada033f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/f34eee7255142ab5416107972ef13d011f11e163", - "reference": "f34eee7255142ab5416107972ef13d011f11e163", + "url": "https://api.github.com/repos/J7mbo/twitter-api-php/zipball/443d22c53d621b3cc6b7e0c56daa60c5ada033f7", + "reference": "443d22c53d621b3cc6b7e0c56daa60c5ada033f7", "shasum": "" }, "require": { - "asm89/stack-cors": "~1.0", - "composer/semver": "~1.0", - "doctrine/annotations": "1.2.*", - "doctrine/common": "^2.5", - "easyrdf/easyrdf": "0.9.*", - "egulias/email-validator": "1.2.*", - "guzzlehttp/guzzle": "^6.2.1", - "masterminds/html5": "~2.1", - "paragonie/random_compat": "^1.0|^2.0", - "php": ">=5.5.9", - "stack/builder": "1.0.*", - "symfony-cmf/routing": "~1.4", - "symfony/class-loader": "~2.8", - "symfony/console": "~2.8", - "symfony/dependency-injection": "~2.8", - "symfony/event-dispatcher": "~2.8", - "symfony/http-foundation": "~2.8", - "symfony/http-kernel": "~2.8", - "symfony/polyfill-iconv": "~1.0", - "symfony/process": "~2.8", - "symfony/psr-http-message-bridge": "^1.0", - "symfony/routing": "~2.8", - "symfony/serializer": "~2.8", - "symfony/translation": "~2.8", - "symfony/validator": "~2.8", - "symfony/yaml": "~2.8", - "twig/twig": "^1.23.1", - "zendframework/zend-diactoros": "~1.1", - "zendframework/zend-feed": "~2.4" + "ext-curl": "*" }, - "conflict": { - "drush/drush": "<8.1.10" + "require-dev": { + "phpunit/phpunit": "~4.5,>=4.5.1" }, - "replace": { - "drupal/action": "self.version", - "drupal/aggregator": "self.version", - "drupal/automated_cron": "self.version", - "drupal/ban": "self.version", - "drupal/bartik": "self.version", - "drupal/basic_auth": "self.version", - "drupal/big_pipe": "self.version", - "drupal/block": "self.version", - "drupal/block_content": "self.version", - "drupal/block_place": "self.version", - "drupal/book": "self.version", - "drupal/breakpoint": "self.version", - "drupal/ckeditor": "self.version", - "drupal/classy": "self.version", - "drupal/color": "self.version", - "drupal/comment": "self.version", - "drupal/config": "self.version", - "drupal/config_translation": "self.version", - "drupal/contact": "self.version", - "drupal/content_moderation": "self.version", - "drupal/content_translation": "self.version", - "drupal/contextual": "self.version", - "drupal/core-annotation": "self.version", - "drupal/core-assertion": "self.version", - "drupal/core-bridge": "self.version", - "drupal/core-datetime": "self.version", - "drupal/core-dependency-injection": "self.version", - "drupal/core-diff": "self.version", - "drupal/core-discovery": "self.version", - "drupal/core-event-dispatcher": "self.version", - "drupal/core-file-cache": "self.version", - "drupal/core-filesystem": "self.version", - "drupal/core-gettext": "self.version", - "drupal/core-graph": "self.version", - "drupal/core-http-foundation": "self.version", - "drupal/core-php-storage": "self.version", - "drupal/core-plugin": "self.version", - "drupal/core-proxy-builder": "self.version", - "drupal/core-render": "self.version", - "drupal/core-serialization": "self.version", - "drupal/core-transliteration": "self.version", - "drupal/core-utility": "self.version", - "drupal/core-uuid": "self.version", - "drupal/datetime": "self.version", - "drupal/datetime_range": "self.version", - "drupal/dblog": "self.version", - "drupal/dynamic_page_cache": "self.version", - "drupal/editor": "self.version", - "drupal/entity_reference": "self.version", - "drupal/field": "self.version", - "drupal/field_layout": "self.version", - "drupal/field_ui": "self.version", - "drupal/file": "self.version", - "drupal/filter": "self.version", - "drupal/forum": "self.version", - "drupal/hal": "self.version", - "drupal/help": "self.version", - "drupal/history": "self.version", - "drupal/image": "self.version", - "drupal/inline_form_errors": "self.version", - "drupal/language": "self.version", - "drupal/layout_discovery": "self.version", - "drupal/link": "self.version", - "drupal/locale": "self.version", - "drupal/menu_link_content": "self.version", - "drupal/menu_ui": "self.version", - "drupal/migrate": "self.version", - "drupal/migrate_drupal": "self.version", - "drupal/migrate_drupal_ui": "self.version", - "drupal/minimal": "self.version", - "drupal/node": "self.version", - "drupal/options": "self.version", - "drupal/outside_in": "self.version", - "drupal/page_cache": "self.version", - "drupal/path": "self.version", - "drupal/quickedit": "self.version", - "drupal/rdf": "self.version", - "drupal/responsive_image": "self.version", - "drupal/rest": "self.version", - "drupal/search": "self.version", - "drupal/serialization": "self.version", - "drupal/seven": "self.version", - "drupal/shortcut": "self.version", - "drupal/simpletest": "self.version", - "drupal/standard": "self.version", - "drupal/stark": "self.version", - "drupal/statistics": "self.version", - "drupal/syslog": "self.version", - "drupal/system": "self.version", - "drupal/taxonomy": "self.version", - "drupal/telephone": "self.version", - "drupal/text": "self.version", - "drupal/toolbar": "self.version", - "drupal/tour": "self.version", - "drupal/tracker": "self.version", - "drupal/update": "self.version", - "drupal/user": "self.version", - "drupal/views": "self.version", - "drupal/views_ui": "self.version", - "drupal/workflows": "self.version" + "time": "2017-05-08T12:10:56+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "TwitterAPIExchange.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GNU Public License" + ], + "authors": [ + { + "name": "James Mallison", + "homepage": "https://github.com/j7mbo/twitter-api-php" + } + ], + "description": "Simple PHP Wrapper for Twitter API v1.1 calls", + "homepage": "https://github.com/j7mbo/twitter-api-php", + "keywords": [ + "api", + "php", + "twitter" + ] + }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.9.3", + "version_normalized": "4.9.3.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "95e1bae3182efc0f3422896a3236e991049dac69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/95e1bae3182efc0f3422896a3236e991049dac69", + "reference": "95e1bae3182efc0f3422896a3236e991049dac69", + "shasum": "" + }, + "require": { + "php": ">=5.2" }, "require-dev": { - "behat/mink": "1.7.x-dev", - "behat/mink-goutte-driver": "~1.2", - "drupal/coder": "8.2.12", - "jcalderonzumba/gastonjs": "~1.0.2", - "jcalderonzumba/mink-phantomjs-driver": "~0.3.1", - "mikey179/vfsstream": "~1.2", - "phpunit/phpunit": ">=4.8.28 <5", - "symfony/browser-kit": ">=2.8.13 <3.0", - "symfony/css-selector": "~2.8" + "simpletest/simpletest": "^1.1" }, - "time": "2017-06-21T18:13:27+00:00", - "type": "drupal-core", + "time": "2017-06-03T02:28:16+00:00", + "type": "library", "installation-source": "dist", "autoload": { - "psr-4": { - "Drupal\\Core\\": "lib/Drupal/Core", - "Drupal\\Component\\": "lib/Drupal/Component", - "Drupal\\Driver\\": "../drivers/lib/Drupal/Driver" + "psr-0": { + "HTMLPurifier": "library/" }, - "classmap": [ - "lib/Drupal.php", - "lib/Drupal/Component/Utility/Timer.php", - "lib/Drupal/Component/Utility/Unicode.php", - "lib/Drupal/Core/Database/Database.php", - "lib/Drupal/Core/DrupalKernel.php", - "lib/Drupal/Core/DrupalKernelInterface.php", - "lib/Drupal/Core/Site/Settings.php" + "files": [ + "library/HTMLPurifier.composer.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0+" + "LGPL" ], - "description": "Drupal is an open source content management platform powering millions of websites and applications." + "authors": [ + { + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" + } + ], + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", + "keywords": [ + "html" + ] + }, + { + "name": "caxy/php-htmldiff", + "version": "v0.1.5", + "version_normalized": "0.1.5.0", + "source": { + "type": "git", + "url": "https://github.com/caxy/php-htmldiff.git", + "reference": "d7540c9938c860f2cb7083f72ba24c45f51d57bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/caxy/php-htmldiff/zipball/d7540c9938c860f2cb7083f72ba24c45f51d57bc", + "reference": "d7540c9938c860f2cb7083f72ba24c45f51d57bc", + "shasum": "" + }, + "require": { + "ezyang/htmlpurifier": "^4.7", + "php": ">=5.3.3", + "sunra/php-simple-html-dom-parser": "^1.5" + }, + "require-dev": { + "doctrine/cache": "~1.0", + "phpunit/phpunit": "~5.0" + }, + "suggest": { + "doctrine/cache": "Used for caching the calculated diffs using a Doctrine Cache Provider" + }, + "time": "2017-06-12T17:35:44+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Caxy\\HtmlDiff": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0" + ], + "authors": [ + { + "name": "Josh Schroeder", + "email": "jschroeder@caxy.com", + "homepage": "http://www.caxy.com" + } + ], + "description": "A library for comparing two HTML files/snippets and highlighting the differences using simple HTML.", + "homepage": "https://github.com/caxy/php-htmldiff", + "keywords": [ + "diff", + "html" + ] } ] diff --git a/vendor/composer/installers/.editorconfig b/vendor/composer/installers/.editorconfig new file mode 100644 index 000000000..153cf3ef5 --- /dev/null +++ b/vendor/composer/installers/.editorconfig @@ -0,0 +1,10 @@ +; top-most EditorConfig file +root = true + +; Unix-style newlines +[*] +end_of_line = LF + +[*.php] +indent_style = space +indent_size = 4 diff --git a/vendor/composer/installers/.gitignore b/vendor/composer/installers/.gitignore new file mode 100644 index 000000000..ff7f293dc --- /dev/null +++ b/vendor/composer/installers/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +.idea/ diff --git a/vendor/composer/installers/.travis.yml b/vendor/composer/installers/.travis.yml new file mode 100644 index 000000000..c2ec2d16e --- /dev/null +++ b/vendor/composer/installers/.travis.yml @@ -0,0 +1,23 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - hhvm + +matrix: + fast_finish: true + allow_failures: + - php: 7.0 + - php: 7.1 + +before_script: + - composer self-update + - composer install + +script: + - composer test diff --git a/vendor/composer/installers/CHANGELOG.md b/vendor/composer/installers/CHANGELOG.md new file mode 100644 index 000000000..d5d26197d --- /dev/null +++ b/vendor/composer/installers/CHANGELOG.md @@ -0,0 +1,60 @@ +# Change Log + +## v1.3.0 - 2017-04-24 +### Added +* Kanboard plugins installer. +* Porto-SAP installer. +* Add `core` to concrete5 installer. +* Support Moodle "search" plugin type. +* SyDES installer. +* iTop installer. +* Lavalite installer. +* Module type for Eliasis. +* Vgmcp installer. +* OntoWiki installer. +* The requirements for contributing (CONTRIBUTING.md). + +### Changed +* Concrete5: block & theme install location updates. + +## v1.2.0 - 2016-08-13 +### Added +* Installer for Attogram. +* Installer for Cockpit. +* Installer for Plentymarkets. +* Installer for ReIndex. +* Installer for Vanilla. +* Installer for YAWIK. +* Added missing environments for new Shopware (5.2) Plugin System. + +## v1.1.0 - 2016-07-05 +### Added +* Installer for ReIndex. +* Installer for RadPHP. +* Installer for Decibel. +* Installer for Phifty. +* Installer for ExpressionEngine. + +### Changed +* New paths for new Bitrix CMS. Old paths is deprecated. + +### Deprecated +* Old paths in Bitrix CMS Installer is deprecated. + +## v1.0.25 - 2016-04-13 +### Removed +* Revert TYPO3 installer deletion. + +## v1.0.24 - 2016-04-05 +### Added +* Installer for ImageCMS. +* Installer for Mautic. +* New types in the Kirby installer: `kirby-plugin` and `kirby-field`. +* New types in the Drupal installer: `custom-theme` and `custom-module`. + +### Changed +* Switch to PSR-4. +* Update Bitrix Installer: configuration for setting custom path to directory with kernel. + +### Removed +* Remove TYPO3 Extension installers. diff --git a/vendor/composer/installers/CONTRIBUTING.md b/vendor/composer/installers/CONTRIBUTING.md new file mode 100644 index 000000000..1b1998e01 --- /dev/null +++ b/vendor/composer/installers/CONTRIBUTING.md @@ -0,0 +1,24 @@ +# Contributing + +If you would like to help, please take a look at the list of +[issues](https://github.com/composer/installers/issues). + +## Pull requests + +* [Fork and clone](https://help.github.com/articles/fork-a-repo). +* Run the command `php composer.phar install` to install the dependencies. + This will also install the dev dependencies. See [Composer](https://getcomposer.org/doc/03-cli.md#install). +* Use the command `phpunit` to run the tests. See [PHPUnit](http://phpunit.de). +* Create a branch, commit, push and send us a + [pull request](https://help.github.com/articles/using-pull-requests). + +To ensure a consistent code base, you should make sure the code follows the +coding standards [PSR-1](http://www.php-fig.org/psr/psr-1/) and +[PSR-2](http://www.php-fig.org/psr/psr-2/). + +### Create a new Installer + +* Create class extends `Composer\Installers\BaseInstaller` with your Installer. +* Create unit tests as a separate class or as part of a `Composer\Installers\Test\InstallerTest`. +* Add information about your Installer in `README.md` in section "Current Supported Package Types". +* Run the tests. diff --git a/vendor/composer/installers/README.md b/vendor/composer/installers/README.md new file mode 100644 index 000000000..332142c55 --- /dev/null +++ b/vendor/composer/installers/README.md @@ -0,0 +1,214 @@ +# A Multi-Framework [Composer](http://getcomposer.org) Library Installer + +[![Build Status](http://img.shields.io/travis/composer/installers.svg)](http://travis-ci.org/composer/installers) + +This is for PHP package authors to require in their `composer.json`. It will +install their package to the correct location based on the specified package +type. + +The goal of Installers is to be a simple package type to install path map. +Users can also customize the install path per package and package authors can +modify the package name upon installing. + +Installers isn't intended on replacing all custom installers. If your +package requires special installation handling then by all means, create a +custom installer to handle it. + +**Natively Supported Frameworks**: + +The following frameworks natively work with Composer and will be +installed to the default `vendor` directory. `composer/installers` +is not needed to install packages with these frameworks: + +* Aura +* Symfony2 +* Yii +* Yii2 + +## Current Supported Package Types + +> Stable types are marked as **bold**, this means that installation paths +> for those type will not be changed. Any adjustment for those types would +> require creation of brand new type that will cover required changes. + +| Framework | Types +| --------- | ----- +| Aimeos | `aimeos-extension` +| Asgard | `asgard-module`
`asgard-theme` +| Attogram | `attogram-module` +| AGL | `agl-module` +| Bonefish | `bonefish-package` +| AnnotateCms | `annotatecms-module`
`annotatecms-component`
`annotatecms-service` +| Bitrix | `bitrix-module` (deprecated)
`bitrix-component` (deprecated)
`bitrix-theme` (deprecated)

`bitrix-d7-module`
`bitrix-d7-component`
`bitrix-d7-template` +| CakePHP 2+ | **`cakephp-plugin`** +| Chef | `chef-cookbook`
`chef-role` +| CCFramework | `ccframework-ship`
`ccframework-theme` +| Cockpit | `cockpit-module` +| CodeIgniter | `codeigniter-library`
`codeigniter-third-party`
`codeigniter-module` +| concrete5 | `concrete5-core`
`concrete5-package`
`concrete5-theme`
`concrete5-block`
`concrete5-update` +| Craft | `craft-plugin` +| Croogo | `croogo-plugin`
`croogo-theme` +| Decibel | `decibel-app` +| DokuWiki | `dokuwiki-plugin`
`dokuwiki-template` +| Dolibarr | `dolibarr-module` +| Drupal | `drupal-core`
`drupal-module`
`drupal-theme`

`drupal-library`
`drupal-profile`
`drupal-drush` +| Elgg | `elgg-plugin` +| Eliasis | `eliasis-module` +| ExpressionEngine 3 | `ee3-addon`
`ee3-theme` +| FuelPHP v1.x | `fuel-module`
`fuel-package`
`fuel-theme` +| FuelPHP v2.x | `fuelphp-component` +| Grav | `grav-plugin`
`grav-theme` +| Hurad | `hurad-plugin`
`hurad-theme` +| ImageCMS | `imagecms-template`
`imagecms-module`
`imagecms-library` +| iTop | `itop-extension` +| Joomla | `joomla-component`
`joomla-module`
`joomla-template`
`joomla-plugin`
`joomla-library` +| Kanboard | `kanboard-plugin` +| Kirby | **`kirby-plugin`**
`kirby-field`
`kirby-tag` +| KodiCMS | `kodicms-plugin`
`kodicms-media` +| Kohana | **`kohana-module`** +| Laravel | `laravel-library` +| Lavalite | `lavalite-theme`
`lavalite-package` +| Lithium | **`lithium-library`
`lithium-source`** +| Magento | `magento-library`
`magento-skin`
`magento-theme` +| Mako | `mako-package` +| Mautic | `mautic-plugin`
`mautic-theme` +| Maya | `maya-module` +| MODX Evo | `modxevo-snippet`
`modxevo-plugin`
`modxevo-module`
`modxevo-template`
`modxevo-lib` +| MediaWiki | `mediawiki-extension` +| October | **`october-module`
`october-plugin`
`october-theme`** +| OntoWiki | `ontowiki-extension`
`ontowiki-theme`
`ontowiki-translation` +| OXID | `oxid-module`
`oxid-theme`
`oxid-out` +| MODULEWork | `modulework-module` +| Moodle | `moodle-*` (Please [check source](https://raw.githubusercontent.com/composer/installers/master/src/Composer/Installers/MoodleInstaller.php) for all supported types) +| Piwik | `piwik-plugin` +| phpBB | `phpbb-extension`
`phpbb-style`
`phpbb-language` +| Pimcore | `pimcore-plugin` +| Plentymarkets | `plentymarkets-plugin` +| PPI | **`ppi-module`** +| Puppet | `puppet-module` +| Porto | `porto-container` +| RadPHP | `radphp-bundle` +| REDAXO | `redaxo-addon` +| ReIndex | **`reindex-plugin`**
**`reindex-theme`** +| Roundcube | `roundcube-plugin` +| shopware | `shopware-backend-plugin`
`shopware-core-plugin`
`shopware-frontend-plugin`
`shopware-theme`
`shopware-plugin`
`shopware-frontend-theme` +| SilverStripe | `silverstripe-module`
`silverstripe-theme` +| SMF | `smf-module`
`smf-theme` +| SyDES | `sydes-module`
`sydes-theme` +| symfony1 | **`symfony1-plugin`** +| Tusk | `tusk-task`
`tusk-command`
`tusk-asset` +| TYPO3 Flow | `typo3-flow-package`
`typo3-flow-framework`
`typo3-flow-plugin`
`typo3-flow-site`
`typo3-flow-boilerplate`
`typo3-flow-build` +| TYPO3 CMS | `typo3-cms-extension` (Deprecated in this package, use the [TYPO3 CMS Installers](https://packagist.org/packages/typo3/cms-composer-installers) instead) +| Vanilla | `vanilla-plugin`
`vanilla-theme` +| Vgmcp | `vgmcp-bundle`
`vgmcp-theme` +| Wolf CMS | `wolfcms-plugin` +| WordPress | `wordpress-plugin`
`wordpress-theme`

`wordpress-muplugin` +| YAWIK | `yawik-module` +| Zend | `zend-library`
`zend-extra`
`zend-module` +| Zikula | `zikula-module`
`zikula-theme` +| Prestashop | `prestashop-module`
`prestashop-theme` +| Phifty | `phifty-bundle`
`phifty-framework`
`phifty-library` + +## Example `composer.json` File + +This is an example for a CakePHP plugin. The only important parts to set in your +composer.json file are `"type": "cakephp-plugin"` which describes what your +package is and `"require": { "composer/installers": "~1.0" }` which tells composer +to load the custom installers. + +```json +{ + "name": "you/ftp", + "type": "cakephp-plugin", + "require": { + "composer/installers": "~1.0" + } +} +``` + +This would install your package to the `Plugin/Ftp/` folder of a CakePHP app +when a user runs `php composer.phar install`. + +So submit your packages to [packagist.org](http://packagist.org)! + +## Custom Install Paths + +If you are consuming a package that uses the `composer/installers` you can +override the install path with the following extra in your `composer.json`: + +```json +{ + "extra": { + "installer-paths": { + "your/custom/path/{$name}/": ["shama/ftp", "vendor/package"] + } + } +} +``` + +A package type can have a custom installation path with a `type:` prefix. + +``` json +{ + "extra": { + "installer-paths": { + "your/custom/path/{$name}/": ["type:wordpress-plugin"] + } + } +} +``` + +You can also have the same vendor packages with a custom installation path by +using the `vendor:` prefix. + +``` json +{ + "extra": { + "installer-paths": { + "your/custom/path/{$name}/": ["vendor:my_organization"] + } + } +} +``` + +These would use your custom path for each of the listed packages. The available +variables to use in your paths are: `{$name}`, `{$vendor}`, `{$type}`. + +## Custom Install Names + +If you're a package author and need your package to be named differently when +installed consider using the `installer-name` extra. + +For example you have a package named `shama/cakephp-ftp` with the type +`cakephp-plugin`. Installing with `composer/installers` would install to the +path `Plugin/CakephpFtp`. Due to the strict naming conventions, you as a +package author actually need the package to be named and installed to +`Plugin/Ftp`. Using the following config within your **package** `composer.json` +will allow this: + +```json +{ + "name": "shama/cakephp-ftp", + "type": "cakephp-plugin", + "extra": { + "installer-name": "Ftp" + } +} +``` + +Please note the name entered into `installer-name` will be the final and will +not be inflected. + +## Should we allow dynamic package types or paths? No. + +What are they? The ability for a package author to determine where a package +will be installed either through setting the path directly in their +`composer.json` or through a dynamic package type: `"type": +"framework-install-here"`. + +It has been proposed many times. Even implemented once early on and then +removed. Installers won't do this because it would allow a single package +author to wipe out entire folders without the user's consent. That user would +then come here to yell at us. + +Anyone still wanting this capability should consider requiring https://github.com/oomphinc/composer-installers-extender. diff --git a/vendor/composer/installers/composer.json b/vendor/composer/installers/composer.json index 3b12fa51e..4dd0b9045 100644 --- a/vendor/composer/installers/composer.json +++ b/vendor/composer/installers/composer.json @@ -21,18 +21,23 @@ "Dolibarr", "Drupal", "Elgg", + "Eliasis", "ExpressionEngine", "FuelPHP", "Grav", "Hurad", "ImageCMS", + "iTop", "Joomla", + "Kanboard", "Kohana", "Laravel", + "Lavalite", "Lithium", "Magento", "Mako", "Mautic", + "Maya", "MODX Evo", "MediaWiki", "OXID", @@ -43,12 +48,14 @@ "Plentymarkets", "PPI", "Puppet", + "Porto", "RadPHP", "ReIndex", "Roundcube", "shopware", "SilverStripe", "SMF", + "SyDES", "symfony", "Thelia", "TYPO3", diff --git a/vendor/composer/installers/phpunit.xml.dist b/vendor/composer/installers/phpunit.xml.dist new file mode 100644 index 000000000..cc5cc9915 --- /dev/null +++ b/vendor/composer/installers/phpunit.xml.dist @@ -0,0 +1,25 @@ + + + + + + tests/Composer/Installers + + + + + + src/Composer/Installers + + + \ No newline at end of file diff --git a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php index 176c91a9d..96e987a28 100644 --- a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php @@ -75,7 +75,6 @@ class CakePHPInstaller extends BaseInstaller $installed = new $constraintClass('=', $package->getVersion()); if ($cake3->matches($installed)) { return true; - break; } } } diff --git a/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php index 4d398a445..5c01bafd7 100644 --- a/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php +++ b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php @@ -4,9 +4,10 @@ namespace Composer\Installers; class Concrete5Installer extends BaseInstaller { protected $locations = array( - 'block' => 'blocks/{$name}/', + 'core' => 'concrete/', + 'block' => 'application/blocks/{$name}/', 'package' => 'packages/{$name}/', - 'theme' => 'themes/{$name}/', + 'theme' => 'application/themes/{$name}/', 'update' => 'updates/{$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 000000000..2be4e3cb7 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/' + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/Installer.php b/vendor/composer/installers/src/Composer/Installers/Installer.php index 5b6c553a8..10f28bbf5 100644 --- a/vendor/composer/installers/src/Composer/Installers/Installer.php +++ b/vendor/composer/installers/src/Composer/Installers/Installer.php @@ -34,6 +34,7 @@ class Installer extends LibraryInstaller 'decibel' => 'DecibelInstaller', 'drupal' => 'DrupalInstaller', 'elgg' => 'ElggInstaller', + 'eliasis' => 'EliasisInstaller', 'ee3' => 'ExpressionEngineInstaller', 'ee2' => 'ExpressionEngineInstaller', 'fuel' => 'FuelInstaller', @@ -41,14 +42,18 @@ class Installer extends LibraryInstaller 'grav' => 'GravInstaller', 'hurad' => 'HuradInstaller', 'imagecms' => 'ImageCMSInstaller', + 'itop' => 'ItopInstaller', 'joomla' => 'JoomlaInstaller', + 'kanboard' => 'KanboardInstaller', 'kirby' => 'KirbyInstaller', 'kodicms' => 'KodiCMSInstaller', 'kohana' => 'KohanaInstaller', 'laravel' => 'LaravelInstaller', + 'lavalite' => 'LavaLiteInstaller', 'lithium' => 'LithiumInstaller', 'magento' => 'MagentoInstaller', 'mako' => 'MakoInstaller', + 'maya' => 'MayaInstaller', 'mautic' => 'MauticInstaller', 'mediawiki' => 'MediaWikiInstaller', 'microweber' => 'MicroweberInstaller', @@ -56,6 +61,7 @@ class Installer extends LibraryInstaller 'modxevo' => 'MODXEvoInstaller', 'moodle' => 'MoodleInstaller', 'october' => 'OctoberInstaller', + 'ontowiki' => 'OntoWikiInstaller', 'oxid' => 'OxidInstaller', 'phpbb' => 'PhpBBInstaller', 'pimcore' => 'PimcoreInstaller', @@ -65,12 +71,14 @@ class Installer extends LibraryInstaller 'puppet' => 'PuppetInstaller', 'radphp' => 'RadPHPInstaller', 'phifty' => 'PhiftyInstaller', + 'porto' => 'PortoInstaller', 'redaxo' => 'RedaxoInstaller', 'reindex' => 'ReIndexInstaller', 'roundcube' => 'RoundcubeInstaller', 'shopware' => 'ShopwareInstaller', 'silverstripe' => 'SilverStripeInstaller', 'smf' => 'SMFInstaller', + 'sydes' => 'SyDESInstaller', 'symfony1' => 'Symfony1Installer', 'thelia' => 'TheliaInstaller', 'tusk' => 'TuskInstaller', 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 000000000..c6c1b3374 --- /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/KanboardInstaller.php b/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php new file mode 100644 index 000000000..9cb7b8cdb --- /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/LavaLiteInstaller.php b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php new file mode 100644 index 000000000..8130b8871 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php @@ -0,0 +1,10 @@ + 'packages/{$name}/', + 'theme' => 'public/themes/{$name}/', + ); +} 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 000000000..30a91676d --- /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/MoodleInstaller.php b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php index 3cdda6ca5..a89c82f73 100644 --- a/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php @@ -45,6 +45,7 @@ class MoodleInstaller extends BaseInstaller '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}/', 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 000000000..5dd3438d9 --- /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/PortoInstaller.php b/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php new file mode 100644 index 000000000..dbf85e635 --- /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/SyDESInstaller.php b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php new file mode 100644 index 000000000..83ef9d091 --- /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/VgmcpInstaller.php b/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php new file mode 100644 index 000000000..7d90c5e6e --- /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/tests/Composer/Installers/Test/AsgardInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php new file mode 100644 index 000000000..f6e834104 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php @@ -0,0 +1,79 @@ +installer = new AsgardInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + array('name' => $expected, 'type' => $type), + $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)) + ); + } + + public function packageNameInflectionProvider() + { + return array( + // Should keep module name StudlyCase + array( + 'asgard-module', + 'user-profile', + 'UserProfile' + ), + array( + 'asgard-module', + 'asgard-module', + 'Asgard' + ), + array( + 'asgard-module', + 'blog', + 'Blog' + ), + // tests that exactly one '-module' is cut off + array( + 'asgard-module', + 'some-module-module', + 'SomeModule', + ), + // tests that exactly one '-theme' is cut off + array( + 'asgard-theme', + 'some-theme-theme', + 'SomeTheme', + ), + // tests that names without '-theme' suffix stay valid + array( + 'asgard-theme', + 'someothertheme', + 'Someothertheme', + ), + // Should keep theme name StudlyCase + array( + 'asgard-theme', + 'adminlte-advanced', + 'AdminlteAdvanced' + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/BitrixInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/BitrixInstallerTest.php new file mode 100644 index 000000000..e909bb426 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/BitrixInstallerTest.php @@ -0,0 +1,76 @@ +composer = new Composer(); + } + + /** + * @param string $vars + * @param string $expectedVars + * + * @covers ::inflectPackageVars + * + * @dataProvider provideExpectedInflectionResults + */ + final public function testInflectPackageVars($vars, $expectedVars) + { + + $this->installer = new BitrixInstaller( + new Package($vars['name'], '4.2', '4.2'), + $this->composer + ); + $actual = $this->installer->inflectPackageVars($vars); + $this->assertEquals($actual, $expectedVars); + } + + /** + * Provides various parameters for packages and the expected result after inflection + * + * @return array + */ + final public function provideExpectedInflectionResults() + { + return array( + //check bitrix-dir is correct + array( + array('name' => 'Nyan/Cat'), + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'bitrix') + ), + array( + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'bitrix'), + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'bitrix') + ), + array( + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'local'), + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'local') + ), + ); + } +} \ No newline at end of file diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php new file mode 100644 index 000000000..523e84762 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php @@ -0,0 +1,115 @@ +package = new Package('CamelCased', '1.0', '1.0'); + $this->io = $this->getMock('Composer\IO\PackageInterface'); + $this->composer = new Composer(); + $this->composer->setConfig(new Config(false)); + } + + /** + * testInflectPackageVars + * + * @return void + */ + public function testInflectPackageVars() + { + $installer = new CakePHPInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'CamelCased')); + $this->assertEquals($result, array('name' => 'CamelCased')); + + $installer = new CakePHPInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'with-dash')); + $this->assertEquals($result, array('name' => 'WithDash')); + + $installer = new CakePHPInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'with_underscore')); + $this->assertEquals($result, array('name' => 'WithUnderscore')); + + $installer = new CakePHPInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'cake/acl')); + $this->assertEquals($result, array('name' => 'Cake/Acl')); + + $installer = new CakePHPInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'cake/debug-kit')); + $this->assertEquals($result, array('name' => 'Cake/DebugKit')); + } + + /** + * Test getLocations returning appropriate values based on CakePHP version + * + */ + public function testGetLocations() { + $package = new RootPackage('CamelCased', '1.0', '1.0'); + $composer = $this->composer; + $rm = new RepositoryManager( + $this->getMock('Composer\IO\IOInterface'), + $this->getMock('Composer\Config') + ); + $composer->setRepositoryManager($rm); + $installer = new CakePHPInstaller($package, $composer); + + // 2.0 < cakephp < 3.0 + $this->setCakephpVersion($rm, '2.0.0'); + $result = $installer->getLocations(); + $this->assertContains('Plugin/', $result['plugin']); + + $this->setCakephpVersion($rm, '2.5.9'); + $result = $installer->getLocations(); + $this->assertContains('Plugin/', $result['plugin']); + + $this->setCakephpVersion($rm, '~2.5'); + $result = $installer->getLocations(); + $this->assertContains('Plugin/', $result['plugin']); + + // special handling for 2.x versions when 3.x is still in development + $this->setCakephpVersion($rm, 'dev-master'); + $result = $installer->getLocations(); + $this->assertContains('Plugin/', $result['plugin']); + + $this->setCakephpVersion($rm, '>=2.5'); + $result = $installer->getLocations(); + $this->assertContains('Plugin/', $result['plugin']); + + // cakephp >= 3.0 + $this->setCakephpVersion($rm, '3.0.*-dev'); + $result = $installer->getLocations(); + $this->assertContains('vendor/{$vendor}/{$name}/', $result['plugin']); + + $this->setCakephpVersion($rm, '~8.8'); + $result = $installer->getLocations(); + $this->assertContains('vendor/{$vendor}/{$name}/', $result['plugin']); + } + + protected function setCakephpVersion($rm, $version) { + $parser = new VersionParser(); + list(, $version) = explode(' ', $parser->parseConstraints($version)); + $installed = new InstalledArrayRepository(); + $package = new Package('cakephp/cakephp', $version, $version); + $installed->addPackage($package); + $rm->setLocalRepository($installed); + } + +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php new file mode 100644 index 000000000..31ccecdbc --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php @@ -0,0 +1,83 @@ +installer = new CraftInstaller(); + } + + /** + * @param string $packageName + * @param string $expectedName + * + * @covers ::inflectPackageVars + * + * @dataProvider provideExpectedInflectionResults + */ + final public function testInflectPackageVars($packageName, $expectedName) + { + $installer = $this->installer; + + $vars = array('name' => $packageName); + $expected = array('name' => $expectedName); + + $actual = $installer->inflectPackageVars($vars); + + $this->assertEquals($actual, $expected); + } + + /** + * Provides various names for packages and the expected result after inflection + * + * @return array + */ + final public function provideExpectedInflectionResults() + { + return array( + // lowercase + array('foo', 'foo'), + array('craftfoo', 'craftfoo'), + array('fooplugin', 'fooplugin'), + array('craftfooplugin', 'craftfooplugin'), + // lowercase - dash + array('craft-foo', 'foo'), + array('foo-plugin', 'foo'), + array('craft-foo-plugin', 'foo'), + // lowercase - underscore + array('craft_foo', 'craft_foo'), + array('foo_plugin', 'foo_plugin'), + array('craft_foo_plugin', 'craft_foo_plugin'), + // CamelCase + array('Foo', 'Foo'), + array('CraftFoo', 'CraftFoo'), + array('FooPlugin', 'FooPlugin'), + array('CraftFooPlugin', 'CraftFooPlugin'), + // CamelCase - Dash + array('Craft-Foo', 'Foo'), + array('Foo-Plugin', 'Foo'), + array('Craft-Foo-Plugin', 'Foo'), + // CamelCase - underscore + array('Craft_Foo', 'Craft_Foo'), + array('Foo_Plugin', 'Foo_Plugin'), + array('Craft_Foo_Plugin', 'Craft_Foo_Plugin'), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/DokuWikiInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/DokuWikiInstallerTest.php new file mode 100644 index 000000000..9e385e6a8 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/DokuWikiInstallerTest.php @@ -0,0 +1,89 @@ +installer = new DokuWikiInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)), + array('name' => $expected, 'type'=>$type) + ); + } + + public function packageNameInflectionProvider() + { + return array( + array( + 'dokuwiki-plugin', + 'dokuwiki-test-plugin', + 'test', + ), + array( + 'dokuwiki-plugin', + 'test-plugin', + 'test', + ), + array( + 'dokuwiki-plugin', + 'dokuwiki_test', + 'test', + ), + array( + 'dokuwiki-plugin', + 'test', + 'test', + ), + array( + 'dokuwiki-plugin', + 'test-template', + 'test-template', + ), + array( + 'dokuwiki-template', + 'dokuwiki-test-template', + 'test', + ), + array( + 'dokuwiki-template', + 'test-template', + 'test', + ), + array( + 'dokuwiki-template', + 'dokuwiki_test', + 'test', + ), + array( + 'dokuwiki-template', + 'test', + 'test', + ), + array( + 'dokuwiki-template', + 'test-plugin', + 'test-plugin', + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/GravInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/GravInstallerTest.php new file mode 100644 index 000000000..b757799b4 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/GravInstallerTest.php @@ -0,0 +1,63 @@ +composer = new Composer(); + } + + public function testInflectPackageVars() + { + $package = $this->getPackage('vendor/name', '0.0.0'); + $installer = new GravInstaller($package, $this->composer); + $packageVars = $this->getPackageVars($package); + + $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => 'test'))); + $this->assertEquals('test', $result['name']); + + foreach ($installer->getLocations() as $name => $location) { + $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "$name-test"))); + $this->assertEquals('test', $result['name']); + $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "test-$name"))); + $this->assertEquals('test', $result['name']); + $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "$name-test-test"))); + $this->assertEquals('test-test', $result['name']); + $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "test-test-$name"))); + $this->assertEquals('test-test', $result['name']); + $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-$name-test"))); + $this->assertEquals('test', $result['name']); + $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-test-$name"))); + $this->assertEquals('test', $result['name']); + $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-$name-test-test"))); + $this->assertEquals('test-test', $result['name']); + $result = $installer->inflectPackageVars(array_merge($packageVars, array('name' => "grav-test-test-$name"))); + $this->assertEquals('test-test', $result['name']); + } + } + + /** + * @param $package \Composer\Package\PackageInterface + */ + public function getPackageVars($package) + { + $type = $package->getType(); + + $prettyName = $package->getPrettyName(); + if (strpos($prettyName, '/') !== false) { + list($vendor, $name) = explode('/', $prettyName); + } else { + $vendor = ''; + $name = $prettyName; + } + + return compact('name', 'vendor', 'type'); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php new file mode 100644 index 000000000..91a303a1d --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php @@ -0,0 +1,512 @@ +fs = new Filesystem; + + $this->composer = new Composer(); + $this->config = new Config(); + $this->composer->setConfig($this->config); + + $this->vendorDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'baton-test-vendor'; + $this->ensureDirectoryExistsAndClear($this->vendorDir); + + $this->binDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'baton-test-bin'; + $this->ensureDirectoryExistsAndClear($this->binDir); + + $this->config->merge(array( + 'config' => array( + 'vendor-dir' => $this->vendorDir, + 'bin-dir' => $this->binDir, + ), + )); + + $this->dm = $this->getMockBuilder('Composer\Downloader\DownloadManager') + ->disableOriginalConstructor() + ->getMock(); + $this->composer->setDownloadManager($this->dm); + + $this->repository = $this->getMock('Composer\Repository\InstalledRepositoryInterface'); + $this->io = $this->getMock('Composer\IO\IOInterface'); + } + + /** + * tearDown + * + * @return void + */ + public function tearDown() + { + $this->fs->removeDirectory($this->vendorDir); + $this->fs->removeDirectory($this->binDir); + } + + /** + * testSupports + * + * @return void + * + * @dataProvider dataForTestSupport + */ + public function testSupports($type, $expected) + { + $installer = new Installer($this->io, $this->composer); + $this->assertSame($expected, $installer->supports($type), sprintf('Failed to show support for %s', $type)); + } + + /** + * dataForTestSupport + */ + public function dataForTestSupport() + { + return array( + array('agl-module', true), + array('aimeos-extension', true), + array('annotatecms-module', true), + array('annotatecms-component', true), + array('annotatecms-service', true), + array('attogram-module', true), + array('bitrix-module', true), + array('bitrix-component', true), + array('bitrix-theme', true), + array('bonefish-package', true), + array('cakephp', false), + array('cakephp-', false), + array('cakephp-app', false), + array('cakephp-plugin', true), + array('chef-cookbook', true), + array('chef-role', true), + array('cockpit-module', true), + array('codeigniter-app', false), + array('codeigniter-library', true), + array('codeigniter-third-party', true), + array('codeigniter-module', true), + array('concrete5-block', true), + array('concrete5-package', true), + array('concrete5-theme', true), + array('concrete5-core', true), + array('concrete5-update', true), + array('craft-plugin', true), + array('croogo-plugin', true), + array('croogo-theme', true), + array('decibel-app', true), + array('dokuwiki-plugin', true), + array('dokuwiki-template', true), + array('drupal-module', true), + array('dolibarr-module', true), + array('ee3-theme', true), + array('ee3-addon', true), + array('ee2-theme', true), + array('ee2-addon', true), + array('elgg-plugin', true), + array('eliasis-module', true), + array('fuel-module', true), + array('fuel-package', true), + array('fuel-theme', true), + array('fuelphp-component', true), + array('hurad-plugin', true), + array('hurad-theme', true), + array('imagecms-template', true), + array('imagecms-module', true), + array('imagecms-library', true), + array('itop-extension', true), + array('joomla-library', true), + array('kanboard-plugin', true), + array('kirby-plugin', true), + array('kohana-module', true), + array('laravel-library', true), + array('lavalite-theme', true), + array('lavalite-package', true), + array('lithium-library', true), + array('magento-library', true), + array('mako-package', true), + array('modxevo-snippet', true), + array('modxevo-plugin', true), + array('modxevo-module', true), + array('modxevo-template', true), + array('modxevo-lib', true), + array('mediawiki-extension', true), + array('mediawiki-skin', true), + array('microweber-module', true), + array('modulework-module', true), + array('moodle-mod', true), + array('october-module', true), + array('october-plugin', true), + array('piwik-plugin', true), + array('phpbb-extension', true), + array('pimcore-plugin', true), + array('plentymarkets-plugin', true), + array('ppi-module', true), + array('prestashop-module', true), + array('prestashop-theme', true), + array('puppet-module', true), + array('porto-container', true), + array('radphp-bundle', true), + array('redaxo-addon', true), + array('redaxo-bestyle-plugin', true), + array('reindex-theme', true), + array('reindex-plugin', true), + array('roundcube-plugin', true), + array('shopware-backend-plugin', true), + array('shopware-core-plugin', true), + array('shopware-frontend-plugin', true), + array('shopware-theme', true), + array('shopware-plugin', true), + array('shopware-frontend-theme', true), + array('silverstripe-module', true), + array('silverstripe-theme', true), + array('smf-module', true), + array('smf-theme', true), + array('sydes-module', true), + array('sydes-theme', true), + array('symfony1-plugin', true), + array('thelia-module', true), + array('thelia-frontoffice-template', true), + array('thelia-backoffice-template', true), + array('thelia-email-template', true), + array('tusk-task', true), + array('tusk-asset', true), + array('typo3-flow-plugin', true), + array('typo3-cms-extension', true), + array('vanilla-plugin', true), + array('vanilla-theme', true), + array('whmcs-gateway', true), + array('wolfcms-plugin', true), + array('wordpress-plugin', true), + array('wordpress-core', false), + array('yawik-module', true), + array('zend-library', true), + array('zikula-module', true), + array('zikula-theme', true), + array('kodicms-plugin', true), + array('kodicms-media', true), + array('phifty-bundle', true), + array('phifty-library', true), + array('phifty-framework', true), + ); + } + + /** + * testInstallPath + * + * @dataProvider dataForTestInstallPath + */ + public function testInstallPath($type, $path, $name, $version = '1.0.0') + { + $installer = new Installer($this->io, $this->composer); + $package = new Package($name, $version, $version); + + $package->setType($type); + $result = $installer->getInstallPath($package); + $this->assertEquals($path, $result); + } + + /** + * dataFormTestInstallPath + */ + public function dataForTestInstallPath() + { + return array( + array('agl-module', 'More/MyTestPackage/', 'agl/my_test-package'), + array('aimeos-extension', 'ext/ai-test/', 'author/ai-test'), + array('annotatecms-module', 'addons/modules/my_module/', 'vysinsky/my_module'), + array('annotatecms-component', 'addons/components/my_component/', 'vysinsky/my_component'), + array('annotatecms-service', 'addons/services/my_service/', 'vysinsky/my_service'), + array('attogram-module', 'modules/my_module/', 'author/my_module'), + array('bitrix-module', 'bitrix/modules/my_module/', 'author/my_module'), + array('bitrix-component', 'bitrix/components/my_component/', 'author/my_component'), + array('bitrix-theme', 'bitrix/templates/my_theme/', 'author/my_theme'), + array('bitrix-d7-module', 'bitrix/modules/author.my_module/', 'author/my_module'), + array('bitrix-d7-component', 'bitrix/components/author/my_component/', 'author/my_component'), + array('bitrix-d7-template', 'bitrix/templates/author_my_template/', 'author/my_template'), + array('bonefish-package', 'Packages/bonefish/package/', 'bonefish/package'), + array('cakephp-plugin', 'Plugin/Ftp/', 'shama/ftp'), + array('chef-cookbook', 'Chef/mre/my_cookbook/', 'mre/my_cookbook'), + array('chef-role', 'Chef/roles/my_role/', 'mre/my_role'), + array('cockpit-module', 'cockpit/modules/addons/My_module/', 'piotr-cz/cockpit-my_module'), + array('codeigniter-library', 'application/libraries/my_package/', 'shama/my_package'), + array('codeigniter-module', 'application/modules/my_package/', 'shama/my_package'), + array('concrete5-block', 'application/blocks/concrete5_block/', 'remo/concrete5_block'), + array('concrete5-package', 'packages/concrete5_package/', 'remo/concrete5_package'), + array('concrete5-theme', 'application/themes/concrete5_theme/', 'remo/concrete5_theme'), + array('concrete5-core', 'concrete/', 'concrete5/core'), + array('concrete5-update', 'updates/concrete5/', 'concrete5/concrete5'), + array('craft-plugin', 'craft/plugins/my_plugin/', 'mdcpepper/my_plugin'), + array('croogo-plugin', 'Plugin/Sitemaps/', 'fahad19/sitemaps'), + array('croogo-theme', 'View/Themed/Readable/', 'rchavik/readable'), + array('decibel-app', 'app/someapp/', 'author/someapp'), + array('dokuwiki-plugin', 'lib/plugins/someplugin/', 'author/someplugin'), + array('dokuwiki-template', 'lib/tpl/sometemplate/', 'author/sometemplate'), + array('dolibarr-module', 'htdocs/custom/my_module/', 'shama/my_module'), + array('drupal-module', 'modules/my_module/', 'shama/my_module'), + array('drupal-theme', 'themes/my_module/', 'shama/my_module'), + array('drupal-profile', 'profiles/my_module/', 'shama/my_module'), + array('drupal-drush', 'drush/my_module/', 'shama/my_module'), + array('elgg-plugin', 'mod/sample_plugin/', 'test/sample_plugin'), + array('eliasis-module', 'modules/my_module/', 'shama/my_module'), + array('ee3-addon', 'system/user/addons/ee_theme/', 'author/ee_theme'), + array('ee3-theme', 'themes/user/ee_package/', 'author/ee_package'), + array('ee2-addon', 'system/expressionengine/third_party/ee_theme/', 'author/ee_theme'), + array('ee2-theme', 'themes/third_party/ee_package/', 'author/ee_package'), + array('fuel-module', 'fuel/app/modules/module/', 'fuel/module'), + array('fuel-package', 'fuel/packages/orm/', 'fuel/orm'), + array('fuel-theme', 'fuel/app/themes/theme/', 'fuel/theme'), + array('fuelphp-component', 'components/demo/', 'fuelphp/demo'), + array('hurad-plugin', 'plugins/Akismet/', 'atkrad/akismet'), + array('hurad-theme', 'plugins/Hurad2013/', 'atkrad/Hurad2013'), + array('imagecms-template', 'templates/my_template/', 'shama/my_template'), + array('imagecms-module', 'application/modules/my_module/', 'shama/my_module'), + array('imagecms-library', 'application/libraries/my_library/', 'shama/my_library'), + array('itop-extension', 'extensions/my_extension/', 'shama/my_extension'), + array('joomla-plugin', 'plugins/my_plugin/', 'shama/my_plugin'), + array('kanboard-plugin', 'plugins/my_plugin/', 'shama/my_plugin'), + array('kirby-plugin', 'site/plugins/my_plugin/', 'shama/my_plugin'), + array('kohana-module', 'modules/my_package/', 'shama/my_package'), + array('laravel-library', 'libraries/my_package/', 'shama/my_package'), + array('lavalite-theme', 'public/themes/my_theme/', 'shama/my_theme'), + array('lavalite-package', 'packages/my_package/', 'shama/my_package'), + array('lithium-library', 'libraries/li3_test/', 'user/li3_test'), + array('magento-library', 'lib/foo/', 'test/foo'), + array('modxevo-snippet', 'assets/snippets/my_snippet/', 'shama/my_snippet'), + array('modxevo-plugin', 'assets/plugins/my_plugin/', 'shama/my_plugin'), + array('modxevo-module', 'assets/modules/my_module/', 'shama/my_module'), + array('modxevo-template', 'assets/templates/my_template/', 'shama/my_template'), + array('modxevo-lib', 'assets/lib/my_lib/', 'shama/my_lib'), + array('mako-package', 'app/packages/my_package/', 'shama/my_package'), + array('mediawiki-extension', 'extensions/APC/', 'author/APC'), + array('mediawiki-extension', 'extensions/APC/', 'author/APC-extension'), + array('mediawiki-extension', 'extensions/UploadWizard/', 'author/upload-wizard'), + array('mediawiki-extension', 'extensions/SyntaxHighlight_GeSHi/', 'author/syntax-highlight_GeSHi'), + array('mediawiki-skin', 'skins/someskin/', 'author/someskin-skin'), + array('mediawiki-skin', 'skins/someskin/', 'author/someskin'), + array('microweber-module', 'userfiles/modules/my-thing/', 'author/my-thing-module'), + array('modulework-module', 'modules/my_package/', 'shama/my_package'), + array('moodle-mod', 'mod/my_package/', 'shama/my_package'), + array('october-module', 'modules/my_plugin/', 'shama/my_plugin'), + array('october-plugin', 'plugins/shama/my_plugin/', 'shama/my_plugin'), + array('october-theme', 'themes/my_theme/', 'shama/my_theme'), + array('piwik-plugin', 'plugins/VisitSummary/', 'shama/visit-summary'), + array('prestashop-module', 'modules/a-module/', 'vendor/a-module'), + array('prestashop-theme', 'themes/a-theme/', 'vendor/a-theme'), + array('phpbb-extension', 'ext/test/foo/', 'test/foo'), + array('phpbb-style', 'styles/foo/', 'test/foo'), + array('phpbb-language', 'language/foo/', 'test/foo'), + array('pimcore-plugin', 'plugins/MyPlugin/', 'ubikz/my_plugin'), + array('plentymarkets-plugin', 'HelloWorld/', 'plugin-hello-world'), + array('ppi-module', 'modules/foo/', 'test/foo'), + array('puppet-module', 'modules/puppet-name/', 'puppet/puppet-name'), + array('porto-container', 'app/Containers/container-name/', 'test/container-name'), + array('radphp-bundle', 'src/Migration/', 'atkrad/migration'), + array('redaxo-addon', 'redaxo/include/addons/my_plugin/', 'shama/my_plugin'), + array('redaxo-bestyle-plugin', 'redaxo/include/addons/be_style/plugins/my_plugin/', 'shama/my_plugin'), + array('reindex-theme', 'themes/my_module/', 'author/my_module'), + array('reindex-plugin', 'plugins/my_module/', 'author/my_module'), + array('roundcube-plugin', 'plugins/base/', 'test/base'), + array('roundcube-plugin', 'plugins/replace_dash/', 'test/replace-dash'), + array('shopware-backend-plugin', 'engine/Shopware/Plugins/Local/Backend/ShamaMyBackendPlugin/', 'shama/my-backend-plugin'), + array('shopware-core-plugin', 'engine/Shopware/Plugins/Local/Core/ShamaMyCorePlugin/', 'shama/my-core-plugin'), + array('shopware-frontend-plugin', 'engine/Shopware/Plugins/Local/Frontend/ShamaMyFrontendPlugin/', 'shama/my-frontend-plugin'), + array('shopware-theme', 'templates/my_theme/', 'shama/my-theme'), + array('shopware-frontend-theme', 'themes/Frontend/ShamaMyFrontendTheme/', 'shama/my-frontend-theme'), + array('shopware-plugin', 'custom/plugins/ShamaMyPlugin/', 'shama/my-plugin'), + array('silverstripe-module', 'my_module/', 'shama/my_module'), + array('silverstripe-module', 'sapphire/', 'silverstripe/framework', '2.4.0'), + array('silverstripe-module', 'framework/', 'silverstripe/framework', '3.0.0'), + array('silverstripe-module', 'framework/', 'silverstripe/framework', '3.0.0-rc1'), + array('silverstripe-module', 'framework/', 'silverstripe/framework', 'my/branch'), + array('silverstripe-theme', 'themes/my_theme/', 'shama/my_theme'), + array('smf-module', 'Sources/my_module/', 'shama/my_module'), + array('smf-theme', 'Themes/my_theme/', 'shama/my_theme'), + array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sfShamaPlugin'), + array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sf-shama-plugin'), + array('thelia-module', 'local/modules/my_module/', 'shama/my_module'), + array('thelia-frontoffice-template', 'templates/frontOffice/my_template_fo/', 'shama/my_template_fo'), + array('thelia-backoffice-template', 'templates/backOffice/my_template_bo/', 'shama/my_template_bo'), + array('thelia-email-template', 'templates/email/my_template_email/', 'shama/my_template_email'), + array('tusk-task', '.tusk/tasks/my_task/', 'shama/my_task'), + array('typo3-flow-package', 'Packages/Application/my_package/', 'shama/my_package'), + array('typo3-flow-build', 'Build/my_package/', 'shama/my_package'), + array('typo3-cms-extension', 'typo3conf/ext/my_extension/', 'shama/my_extension'), + array('vanilla-plugin', 'plugins/my_plugin/', 'shama/my_plugin'), + array('vanilla-theme', 'themes/my_theme/', 'shama/my_theme'), + array('whmcs-gateway', 'modules/gateways/gateway_name/', 'vendor/gateway_name'), + array('wolfcms-plugin', 'wolf/plugins/my_plugin/', 'shama/my_plugin'), + array('wordpress-plugin', 'wp-content/plugins/my_plugin/', 'shama/my_plugin'), + array('wordpress-muplugin', 'wp-content/mu-plugins/my_plugin/', 'shama/my_plugin'), + array('zend-extra', 'extras/library/zend_test/', 'shama/zend_test'), + array('zikula-module', 'modules/my-test_module/', 'my/test_module'), + array('zikula-theme', 'themes/my-test_theme/', 'my/test_theme'), + array('kodicms-media', 'cms/media/vendor/my_media/', 'shama/my_media'), + array('kodicms-plugin', 'cms/plugins/my_plugin/', 'shama/my_plugin'), + array('phifty-bundle', 'bundles/core/', 'shama/core'), + array('phifty-library', 'libraries/my-lib/', 'shama/my-lib'), + array('phifty-framework', 'frameworks/my-framework/', 'shama/my-framework'), + array('yawik-module', 'module/MyModule/', 'shama/my_module'), + ); + } + + /** + * testGetCakePHPInstallPathException + * + * @return void + * + * @expectedException \InvalidArgumentException + */ + public function testGetCakePHPInstallPathException() + { + $installer = new Installer($this->io, $this->composer); + $package = new Package('shama/ftp', '1.0.0', '1.0.0'); + + $package->setType('cakephp-whoops'); + $result = $installer->getInstallPath($package); + } + + /** + * testCustomInstallPath + */ + public function testCustomInstallPath() + { + $installer = new Installer($this->io, $this->composer); + $package = new Package('shama/ftp', '1.0.0', '1.0.0'); + $package->setType('cakephp-plugin'); + $consumerPackage = new RootPackage('foo/bar', '1.0.0', '1.0.0'); + $this->composer->setPackage($consumerPackage); + $consumerPackage->setExtra(array( + 'installer-paths' => array( + 'my/custom/path/{$name}/' => array( + 'shama/ftp', + 'foo/bar', + ), + ), + )); + $result = $installer->getInstallPath($package); + $this->assertEquals('my/custom/path/Ftp/', $result); + } + + /** + * testCustomInstallerName + */ + public function testCustomInstallerName() + { + $installer = new Installer($this->io, $this->composer); + $package = new Package('shama/cakephp-ftp-plugin', '1.0.0', '1.0.0'); + $package->setType('cakephp-plugin'); + $package->setExtra(array( + 'installer-name' => 'FTP', + )); + $result = $installer->getInstallPath($package); + $this->assertEquals('Plugin/FTP/', $result); + } + + /** + * testCustomTypePath + */ + public function testCustomTypePath() + { + $installer = new Installer($this->io, $this->composer); + $package = new Package('slbmeh/my_plugin', '1.0.0', '1.0.0'); + $package->setType('wordpress-plugin'); + $consumerPackage = new RootPackage('foo/bar', '1.0.0', '1.0.0'); + $this->composer->setPackage($consumerPackage); + $consumerPackage->setExtra(array( + 'installer-paths' => array( + 'my/custom/path/{$name}/' => array( + 'type:wordpress-plugin' + ), + ), + )); + $result = $installer->getInstallPath($package); + $this->assertEquals('my/custom/path/my_plugin/', $result); + } + + /** + * testVendorPath + */ + public function testVendorPath() + { + $installer = new Installer($this->io, $this->composer); + $package = new Package('penyaskito/my_module', '1.0.0', '1.0.0'); + $package->setType('drupal-module'); + $consumerPackage = new RootPackage('drupal/drupal', '1.0.0', '1.0.0'); + $this->composer->setPackage($consumerPackage); + $consumerPackage->setExtra(array( + 'installer-paths' => array( + 'modules/custom/{$name}/' => array( + 'vendor:penyaskito' + ), + ), + )); + $result = $installer->getInstallPath($package); + $this->assertEquals('modules/custom/my_module/', $result); + } + + /** + * testNoVendorName + */ + public function testNoVendorName() + { + $installer = new Installer($this->io, $this->composer); + $package = new Package('sfPhpunitPlugin', '1.0.0', '1.0.0'); + + $package->setType('symfony1-plugin'); + $result = $installer->getInstallPath($package); + $this->assertEquals('plugins/sfPhpunitPlugin/', $result); + } + + /** + * testTypo3Inflection + */ + public function testTypo3Inflection() + { + $installer = new Installer($this->io, $this->composer); + $package = new Package('typo3/fluid', '1.0.0', '1.0.0'); + + $package->setAutoload(array( + 'psr-0' => array( + 'TYPO3\\Fluid' => 'Classes', + ), + )); + + $package->setType('typo3-flow-package'); + $result = $installer->getInstallPath($package); + $this->assertEquals('Packages/Application/TYPO3.Fluid/', $result); + } + + public function testUninstallAndDeletePackageFromLocalRepo() + { + $package = new Package('foo', '1.0.0', '1.0.0'); + + $installer = $this->getMock('Composer\Installers\Installer', array('getInstallPath'), array($this->io, $this->composer)); + $installer->expects($this->once())->method('getInstallPath')->with($package)->will($this->returnValue(sys_get_temp_dir().'/foo')); + + $repo = $this->getMock('Composer\Repository\InstalledRepositoryInterface'); + $repo->expects($this->once())->method('hasPackage')->with($package)->will($this->returnValue(true)); + $repo->expects($this->once())->method('removePackage')->with($package); + + $installer->uninstall($repo, $package); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/MayaInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/MayaInstallerTest.php new file mode 100644 index 000000000..f800c6116 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/MayaInstallerTest.php @@ -0,0 +1,61 @@ +installer = new MayaInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + array('name' => $expected, 'type' => $type), + $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)) + ); + } + + public function packageNameInflectionProvider() + { + return array( + // Should keep module name StudlyCase + array( + 'maya-module', + 'user-profile', + 'UserProfile' + ), + array( + 'maya-module', + 'maya-module', + 'Maya' + ), + array( + 'maya-module', + 'blog', + 'Blog' + ), + // tests that exactly one '-module' is cut off + array( + 'maya-module', + 'some-module-module', + 'SomeModule', + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/MediaWikiInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/MediaWikiInstallerTest.php new file mode 100644 index 000000000..3675e188b --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/MediaWikiInstallerTest.php @@ -0,0 +1,66 @@ +installer = new MediaWikiInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)), + array('name' => $expected, 'type'=>$type) + ); + } + + public function packageNameInflectionProvider() + { + return array( + array( + 'mediawiki-extension', + 'sub-page-list', + 'SubPageList', + ), + array( + 'mediawiki-extension', + 'sub-page-list-extension', + 'SubPageList', + ), + array( + 'mediawiki-extension', + 'semantic-mediawiki', + 'SemanticMediawiki', + ), + // tests that exactly one '-skin' is cut off, and that skins do not get ucwords treatment like extensions + array( + 'mediawiki-skin', + 'some-skin-skin', + 'some-skin', + ), + // tests that names without '-skin' suffix stay valid + array( + 'mediawiki-skin', + 'someotherskin', + 'someotherskin', + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/OctoberInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/OctoberInstallerTest.php new file mode 100644 index 000000000..fd427cdc3 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/OctoberInstallerTest.php @@ -0,0 +1,66 @@ +installer = new OctoberInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)), + array('name' => $expected, 'type' => $type) + ); + } + + public function packageNameInflectionProvider() + { + return array( + array( + 'october-plugin', + 'subpagelist', + 'subpagelist', + ), + array( + 'october-plugin', + 'subpagelist-plugin', + 'subpagelist', + ), + array( + 'october-plugin', + 'semanticoctober', + 'semanticoctober', + ), + // tests that exactly one '-theme' is cut off + array( + 'october-theme', + 'some-theme-theme', + 'some-theme', + ), + // tests that names without '-theme' suffix stay valid + array( + 'october-theme', + 'someothertheme', + 'someothertheme', + ), + ); + } +} \ No newline at end of file diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/OntoWikiInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/OntoWikiInstallerTest.php new file mode 100644 index 000000000..24c498c87 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/OntoWikiInstallerTest.php @@ -0,0 +1,85 @@ +installer = new OntoWikiInstaller(); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)), + array('name' => $expected, 'type'=>$type) + ); + } + + public function packageNameInflectionProvider() + { + return array( + array( + 'ontowiki-extension', + 'CSVImport.ontowiki', + 'csvimport', + ), + array( + 'ontowiki-extension', + 'csvimport', + 'csvimport', + ), + array( + 'ontowiki-extension', + 'some_ontowiki_extension', + 'some_ontowiki_extension', + ), + array( + 'ontowiki-extension', + 'some_ontowiki_extension.ontowiki', + 'some_ontowiki_extension', + ), + array( + 'ontowiki-translation', + 'de-translation.ontowiki', + 'de', + ), + array( + 'ontowiki-translation', + 'en-US-translation.ontowiki', + 'en-us', + ), + array( + 'ontowiki-translation', + 'en-US-translation', + 'en-us', + ), + array( + 'ontowiki-theme', + 'blue-theme.ontowiki', + 'blue', + ), + array( + 'ontowiki-theme', + 'blue-theme', + 'blue', + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/PimcoreInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/PimcoreInstallerTest.php new file mode 100644 index 000000000..ea79374bf --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/PimcoreInstallerTest.php @@ -0,0 +1,44 @@ +package = new Package('CamelCased', '1.0', '1.0'); + $this->io = $this->getMock('Composer\IO\PackageInterface'); + $this->composer = new Composer(); + } + + /** + * testInflectPackageVars + * + * @return void + */ + public function testInflectPackageVars() + { + $installer = new PimcoreInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'CamelCased')); + $this->assertEquals($result, array('name' => 'CamelCased')); + + $installer = new PimcoreInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'with-dash')); + $this->assertEquals($result, array('name' => 'WithDash')); + + $installer = new PimcoreInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'with_underscore')); + $this->assertEquals($result, array('name' => 'WithUnderscore')); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/PiwikInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/PiwikInstallerTest.php new file mode 100644 index 000000000..8d9ff3f82 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/PiwikInstallerTest.php @@ -0,0 +1,63 @@ +package = new Package('VisitSummary', '1.0', '1.0'); + $this->io = $this->getMock('Composer\IO\PackageInterface'); + $this->composer = new Composer(); + } + + /** + * testInflectPackageVars + * + * @return void + */ + public function testInflectPackageVars() + { + $installer = new PiwikInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'VisitSummary')); + $this->assertEquals($result, array('name' => 'VisitSummary')); + + $installer = new PiwikInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'visit-summary')); + $this->assertEquals($result, array('name' => 'VisitSummary')); + + $installer = new PiwikInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => 'visit_summary')); + $this->assertEquals($result, array('name' => 'VisitSummary')); + } + +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/SyDESInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/SyDESInstallerTest.php new file mode 100644 index 000000000..1521fbf33 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/SyDESInstallerTest.php @@ -0,0 +1,81 @@ +installer = new SyDESInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + array('name' => $expected, 'type' => $type), + $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)) + ); + } + + public function packageNameInflectionProvider() + { + return array( + // modules + array( + 'sydes-module', + 'name', + 'Name' + ), + array( + 'sydes-module', + 'sample-name', + 'SampleName' + ), + array( + 'sydes-module', + 'sydes-name', + 'Name' + ), + array( + 'sydes-module', + 'sample-name-module', + 'SampleName', + ), + array( + 'sydes-module', + 'sydes-sample-name-module', + 'SampleName' + ), + // themes + array( + 'sydes-theme', + 'some-theme-theme', + 'some-theme', + ), + array( + 'sydes-theme', + 'sydes-sometheme', + 'sometheme', + ), + array( + 'sydes-theme', + 'Sample-Name', + 'sample-name' + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/TestCase.php b/vendor/composer/installers/tests/Composer/Installers/Test/TestCase.php new file mode 100644 index 000000000..6418a03b8 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/TestCase.php @@ -0,0 +1,64 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Installers\Test; + +use Composer\Package\Version\VersionParser; +use Composer\Package\Package; +use Composer\Package\AliasPackage; +use Composer\Package\LinkConstraint\VersionConstraint; +use Composer\Util\Filesystem; + +abstract class TestCase extends \PHPUnit_Framework_TestCase +{ + private static $parser; + + protected static function getVersionParser() + { + if (!self::$parser) { + self::$parser = new VersionParser(); + } + + return self::$parser; + } + + protected function getVersionConstraint($operator, $version) + { + return new VersionConstraint( + $operator, + self::getVersionParser()->normalize($version) + ); + } + + protected function getPackage($name, $version) + { + $normVersion = self::getVersionParser()->normalize($version); + + return new Package($name, $normVersion, $version); + } + + protected function getAliasPackage($package, $version) + { + $normVersion = self::getVersionParser()->normalize($version); + + return new AliasPackage($package, $normVersion, $version); + } + + protected function ensureDirectoryExistsAndClear($directory) + { + $fs = new Filesystem(); + if (is_dir($directory)) { + $fs->removeDirectory($directory); + } + mkdir($directory, 0777, true); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/VgmcpInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/VgmcpInstallerTest.php new file mode 100644 index 000000000..8b33ab81e --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/VgmcpInstallerTest.php @@ -0,0 +1,79 @@ +installer = new VgmcpInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + array('name' => $expected, 'type' => $type), + $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)) + ); + } + + public function packageNameInflectionProvider() + { + return array( + // Should keep bundle name StudlyCase + array( + 'vgmcp-bundle', + 'user-profile', + 'UserProfile' + ), + array( + 'vgmcp-bundle', + 'vgmcp-bundle', + 'Vgmcp' + ), + array( + 'vgmcp-bundle', + 'blog', + 'Blog' + ), + // tests that exactly one '-bundle' is cut off + array( + 'vgmcp-bundle', + 'some-bundle-bundle', + 'SomeBundle', + ), + // tests that exactly one '-theme' is cut off + array( + 'vgmcp-theme', + 'some-theme-theme', + 'SomeTheme', + ), + // tests that names without '-theme' suffix stay valid + array( + 'vgmcp-theme', + 'someothertheme', + 'Someothertheme', + ), + // Should keep theme name StudlyCase + array( + 'vgmcp-theme', + 'adminlte-advanced', + 'AdminlteAdvanced' + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/YawikInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/YawikInstallerTest.php new file mode 100644 index 000000000..d8d35ff24 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/YawikInstallerTest.php @@ -0,0 +1,64 @@ +package = new Package('YawikCompanyRegistration', '1.0', '1.0'); + $this->io = $this->getMock('Composer\IO\PackageInterface'); + $this->composer = new Composer(); + } + + /** + * testInflectPackageVars + * + * @dataProvider packageNameProvider + * @return void + */ + public function testInflectPackageVars($input) + { + $installer = new YawikInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => $input)); + $this->assertEquals($result, array('name' => 'YawikCompanyRegistration')); + } + + public function packageNameProvider() + { + return array( + array('yawik-company-registration'), + array('yawik_company_registration'), + array('YawikCompanyRegistration') + ); + } +} diff --git a/vendor/composer/installers/tests/bootstrap.php b/vendor/composer/installers/tests/bootstrap.php new file mode 100644 index 000000000..30c8fdc67 --- /dev/null +++ b/vendor/composer/installers/tests/bootstrap.php @@ -0,0 +1,4 @@ +add('Composer\Installers\Test', __DIR__); diff --git a/vendor/consolidation/output-formatters/CHANGELOG.md b/vendor/consolidation/output-formatters/CHANGELOG.md index 4f584e4dd..8c8d3b4db 100644 --- a/vendor/consolidation/output-formatters/CHANGELOG.md +++ b/vendor/consolidation/output-formatters/CHANGELOG.md @@ -1,5 +1,21 @@ # Change Log +### 3.1.10 - 6 June 2017 + +- Typo in CalculateWidths::distributeLongColumns causes failure for some column width distributions + +### 3.1.9 - 8 May 2017 + +- Improve wrapping algorithm + +### 3.1.7 - 20 Jan 2017 + +- Add Windows testing + +### 3.1.6 - 8 Jan 2017 + +- Move victorjonsson/markdowndocs to require-dev + ### 3.1.5 - 23 November 2016 - When converting from XML to an array, use the 'id' or 'name' element as the array key value. diff --git a/vendor/consolidation/output-formatters/composer.json b/vendor/consolidation/output-formatters/composer.json index 5e25eb0b7..6a6354ea9 100644 --- a/vendor/consolidation/output-formatters/composer.json +++ b/vendor/consolidation/output-formatters/composer.json @@ -37,7 +37,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "3.x-dev" } } } diff --git a/vendor/consolidation/output-formatters/docs/api.md b/vendor/consolidation/output-formatters/docs/api.md index e76180125..6e9a8de30 100644 --- a/vendor/consolidation/output-formatters/docs/api.md +++ b/vendor/consolidation/output-formatters/docs/api.md @@ -45,6 +45,8 @@ - [\Consolidation\OutputFormatters\Transformations\SimplifyToArrayInterface (interface)](#interface-consolidationoutputformatterstransformationssimplifytoarrayinterface) - [\Consolidation\OutputFormatters\Transformations\TableTransformation](#class-consolidationoutputformatterstransformationstabletransformation) - [\Consolidation\OutputFormatters\Transformations\WordWrapper](#class-consolidationoutputformatterstransformationswordwrapper) +- [\Consolidation\OutputFormatters\Transformations\Wrap\CalculateWidths](#class-consolidationoutputformatterstransformationswrapcalculatewidths) +- [\Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths](#class-consolidationoutputformatterstransformationswrapcolumnwidths) - [\Consolidation\OutputFormatters\Validate\ValidationInterface (interface)](#interface-consolidationoutputformattersvalidatevalidationinterface) - [\Consolidation\OutputFormatters\Validate\ValidDataTypesInterface (interface)](#interface-consolidationoutputformattersvalidatevaliddatatypesinterface) @@ -640,15 +642,58 @@ | Visibility | Function | |:-----------|:---------| | public | __construct(mixed $width) : void | +| public | minimumWidth(mixed $colkey, mixed $width) : void
Set the minimum width of just one column | | public | setMinimumWidths(array $minimumWidths) : void
If columns have minimum widths, then set them here. | | public | setPaddingFromStyle(\Symfony\Component\Console\Helper\TableStyle $style) : void
Calculate our padding widths from the specified table style. | | public | wrap(array $rows, array $widths=array()) : array
Wrap the cells in each part of the provided data table | -| protected | columnAutowidth(array $rows, array $widths) : void
Determine the best fit for column widths. Ported from Drush. (in characters) - these will be left as is. | -| protected static | longestWordLength(string $str) : int
Return the length of the longest word in the string. | -| protected | selectColumnToReduce(mixed $col_dist, mixed $auto_widths, mixed $max_word_lens) : void | -| protected | shouldSelectThisColumn(mixed $count, mixed $counts, mixed $width) : bool | +| protected | calculateWidths(mixed $rows, array $widths=array()) : void
Determine what widths we'll use for wrapping. | | protected | wrapCell(mixed $cell, string $cellWidth) : mixed
Wrap one cell. Guard against modifying non-strings and then call through to wordwrap(). | +
+### Class: \Consolidation\OutputFormatters\Transformations\Wrap\CalculateWidths + +> Calculate column widths for table cells. Influenced by Drush and webmozart/console. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct() : void | +| public | calculate(mixed $availableWidth, [\Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths](#class-consolidationoutputformatterstransformationswrapcolumnwidths) $dataWidths, [\Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths](#class-consolidationoutputformatterstransformationswrapcolumnwidths) $minimumWidths) : void
Given the total amount of available space, and the width of the columns to place, calculate the optimum column widths to use. | +| public | calculateLongestCell(mixed $rows) : void
Calculate the longest cell data from any row of each of the cells. | +| public | calculateLongestWord(mixed $rows) : void
Calculate the longest word and longest line in the provided data. | +| public | distributeLongColumns(mixed $availableWidth, [\Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths](#class-consolidationoutputformatterstransformationswrapcolumnwidths) $dataWidths, [\Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths](#class-consolidationoutputformatterstransformationswrapcolumnwidths) $minimumWidths) : void
Distribute the remainig space among the columns that were not included in the list of "short" columns. | +| public | getShortColumns(mixed $availableWidth, [\Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths](#class-consolidationoutputformatterstransformationswrapcolumnwidths) $dataWidths, [\Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths](#class-consolidationoutputformatterstransformationswrapcolumnwidths) $minimumWidths) : mixed
Return all of the columns whose longest line length is less than or equal to the average width. | +| protected | calculateColumnWidths(mixed $rows, \callable $fn) : void | +| protected static | longestWordLength(string $str) : int
Return the length of the longest word in the string. | + +
+### Class: \Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths + +> Calculate the width of data in table cells in preparation for word wrapping. + +| Visibility | Function | +|:-----------|:---------| +| public | __construct(array $widths=array()) : void | +| public | adjustMinimumWidths(mixed $availableWidth, mixed $dataCellWidths) : void
If the widths specified by this object do not fit within the provided avaiable width, then reduce them all proportionally. | +| public | averageWidth(mixed $availableWidth) : void
Calculate how much space is available on average for all columns. | +| public | combine([\Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths](#class-consolidationoutputformatterstransformationswrapcolumnwidths) $combineWith) : void
Combine this set of widths with another set, and return a new set that contains the entries from both. | +| public | count() : void
Return the number of columns. | +| public | distribute(mixed $availableWidth) : void
Return proportional weights | +| public | enforceMinimums(mixed $minimumWidths) : void
Ensure that every item in $widths that has a corresponding entry in $minimumWidths is as least as large as the minimum value held there. | +| public | findShortColumns(mixed $thresholdWidth) : mixed
Find all of the columns that are shorter than the specified threshold. | +| public | findUndersizedColumns(mixed $minimumWidths) : mixed
Find all of the columns that are shorter than the corresponding minimum widths. | +| public | isEmpty() : bool
Return true if there is no data in this object | +| public | keys() : void
Return the available keys (column identifiers) from the calculated data set. | +| public | lastColumn() : void | +| public | paddingSpace(mixed $paddingInEachCell, mixed $extraPaddingAtEndOfLine, mixed $extraPaddingAtBeginningOfLine) : void | +| public | removeColumns(mixed $columnKeys) : void
Remove all of the specified columns from this data structure. | +| public | selectColumns(mixed $columnKeys) : void
Select all columns that exist in the provided list of keys. | +| public | setWidth(mixed $key, mixed $width) : void
Set the length of the specified column. | +| public static | sumWidth(mixed $widths) : void
Return the sum of the lengths of the provided widths. | +| public | totalWidth() : void
Return the sum of the lengths of the provided widths. | +| public | width(mixed $key) : void
Return the length of the specified column. | +| public | widths() : void
Return all of the lengths | +| protected | findColumnsUnderThreshold(array $thresholdWidths) : mixed | +
### Interface: \Consolidation\OutputFormatters\Validate\ValidationInterface diff --git a/vendor/consolidation/output-formatters/src/Transformations/DomToArraySimplifier.php b/vendor/consolidation/output-formatters/src/Transformations/DomToArraySimplifier.php index d6771d073..e7a6c8794 100644 --- a/vendor/consolidation/output-formatters/src/Transformations/DomToArraySimplifier.php +++ b/vendor/consolidation/output-formatters/src/Transformations/DomToArraySimplifier.php @@ -85,7 +85,8 @@ class DomToArraySimplifier implements SimplifyToArrayInterface return []; } $uniformChildrenName = $this->hasUniformChildren($element); - if ("{$uniformChildrenName}s" == $element->nodeName) { + // Check for plurals. + if (in_array($element->nodeName, ["{$uniformChildrenName}s", "{$uniformChildrenName}es"])) { $result = $this->getUniformChildren($element->nodeName, $element); } else { $result = $this->getUniqueChildren($element->nodeName, $element); diff --git a/vendor/consolidation/output-formatters/src/Transformations/WordWrapper.php b/vendor/consolidation/output-formatters/src/Transformations/WordWrapper.php index 18519d077..36f9b88d0 100644 --- a/vendor/consolidation/output-formatters/src/Transformations/WordWrapper.php +++ b/vendor/consolidation/output-formatters/src/Transformations/WordWrapper.php @@ -1,12 +1,14 @@ width = $width; + $this->minimumWidths = new ColumnWidths(); } /** @@ -40,7 +43,15 @@ class WordWrapper */ public function setMinimumWidths($minimumWidths) { - $this->minimumWidths = $minimumWidths; + $this->minimumWidths = new ColumnWidths($minimumWidths); + } + + /** + * Set the minimum width of just one column + */ + public function minimumWidth($colkey, $width) + { + $this->minimumWidths->setWidth($colkey, $width); } /** @@ -50,19 +61,18 @@ class WordWrapper */ public function wrap($rows, $widths = []) { - // If the width was not set, then disable wordwrap. - if (!$this->width) { + $auto_widths = $this->calculateWidths($rows, $widths); + + // If no widths were provided, then disable wrapping + if ($auto_widths->isEmpty()) { return $rows; } - // Calculate the column widths to use based on the content. - $auto_widths = $this->columnAutowidth($rows, $widths); - // Do wordwrap on all cells. $newrows = array(); foreach ($rows as $rowkey => $row) { foreach ($row as $colkey => $cell) { - $newrows[$rowkey][$colkey] = $this->wrapCell($cell, $auto_widths[$colkey]); + $newrows[$rowkey][$colkey] = $this->wrapCell($cell, $auto_widths->width($colkey)); } } @@ -70,158 +80,43 @@ class WordWrapper } /** - * Wrap one cell. Guard against modifying non-strings and - * then call through to wordwrap(). - * - * @param mixed $cell - * @param string $cellWidth - * @return mixed - */ - protected function wrapCell($cell, $cellWidth) - { - if (!is_string($cell)) { - return $cell; - } - return wordwrap($cell, $cellWidth, "\n", true); - } - - /** - * Determine the best fit for column widths. Ported from Drush. - * - * @param array $rows The rows to use for calculations. - * @param array $widths Manually specified widths of each column - * (in characters) - these will be left as is. + * Determine what widths we'll use for wrapping. */ - protected function columnAutowidth($rows, $widths) + protected function calculateWidths($rows, $widths = []) { - $auto_widths = $widths; - - // First we determine the distribution of row lengths in each column. - // This is an array of descending character length keys (i.e. starting at - // the rightmost character column), with the value indicating the number - // of rows where that character column is present. - $col_dist = []; - // We will also calculate the longest word in each column - $max_word_lens = []; - foreach ($rows as $rowkey => $row) { - foreach ($row as $col_id => $cell) { - $longest_word_len = static::longestWordLength($cell); - if ((!isset($max_word_lens[$col_id]) || ($max_word_lens[$col_id] < $longest_word_len))) { - $max_word_lens[$col_id] = $longest_word_len; - } - if (empty($widths[$col_id])) { - $length = strlen($cell); - if ($length == 0) { - $col_dist[$col_id][0] = 0; - } - while ($length > 0) { - if (!isset($col_dist[$col_id][$length])) { - $col_dist[$col_id][$length] = 0; - } - $col_dist[$col_id][$length]++; - $length--; - } - } - } + // Widths must be provided in some form or another, or we won't wrap. + if (empty($widths) && !$this->width) { + return new ColumnWidths(); } - foreach ($col_dist as $col_id => $count) { - // Sort the distribution in decending key order. - krsort($col_dist[$col_id]); - // Initially we set all columns to their "ideal" longest width - // - i.e. the width of their longest column. - $auto_widths[$col_id] = max(array_keys($col_dist[$col_id])); - } - - // We determine what width we have available to use, and what width the - // above "ideal" columns take up. - $available_width = $this->width - ($this->extraPaddingAtBeginningOfLine + $this->extraPaddingAtEndOfLine + (count($auto_widths) * $this->paddingInEachCell)); - $auto_width_current = array_sum($auto_widths); - - // If we cannot fit into the minimum width anyway, then just return - // the max word length of each column as the 'ideal' - $minimumIdealLength = array_sum($this->minimumWidths); - if ($minimumIdealLength && ($available_width < $minimumIdealLength)) { - return $max_word_lens; - } + // Technically, `$widths`, if provided here, should be used + // as the exact widths to wrap to. For now we'll just treat + // these as minimum widths + $minimumWidths = $this->minimumWidths->combine(new ColumnWidths($widths)); - // If we need to reduce a column so that we can fit the space we use this - // loop to figure out which column will cause the "least wrapping", - // (relative to the other columns) and reduce the width of that column. - while ($auto_width_current > $available_width) { - list($column, $width) = $this->selectColumnToReduce($col_dist, $auto_widths, $max_word_lens); + $calculator = new CalculateWidths(); + $dataCellWidths = $calculator->calculateLongestCell($rows); - if (!$column || $width <= 1) { - // If we have reached a width of 1 then give up, so wordwrap can still progress. - break; - } - // Reduce the width of the selected column. - $auto_widths[$column]--; - // Reduce our overall table width counter. - $auto_width_current--; - // Remove the corresponding data from the disctribution, so next time - // around we use the data for the row to the left. - unset($col_dist[$column][$width]); - } - return $auto_widths; - } + $availableWidth = $this->width - $dataCellWidths->paddingSpace($this->paddingInEachCell, $this->extraPaddingAtEndOfLine, $this->extraPaddingAtBeginningOfLine); - protected function selectColumnToReduce($col_dist, $auto_widths, $max_word_lens) - { - $column = false; - $count = 0; - $width = 0; - foreach ($col_dist as $col_id => $counts) { - // Of the columns whose length is still > than the the lenght - // of their maximum word length - if ($auto_widths[$col_id] > $max_word_lens[$col_id]) { - if ($this->shouldSelectThisColumn($count, $counts, $width)) { - $column = $col_id; - $count = current($counts); - $width = key($counts); - } - } - } - if ($column !== false) { - return [$column, $width]; - } - foreach ($col_dist as $col_id => $counts) { - if (empty($this->minimumWidths) || ($auto_widths[$col_id] > $this->minimumWidths[$col_id])) { - if ($this->shouldSelectThisColumn($count, $counts, $width)) { - $column = $col_id; - $count = current($counts); - $width = key($counts); - } - } - } - return [$column, $width]; - } + $this->minimumWidths->adjustMinimumWidths($availableWidth, $dataCellWidths); - protected function shouldSelectThisColumn($count, $counts, $width) - { - return - // If we are just starting out, select the first column. - ($count == 0) || - // OR: if this column would cause less wrapping than the currently - // selected column, then select it. - (current($counts) < $count) || - // OR: if this column would cause the same amount of wrapping, but is - // longer, then we choose to wrap the longer column (proportionally - // less wrapping, and helps avoid triple line wraps). - (current($counts) == $count && key($counts) > $width); + return $calculator->calculate($availableWidth, $dataCellWidths, $minimumWidths); } /** - * Return the length of the longest word in the string. - * @param string $str - * @return int + * Wrap one cell. Guard against modifying non-strings and + * then call through to wordwrap(). + * + * @param mixed $cell + * @param string $cellWidth + * @return mixed */ - protected static function longestWordLength($str) + protected function wrapCell($cell, $cellWidth) { - $words = preg_split('/[ -]/', $str); - $lengths = array_map(function ($s) { - return strlen($s); - }, $words); - return max($lengths); + if (!is_string($cell)) { + return $cell; + } + return wordwrap($cell, $cellWidth, "\n", true); } } diff --git a/vendor/consolidation/output-formatters/src/Transformations/Wrap/CalculateWidths.php b/vendor/consolidation/output-formatters/src/Transformations/Wrap/CalculateWidths.php new file mode 100644 index 000000000..04af09208 --- /dev/null +++ b/vendor/consolidation/output-formatters/src/Transformations/Wrap/CalculateWidths.php @@ -0,0 +1,141 @@ +totalWidth() <= $availableWidth) { + return $dataWidths->enforceMinimums($minimumWidths); + } + + // Get the short columns first. If there are none, then distribute all + // of the available width among the remaining columns. + $shortColWidths = $this->getShortColumns($availableWidth, $dataWidths, $minimumWidths); + if ($shortColWidths->isEmpty()) { + return $this->distributeLongColumns($availableWidth, $dataWidths, $minimumWidths); + } + + // If some short columns were removed, then account for the length + // of the removed columns and make a recursive call (since the average + // width may be higher now, if the removed columns were shorter in + // length than the previous average). + $availableWidth -= $shortColWidths->totalWidth(); + $remainingWidths = $dataWidths->removeColumns($shortColWidths->keys()); + $remainingColWidths = $this->calculate($availableWidth, $remainingWidths, $minimumWidths); + + return $shortColWidths->combine($remainingColWidths); + } + + /** + * Calculate the longest cell data from any row of each of the cells. + */ + public function calculateLongestCell($rows) + { + return $this->calculateColumnWidths( + $rows, + function ($cell) { + return strlen($cell); + } + ); + } + + /** + * Calculate the longest word and longest line in the provided data. + */ + public function calculateLongestWord($rows) + { + return $this->calculateColumnWidths( + $rows, + function ($cell) { + return static::longestWordLength($cell); + } + ); + } + + protected function calculateColumnWidths($rows, callable $fn) + { + $widths = []; + + // Examine each row and find the longest line length and longest + // word in each column. + foreach ($rows as $rowkey => $row) { + foreach ($row as $colkey => $cell) { + $value = $fn($cell); + if ((!isset($widths[$colkey]) || ($widths[$colkey] < $value))) { + $widths[$colkey] = $value; + } + } + } + + return new ColumnWidths($widths); + } + + /** + * Return all of the columns whose longest line length is less than or + * equal to the average width. + */ + public function getShortColumns($availableWidth, ColumnWidths $dataWidths, ColumnWidths $minimumWidths) + { + $averageWidth = $dataWidths->averageWidth($availableWidth); + $shortColWidths = $dataWidths->findShortColumns($averageWidth); + return $shortColWidths->enforceMinimums($minimumWidths); + } + + /** + * Distribute the remainig space among the columns that were not + * included in the list of "short" columns. + */ + public function distributeLongColumns($availableWidth, ColumnWidths $dataWidths, ColumnWidths $minimumWidths) + { + // First distribute the remainder without regard to the minimum widths. + $result = $dataWidths->distribute($availableWidth); + + // Find columns that are shorter than their minimum width. + $undersized = $result->findUndersizedColumns($minimumWidths); + + // Nothing too small? Great, we're done! + if ($undersized->isEmpty()) { + return $result; + } + + // Take out the columns that are too small and redistribute the rest. + $availableWidth -= $undersized->totalWidth(); + $remaining = $dataWidths->removeColumns($undersized->keys()); + $distributeRemaining = $this->distributeLongColumns($availableWidth, $remaining, $minimumWidths); + + return $undersized->combine($distributeRemaining); + } + + /** + * Return the length of the longest word in the string. + * @param string $str + * @return int + */ + protected static function longestWordLength($str) + { + $words = preg_split('#[ /-]#', $str); + $lengths = array_map(function ($s) { + return strlen($s); + }, $words); + return max($lengths); + } +} diff --git a/vendor/consolidation/output-formatters/src/Transformations/Wrap/ColumnWidths.php b/vendor/consolidation/output-formatters/src/Transformations/Wrap/ColumnWidths.php new file mode 100644 index 000000000..6995b6afb --- /dev/null +++ b/vendor/consolidation/output-formatters/src/Transformations/Wrap/ColumnWidths.php @@ -0,0 +1,264 @@ +widths = $widths; + } + + public function paddingSpace( + $paddingInEachCell, + $extraPaddingAtEndOfLine = 0, + $extraPaddingAtBeginningOfLine = 0 + ) { + return ($extraPaddingAtBeginningOfLine + $extraPaddingAtEndOfLine + (count($this->widths) * $paddingInEachCell)); + } + + /** + * Find all of the columns that are shorter than the specified threshold. + */ + public function findShortColumns($thresholdWidth) + { + $thresholdWidths = array_fill_keys(array_keys($this->widths), $thresholdWidth); + + return $this->findColumnsUnderThreshold($thresholdWidths); + } + + /** + * Find all of the columns that are shorter than the corresponding minimum widths. + */ + public function findUndersizedColumns($minimumWidths) + { + return $this->findColumnsUnderThreshold($minimumWidths->widths()); + } + + protected function findColumnsUnderThreshold(array $thresholdWidths) + { + $shortColWidths = []; + foreach ($this->widths as $key => $maxLength) { + if (isset($thresholdWidths[$key]) && ($maxLength <= $thresholdWidths[$key])) { + $shortColWidths[$key] = $maxLength; + } + } + + return new ColumnWidths($shortColWidths); + } + + /** + * If the widths specified by this object do not fit within the + * provided avaiable width, then reduce them all proportionally. + */ + public function adjustMinimumWidths($availableWidth, $dataCellWidths) + { + $result = $this->selectColumns($dataCellWidths->keys()); + if ($result->isEmpty()) { + return $result; + } + $numberOfColumns = $dataCellWidths->count(); + + // How many unspecified columns are there? + $unspecifiedColumns = $numberOfColumns - $result->count(); + $averageWidth = $this->averageWidth($availableWidth); + + // Reserve some space for the columns that have no minimum. + // Make sure they collectively get at least half of the average + // width for each column. Or should it be a quarter? + $reservedSpacePerColumn = ($averageWidth / 2); + $reservedSpace = $reservedSpacePerColumn * $unspecifiedColumns; + + // Calculate how much of the available space is remaining for use by + // the minimum column widths after the reserved space is accounted for. + $remainingAvailable = $availableWidth - $reservedSpace; + + // Don't do anything if our widths fit inside the available widths. + if ($result->totalWidth() <= $remainingAvailable) { + return $result; + } + + // Shrink the minimum widths if the table is too compressed. + return $result->distribute($remainingAvailable); + } + + /** + * Return proportional weights + */ + public function distribute($availableWidth) + { + $result = []; + $totalWidth = $this->totalWidth(); + $lastColumn = $this->lastColumn(); + $widths = $this->widths(); + + // Take off the last column, and calculate proportional weights + // for the first N-1 columns. + array_pop($widths); + foreach ($widths as $key => $width) { + $result[$key] = round(($width / $totalWidth) * $availableWidth); + } + + // Give the last column the rest of the available width + $usedWidth = $this->sumWidth($result); + $result[$lastColumn] = $availableWidth - $usedWidth; + + return new ColumnWidths($result); + } + + public function lastColumn() + { + $keys = $this->keys(); + return array_pop($keys); + } + + /** + * Return the number of columns. + */ + public function count() + { + return count($this->widths); + } + + /** + * Calculate how much space is available on average for all columns. + */ + public function averageWidth($availableWidth) + { + if ($this->isEmpty()) { + debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + } + return $availableWidth / $this->count(); + } + + /** + * Return the available keys (column identifiers) from the calculated + * data set. + */ + public function keys() + { + return array_keys($this->widths); + } + + /** + * Set the length of the specified column. + */ + public function setWidth($key, $width) + { + $this->widths[$key] = $width; + } + + /** + * Return the length of the specified column. + */ + public function width($key) + { + return isset($this->widths[$key]) ? $this->widths[$key] : 0; + } + + /** + * Return all of the lengths + */ + public function widths() + { + return $this->widths; + } + + /** + * Return true if there is no data in this object + */ + public function isEmpty() + { + return empty($this->widths); + } + + /** + * Return the sum of the lengths of the provided widths. + */ + public function totalWidth() + { + return static::sumWidth($this->widths()); + } + + /** + * Return the sum of the lengths of the provided widths. + */ + public static function sumWidth($widths) + { + return array_reduce( + $widths, + function ($carry, $item) { + return $carry + $item; + } + ); + } + + /** + * Ensure that every item in $widths that has a corresponding entry + * in $minimumWidths is as least as large as the minimum value held there. + */ + public function enforceMinimums($minimumWidths) + { + $result = []; + if ($minimumWidths instanceof ColumnWidths) { + $minimumWidths = $minimumWidths->widths(); + } + $minimumWidths += $this->widths; + + foreach ($this->widths as $key => $value) { + $result[$key] = max($value, $minimumWidths[$key]); + } + + return new ColumnWidths($result); + } + + /** + * Remove all of the specified columns from this data structure. + */ + public function removeColumns($columnKeys) + { + $widths = $this->widths(); + + foreach ($columnKeys as $key) { + unset($widths[$key]); + } + + return new ColumnWidths($widths); + } + + /** + * Select all columns that exist in the provided list of keys. + */ + public function selectColumns($columnKeys) + { + $widths = []; + + foreach ($columnKeys as $key) { + if (isset($this->widths[$key])) { + $widths[$key] = $this->width($key); + } + } + + return new ColumnWidths($widths); + } + + /** + * Combine this set of widths with another set, and return + * a new set that contains the entries from both. + */ + public function combine(ColumnWidths $combineWith) + { + // Danger: array_merge renumbers numeric keys; that must not happen here. + $combined = $combineWith->widths(); + foreach ($this->widths() as $key => $value) { + $combined[$key] = $value; + } + return new ColumnWidths($combined); + } +} diff --git a/vendor/consolidation/output-formatters/tests/testFormatters.php b/vendor/consolidation/output-formatters/tests/testFormatters.php index 18b576797..40271c5ef 100644 --- a/vendor/consolidation/output-formatters/tests/testFormatters.php +++ b/vendor/consolidation/output-formatters/tests/testFormatters.php @@ -527,7 +527,6 @@ EOT; function testTableWithWordWrapping() { $options = new FormatterOptions(); - $options->setWidth(42); $data = [ [ @@ -538,19 +537,191 @@ EOT; $data = new RowsOfFields($data); $expected = <<setWidth(42); + $this->assertFormattedOutputMatches($expected, 'table', $data, $options); + + $expected = <<setWidth(78); + $this->assertFormattedOutputMatches($expected, 'table', $data, $options); + } + + function testWrappingLotsOfColumns() + { + $options = new FormatterOptions(); + + $data = [ + [ + 'id' => '4d87b545-b4c3-4ece-9908-20c5c5e67e81', + 'name' => '123456781234567812345678123456781234567812345678', + 'service_level' => 'business', + 'framework' => 'wordpress-network', + 'owner' => '8558a08d-8059-45f6-9c4b-908299a025ee', + 'created' => '2017-05-24 19:28:45', + 'memberships' => 'b3a42ba5-755d-42ca-9109-21bde32809d0: Team,9bfaaf50-ece3-4460-acb8-dc1b8dd536e8: pantheon-engineering-canary-sites', + 'frozen' => 'false', + ], + [ + 'id' => '3d87b545-b4c3-4ece-9908-20c5c5e67e80', + 'name' => 'build-tools-136', + 'service_level' => 'free', + 'framework' => 'drupal8', + 'owner' => '7558a08d-8059-45f6-9c4b-908299a025ef', + 'created' => '2017-05-24 19:28:45', + 'memberships' => '5ae1fa30-8cc4-4894-8ca9-d50628dcba17: ci-for-drupal-8-composer', + 'frozen' => 'false', + ] + ]; + $data = new RowsOfFields($data); + + $expected = <<setWidth(125); + $this->assertFormattedOutputMatches($expected, 'table', $data, $options); + } + + function testTableWithWordWrapping2() + { + $options = new FormatterOptions(); + + $data = [ + [ + 'id' => 42, + 'vid' => 321, + 'description' => 'Life, the Universe and Everything.', + ], + [ + 'id' => 13, + 'vid' => 789, + 'description' => 'Why is six afraid of seven?', + ], + ]; + $data = new RowsOfFields($data); + $expected = <<setWidth(42); + $this->assertFormattedOutputMatches($expected, 'table', $data, $options); + } + + function testTableWithWordWrapping3() + { + $options = new FormatterOptions(); + $data = [ + 'name' => 'Rex', + 'species' => 'dog', + 'food' => 'kibble', + 'legs' => '4', + 'description' => 'Rex is a very good dog, Brett. He likes kibble, and has four legs.', + ]; + $data = new PropertyList($data); + + $expected = <<setWidth(42); + $this->assertFormattedOutputMatches($expected, 'table', $data, $options); + } + + function testTableWithWordWrapping4() + { + $options = new FormatterOptions(); + + $data = [ + 'name' => ['label' => 'Name', 'sep' => ':', 'value' => 'Rex', ], + 'species' => ['label' => 'Species', 'sep' => ':', 'value' => 'dog', ], + 'food' => ['label' => 'Food', 'sep' => ':', 'value' => 'kibble', ], + 'legs' => ['label' => 'Legs', 'sep' => ':', 'value' => '4', ], + 'description' => ['label' => 'Description', 'sep' => ':', 'value' => 'Rex is a very good dog, Brett. He likes kibble, and has four legs.', ], + ]; + $data = new RowsOfFields($data); + $expected = <<setWidth(78); + $this->assertFormattedOutputMatches($expected, 'table', $data, $options); + } + + function testTableWithWordWrapping5() + { + $options = new FormatterOptions(); + $data = [ + 'name' => ['Name', ':', 'Rex', ], + 'species' => ['Species', ':', 'dog', ], + 'food' => ['Food', ':', 'kibble', ], + 'legs' => ['Legs', ':', '4', ], + 'description' => ['Description', ':', 'Rex is a very good dog, Brett. He likes kibble, and has four legs.', ], + ]; + $data = new RowsOfFields($data); + $expected = <<setWidth(78); + $options->setIncludeFieldLables(false); + $options->setTableStyle('compact'); $this->assertFormattedOutputMatches($expected, 'table', $data, $options); } diff --git a/vendor/doctrine/collections/CONTRIBUTING.md b/vendor/doctrine/collections/CONTRIBUTING.md new file mode 100644 index 000000000..407a66521 --- /dev/null +++ b/vendor/doctrine/collections/CONTRIBUTING.md @@ -0,0 +1,67 @@ +# Contribute to Doctrine + +Thank you for contributing to Doctrine! + +Before we can merge your Pull-Request here are some guidelines that you need to follow. +These guidelines exist not to annoy you, but to keep the code base clean, +unified and future proof. + +## We only accept PRs to "master" + +Our branching strategy is "everything to master first", even +bugfixes and we then merge them into the stable branches. You should only +open pull requests against the master branch. Otherwise we cannot accept the PR. + +There is one exception to the rule, when we merged a bug into some stable branches +we do occasionally accept pull requests that merge the same bug fix into earlier +branches. + +## Coding Standard + +We use [doctrine coding standard](https://github.com/doctrine/coding-standard) which is PSR-1 and PSR-2: + +* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md +* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md + +with some exceptions/differences: + +* Keep the nesting of control structures per method as small as possible +* Align equals (=) signs +* Add spaces between assignment, control and return statements +* Prefer early exit over nesting conditions +* Add spaces around a negation if condition ``if ( ! $cond)`` +* Add legal information at the beginning of each source file +* Add ``@author`` [phpDoc](https://www.phpdoc.org/docs/latest/references/phpdoc/tags/author.html) comment at DockBlock of class/interface/trait that you create. + +## Unit-Tests + +Please try to add a test for your pull-request. + +* If you want to contribute new functionality add unit- or functional tests + depending on the scope of the feature. + +You can run the unit-tests by calling ``vendor/bin/phpunit`` from the root of the project. +It will run all the project tests. + +In order to do that, you will need a fresh copy of doctrine/collections, and you +will have to run a composer installation in the project: + +```sh +git clone git@github.com:doctrine/collections.git +cd collections +curl -sS https://getcomposer.org/installer | php -- +./composer.phar install +``` + +## Travis + +We automatically run your pull request through [Travis CI](https://www.travis-ci.org) +against supported PHP versions. If you break the tests, we cannot merge your code, +so please make sure that your code is working before opening up a Pull-Request. + +## Getting merged + +Please allow us time to review your pull requests. We will give our best to review +everything as fast as possible, but cannot always live up to our own expectations. + +Thank you very much again for your contribution! diff --git a/vendor/doctrine/collections/README.md b/vendor/doctrine/collections/README.md new file mode 100644 index 000000000..81e06d0ce --- /dev/null +++ b/vendor/doctrine/collections/README.md @@ -0,0 +1,27 @@ +# Doctrine Collections + +[![Build Status](https://travis-ci.org/doctrine/collections.svg?branch=master)](https://travis-ci.org/doctrine/collections) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/collections/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/collections/?branch=master) +[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/collections/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/collections/?branch=master) + +Collections Abstraction library + +## Changelog + +### v1.3.0 + +* [Explicit casting of first and max results in criteria API](https://github.com/doctrine/collections/pull/26) +* [Keep keys when using `ArrayCollection#matching()` with sorting](https://github.com/doctrine/collections/pull/49) +* [Made `AbstractLazyCollection#$initialized` protected for extensibility](https://github.com/doctrine/collections/pull/52) + +### v1.2.0 + +* Add a new ``AbstractLazyCollection`` + +### v1.1.0 + +* Deprecated ``Comparison::IS``, because it's only there for SQL semantics. + These are fixed in the ORM instead. +* Add ``Comparison::CONTAINS`` to perform partial string matches: + + $criteria->andWhere($criteria->expr()->contains('property', 'Foo')); diff --git a/vendor/doctrine/collections/composer.json b/vendor/doctrine/collections/composer.json index 155cac48f..385fa93d2 100644 --- a/vendor/doctrine/collections/composer.json +++ b/vendor/doctrine/collections/composer.json @@ -13,17 +13,23 @@ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} ], "require": { - "php": ">=5.3.2" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^5.7", + "doctrine/coding-standard": "~0.1@dev" }, "autoload": { "psr-0": { "Doctrine\\Common\\Collections\\": "lib/" } }, + "autoload-dev": { + "psr-4": { + "Doctrine\\Tests\\": "tests/Doctrine/Tests" + } + }, "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.3.x-dev" } } } diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php index bce575120..7ddd068e5 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php @@ -26,6 +26,11 @@ use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor; /** * An ArrayCollection is a Collection implementation that wraps a regular PHP array. * + * Warning: Using (un-)serialize() on a collection is not a supported use-case + * and may break when we change the internals in the future. If you need to + * serialize a collection use {@link toArray()} and reconstruct the collection + * manually. + * * @since 2.0 * @author Guilherme Blanco * @author Jonathan Wage @@ -50,6 +55,21 @@ class ArrayCollection implements Collection, Selectable $this->elements = $elements; } + /** + * Creates a new instance from the specified elements. + * + * This method is provided for derived classes to specify how a new + * instance should be created when constructor semantics have changed. + * + * @param array $elements Elements. + * + * @return static + */ + protected function createFrom(array $elements) + { + return new static($elements); + } + /** * {@inheritDoc} */ @@ -254,9 +274,9 @@ class ArrayCollection implements Collection, Selectable /** * {@inheritDoc} */ - public function add($value) + public function add($element) { - $this->elements[] = $value; + $this->elements[] = $element; return true; } @@ -284,7 +304,7 @@ class ArrayCollection implements Collection, Selectable */ public function map(Closure $func) { - return new static(array_map($func, $this->elements)); + return $this->createFrom(array_map($func, $this->elements)); } /** @@ -292,7 +312,7 @@ class ArrayCollection implements Collection, Selectable */ public function filter(Closure $p) { - return new static(array_filter($this->elements, $p)); + return $this->createFrom(array_filter($this->elements, $p)); } /** @@ -324,7 +344,7 @@ class ArrayCollection implements Collection, Selectable } } - return array(new static($matches), new static($noMatches)); + return array($this->createFrom($matches), $this->createFrom($noMatches)); } /** @@ -368,8 +388,9 @@ class ArrayCollection implements Collection, Selectable } if ($orderings = $criteria->getOrderings()) { + $next = null; foreach (array_reverse($orderings) as $field => $ordering) { - $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1); + $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1, $next); } uasort($filtered, $next); @@ -382,6 +403,6 @@ class ArrayCollection implements Collection, Selectable $filtered = array_slice($filtered, (int)$offset, $length); } - return new static($filtered); + return $this->createFrom($filtered); } } diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php index 994085f91..1239aa393 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php @@ -69,6 +69,24 @@ class ClosureExpressionVisitor extends ExpressionVisitor return $object[$field]; } + if (isset($object->$field)) { + return $object->$field; + } + + // camelcase field name to support different variable naming conventions + $ccField = preg_replace_callback('/_(.?)/', function($matches) { return strtoupper($matches[1]); }, $field); + + foreach ($accessors as $accessor) { + $accessor .= $ccField; + + + if ( ! method_exists($object, $accessor)) { + continue; + } + + return $object->$accessor(); + } + return $object->$field; } @@ -155,6 +173,26 @@ class ClosureExpressionVisitor extends ExpressionVisitor return false !== strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); }; + case Comparison::MEMBER_OF: + return function ($object) use ($field, $value) { + $fieldValues = ClosureExpressionVisitor::getObjectFieldValue($object, $field); + if (!is_array($fieldValues)) { + $fieldValues = iterator_to_array($fieldValues); + } + return in_array($value, $fieldValues); + }; + + case Comparison::STARTS_WITH: + return function ($object) use ($field, $value) { + return 0 === strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); + }; + + case Comparison::ENDS_WITH: + return function ($object) use ($field, $value) { + return $value === substr(ClosureExpressionVisitor::getObjectFieldValue($object, $field), -strlen($value)); + }; + + default: throw new \RuntimeException("Unknown comparison operator: " . $comparison->getOperator()); } diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php index d54ecf25c..ec9a9f48a 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php @@ -27,17 +27,19 @@ namespace Doctrine\Common\Collections\Expr; */ class Comparison implements Expression { - const EQ = '='; - const NEQ = '<>'; - const LT = '<'; - const LTE = '<='; - const GT = '>'; - const GTE = '>='; - const IS = '='; // no difference with EQ - const IN = 'IN'; - const NIN = 'NIN'; - const CONTAINS = 'CONTAINS'; - + const EQ = '='; + const NEQ = '<>'; + const LT = '<'; + const LTE = '<='; + const GT = '>'; + const GTE = '>='; + const IS = '='; // no difference with EQ + const IN = 'IN'; + const NIN = 'NIN'; + const CONTAINS = 'CONTAINS'; + const MEMBER_OF = 'MEMBER_OF'; + const STARTS_WITH = 'STARTS_WITH'; + const ENDS_WITH = 'ENDS_WITH'; /** * @var string */ diff --git a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php index 6539e3c75..1a44a7ba8 100644 --- a/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php +++ b/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php @@ -27,7 +27,7 @@ use Doctrine\Common\Collections\Expr\Value; * Builder for Expressions in the {@link Selectable} interface. * * Important Notice for interoperable code: You have to use scalar - * values only for comparisons, otherwise the behavior of the comparision + * values only for comparisons, otherwise the behavior of the comparison * may be different between implementations (Array vs ORM vs ODM). * * @author Benjamin Eberlei @@ -163,4 +163,38 @@ class ExpressionBuilder { return new Comparison($field, Comparison::CONTAINS, new Value($value)); } + + /** + * @param string $field + * @param mixed $value + * + * @return Comparison + */ + public function memberOf ($field, $value) + { + return new Comparison($field, Comparison::MEMBER_OF, new Value($value)); + } + + /** + * @param string $field + * @param mixed $value + * + * @return Comparison + */ + public function startsWith($field, $value) + { + return new Comparison($field, Comparison::STARTS_WITH, new Value($value)); + } + + /** + * @param string $field + * @param mixed $value + * + * @return Comparison + */ + public function endsWith($field, $value) + { + return new Comparison($field, Comparison::ENDS_WITH, new Value($value)); + } + } diff --git a/vendor/drupal-composer/drupal-scaffold/.editorconfig b/vendor/drupal-composer/drupal-scaffold/.editorconfig new file mode 100644 index 000000000..12bcb27e4 --- /dev/null +++ b/vendor/drupal-composer/drupal-scaffold/.editorconfig @@ -0,0 +1,17 @@ +# Drupal editor configuration normalization +# @see http://editorconfig.org/ + +# This is the top-most .editorconfig file; do not search in parent directories. +root = true + +# All files. +[*] +end_of_line = LF +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[{composer.json,composer.lock}] +indent_size = 4 diff --git a/vendor/drupal-composer/drupal-scaffold/.gitignore b/vendor/drupal-composer/drupal-scaffold/.gitignore new file mode 100644 index 000000000..22d0d82f8 --- /dev/null +++ b/vendor/drupal-composer/drupal-scaffold/.gitignore @@ -0,0 +1 @@ +vendor diff --git a/vendor/drupal-composer/drupal-scaffold/.travis.yml b/vendor/drupal-composer/drupal-scaffold/.travis.yml new file mode 100644 index 000000000..72635d7ce --- /dev/null +++ b/vendor/drupal-composer/drupal-scaffold/.travis.yml @@ -0,0 +1,25 @@ +language: php +php: + - 5.5 + - 5.6 + - 7.0 + +sudo: false + +git: + depth: 10000 + +before_install: + - phpenv config-rm xdebug.ini + - composer --verbose self-update + - composer --version + +install: + - composer --verbose install + +before_script: + - git config --global user.email "travisci@example.com" + - git config --global user.name "Travis CI Test" + +script: + - ./vendor/bin/phpunit diff --git a/vendor/drupal-composer/drupal-scaffold/README.md b/vendor/drupal-composer/drupal-scaffold/README.md new file mode 100644 index 000000000..82f7c8703 --- /dev/null +++ b/vendor/drupal-composer/drupal-scaffold/README.md @@ -0,0 +1,120 @@ +# drupal-scaffold + +[![Build Status](https://travis-ci.org/drupal-composer/drupal-scaffold.svg?branch=master)](https://travis-ci.org/drupal-composer/drupal-scaffold) + +Composer plugin for automatically downloading Drupal scaffold files (like +`index.php`, `update.php`, …) when using `drupal/core` via Composer. + +It is recommended that the vendor directory be placed in its standard location +at the project root, outside of the Drupal root; however, the location of the +vendor directory and the name of the Drupal root may be placed in whatever +location suits the project. Drupal-scaffold will generate the autoload.php +file at the Drupal root to require the Composer-generated autoload file in the +vendor directory. + +## Usage + +Run `composer require drupal-composer/drupal-scaffold:dev-master` in your composer +project before installing or updating `drupal/core`. + +Once drupal-scaffold is required by your project, it will automatically update +your scaffold files whenever `composer update` changes the version of +`drupal/core` installed. + +## Configuration + +You can configure the plugin with providing some settings in the `extra` section +of your root `composer.json`. + +```json +{ + "extra": { + "drupal-scaffold": { + "source": "http://cgit.drupalcode.org/drupal/plain/{path}?h={version}", + "excludes": [ + "google123.html", + "robots.txt" + ], + "includes": [ + "sites/default/example.settings.my.php" + ], + "initial": { + "sites/default/default.services.yml": "sites/default/services.yml", + "sites/default/default.settings.php": "sites/default/settings.php" + }, + "omit-defaults": false + } + } +} +``` +The `source` option may be used to specify the URL to download the +scaffold files from; the default source is drupal.org. The literal string +`{version}` in the `source` option is replaced with the current version of +Drupal core being updated prior to download. + +With the `drupal-scaffold` option `excludes`, you can provide additional paths +that should not be copied or overwritten. The plugin provides no excludes by +default. + +Default includes are provided by the plugin: +``` +.csslintrc +.editorconfig +.eslintignore +.eslintrc (Drupal <= 8.2.x) +.eslintrc.json (Drupal >= 8.3.x) +.gitattributes +.htaccess +index.php +robots.txt +sites/default/default.settings.php +sites/default/default.services.yml +sites/development.services.yml +sites/example.settings.local.php +sites/example.sites.php +update.php +web.config +``` + +When setting `omit-defaults` to `true`, neither the default excludes nor the +default includes will be provided; in this instance, only those files explicitly +listed in the `excludes` and `includes` options will be considered. If +`omit-defaults` is `false` (the default), then any items listed in `excludes` +or `includes` will be in addition to the usual defaults. + +The `initial` hash lists files that should be copied over only if they do not +exist in the destination. The key specifies the path to the source file, and +the value indicates the path to the destination file. + +## Limitation + +When using Composer to install or update the Drupal development branch, the +scaffold files are always taken from the HEAD of the branch (or, more +specifically, from the most recent development .tar.gz archive). This might +not be what you want when using an old development version (e.g. when the +version is fixed via composer.lock). To avoid problems, always commit your +scaffold files to the repository any time that composer.lock is committed. +Note that the correct scaffold files are retrieved when using a tagged release +of `drupal/core` (recommended). + +## Custom command + +The plugin by default is only downloading the scaffold files when installing or +updating `drupal/core`. If you want to call it manually, you have to add the +command callback to the `scripts`-section of your root `composer.json`, like this: + +```json +{ + "scripts": { + "drupal-scaffold": "DrupalComposer\\DrupalScaffold\\Plugin::scaffold" + } +} +``` + +After that you can manually download the scaffold files according to your +configuration by using `composer drupal-scaffold`. + +It is assumed that the scaffold files will be committed to the repository, to +ensure that the correct files are used on the CI server (see **Limitation**, +above). After running `composer install` for the first time commit the scaffold +files to your repository. diff --git a/vendor/drupal-composer/drupal-scaffold/composer.lock b/vendor/drupal-composer/drupal-scaffold/composer.lock new file mode 100644 index 000000000..c7dc77794 --- /dev/null +++ b/vendor/drupal-composer/drupal-scaffold/composer.lock @@ -0,0 +1,1742 @@ +{ + "_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": "116f69e7f88bcdebdc157a80dfaa31c7", + "content-hash": "fcbb0cf6a792bee4cd64b27b2e58909c", + "packages": [], + "packages-dev": [ + { + "name": "composer/ca-bundle", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "a2995e5fe351055f2c7630166af12ce8fd03edfc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/a2995e5fe351055f2c7630166af12ce8fd03edfc", + "reference": "a2995e5fe351055f2c7630166af12ce8fd03edfc", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "symfony/process": "^2.5 || ^3.0" + }, + "suggest": { + "symfony/process": "This is necessary to reliably check whether openssl_x509_parse is vulnerable on older php versions, but can be ignored on PHP 5.5.6+" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "time": "2016-04-13 10:13:24" + }, + { + "name": "composer/composer", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "d401f6e95cca835d165c61648327fc1fa062ba31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/d401f6e95cca835d165c61648327fc1fa062ba31", + "reference": "d401f6e95cca835d165c61648327fc1fa062ba31", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.0", + "justinrainbow/json-schema": "^1.6", + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", + "seld/cli-prompt": "^1.0", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.5 || ^3.0", + "symfony/filesystem": "^2.5 || ^3.0", + "symfony/finder": "^2.2 || ^3.0", + "symfony/process": "^2.1 || ^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2016-05-19 18:44:43" + }, + { + "name": "composer/semver", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "84c47f3d8901440403217afc120683c7385aecb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/84c47f3d8901440403217afc120683c7385aecb8", + "reference": "84c47f3d8901440403217afc120683c7385aecb8", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2016-03-30 13:16:03" + }, + { + "name": "composer/spdx-licenses", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "88c26372b1afac36d8db601cdf04ad8716f53d88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/88c26372b1afac36d8db601cdf04ad8716f53d88", + "reference": "88c26372b1afac36d8db601cdf04ad8716f53d88", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2016-05-04 12:27:30" + }, + { + "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": "justinrainbow/json-schema", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "cc84765fb7317f6b07bd8ac78364747f95b86341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/cc84765fb7317f6b07bd8ac78364747f95b86341", + "reference": "cc84765fb7317f6b07bd8ac78364747f95b86341", + "shasum": "" + }, + "require": { + "php": ">=5.3.29" + }, + "require-dev": { + "json-schema/json-schema-test-suite": "1.1.0", + "phpdocumentor/phpdocumentor": "~2", + "phpunit/phpunit": "~3.7" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2016-01-25 15:43:01" + }, + { + "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.6.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972", + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.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": "2016-02-15 07:46:21" + }, + { + "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.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.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": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2015-06-21 13:08:43" + }, + { + "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.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4|~5" + }, + "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": "2016-05-12 18:03:57" + }, + { + "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.8.26", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "fc1d8cd5b5de11625979125c5639347896ac2c74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc1d8cd5b5de11625979125c5639347896ac2c74", + "reference": "fc1d8cd5b5de11625979125c5639347896ac2c74", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8.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": "2016-05-17 03:09:28" + }, + { + "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": "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.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", + "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": "2016-05-17 03:18:57" + }, + { + "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": "seld/cli-prompt", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/cli-prompt.git", + "reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4", + "reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\CliPrompt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", + "keywords": [ + "cli", + "console", + "hidden", + "input", + "prompt" + ], + "time": "2016-04-18 09:31:41" + }, + { + "name": "seld/jsonlint", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "66834d3e3566bb5798db7294619388786ae99394" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/66834d3e3566bb5798db7294619388786ae99394", + "reference": "66834d3e3566bb5798db7294619388786ae99394", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2015-11-21 02:21:41" + }, + { + "name": "seld/phar-utils", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13 18:44:15" + }, + { + "name": "symfony/console", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "34a214710e0714b6efcf40ba3cd1e31373a97820" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/34a214710e0714b6efcf40ba3cd1e31373a97820", + "reference": "34a214710e0714b6efcf40ba3cd1e31373a97820", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-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": "2016-04-28 09:48:42" + }, + { + "name": "symfony/filesystem", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "74fec3511b62cb934b64bce1d96f06fffa4beafd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/74fec3511b62cb934b64bce1d96f06fffa4beafd", + "reference": "74fec3511b62cb934b64bce1d96f06fffa4beafd", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-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": "2016-04-12 18:09:53" + }, + { + "name": "symfony/finder", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "c54e407b35bc098916704e9fd090da21da4c4f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/c54e407b35bc098916704e9fd090da21da4c4f52", + "reference": "c54e407b35bc098916704e9fd090da21da4c4f52", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2016-03-10 11:13:05" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "dff51f72b0706335131b00a7f49606168c582594" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", + "reference": "dff51f72b0706335131b00a7f49606168c582594", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-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": "2016-05-18 14:26:46" + }, + { + "name": "symfony/process", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "53f9407c0bb1c5a79127db8f7bfe12f0f6f3dcdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/53f9407c0bb1c5a79127db8f7bfe12f0f6f3dcdb", + "reference": "53f9407c0bb1c5a79127db8f7bfe12f0f6f3dcdb", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2016-04-14 15:30:28" + }, + { + "name": "symfony/yaml", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "0047c8366744a16de7516622c5b7355336afae96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0047c8366744a16de7516622c5b7355336afae96", + "reference": "0047c8366744a16de7516622c5b7355336afae96", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-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": "2016-03-04 07:55:57" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "composer/composer": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.4.5" + }, + "platform-dev": [] +} diff --git a/vendor/drupal-composer/drupal-scaffold/phpunit.xml.dist b/vendor/drupal-composer/drupal-scaffold/phpunit.xml.dist new file mode 100644 index 000000000..ac16a3eaf --- /dev/null +++ b/vendor/drupal-composer/drupal-scaffold/phpunit.xml.dist @@ -0,0 +1,15 @@ + + + + + + ./tests/ + + + diff --git a/vendor/drupal-composer/drupal-scaffold/src/Handler.php b/vendor/drupal-composer/drupal-scaffold/src/Handler.php index 51c340c60..b6ca659cd 100644 --- a/vendor/drupal-composer/drupal-scaffold/src/Handler.php +++ b/vendor/drupal-composer/drupal-scaffold/src/Handler.php @@ -10,9 +10,9 @@ namespace DrupalComposer\DrupalScaffold; use Composer\Composer; use Composer\DependencyResolver\Operation\InstallOperation; use Composer\DependencyResolver\Operation\UpdateOperation; +use Composer\EventDispatcher\EventDispatcher; use Composer\IO\IOInterface; use Composer\Package\PackageInterface; -use Composer\EventDispatcher\EventDispatcher; use Composer\Util\Filesystem; use Composer\Util\RemoteFilesystem; use Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem; @@ -113,7 +113,7 @@ class Handler { $remoteFs = new RemoteFilesystem($this->io); - $fetcher = new FileFetcher($remoteFs, $options['source'], $files); + $fetcher = new PrestissimoFileFetcher($remoteFs, $options['source'], $files, $this->io, $this->composer->getConfig()); $fetcher->fetch($version, $webroot); $initialFileFetcher = new InitialFileFetcher($remoteFs, $options['source'], $this->getInitial()); diff --git a/vendor/drupal-composer/drupal-scaffold/src/InitialFileFetcher.php b/vendor/drupal-composer/drupal-scaffold/src/InitialFileFetcher.php index e9ce3144b..4b46c70a3 100644 --- a/vendor/drupal-composer/drupal-scaffold/src/InitialFileFetcher.php +++ b/vendor/drupal-composer/drupal-scaffold/src/InitialFileFetcher.php @@ -7,10 +7,8 @@ namespace DrupalComposer\DrupalScaffold; -use Composer\Util\Filesystem; -use Composer\Util\RemoteFilesystem; - class InitialFileFetcher extends FileFetcher { + public function fetch($version, $destination) { array_walk($this->filenames, function ($filename, $sourceFilename) use ($version, $destination) { $target = "$destination/$filename"; @@ -21,4 +19,5 @@ class InitialFileFetcher extends FileFetcher { } }); } + } diff --git a/vendor/drupal-composer/drupal-scaffold/src/Plugin.php b/vendor/drupal-composer/drupal-scaffold/src/Plugin.php index 3424afd55..73fd2a0fc 100644 --- a/vendor/drupal-composer/drupal-scaffold/src/Plugin.php +++ b/vendor/drupal-composer/drupal-scaffold/src/Plugin.php @@ -8,10 +8,10 @@ namespace DrupalComposer\DrupalScaffold; use Composer\Composer; use Composer\EventDispatcher\EventSubscriberInterface; +use Composer\Installer\PackageEvent; use Composer\Installer\PackageEvents; use Composer\IO\IOInterface; use Composer\Plugin\PluginInterface; -use Composer\Installer\PackageEvent; use Composer\Script\ScriptEvents; /** diff --git a/vendor/drupal-composer/drupal-scaffold/src/PrestissimoFileFetcher.php b/vendor/drupal-composer/drupal-scaffold/src/PrestissimoFileFetcher.php new file mode 100644 index 000000000..a99aa1d7b --- /dev/null +++ b/vendor/drupal-composer/drupal-scaffold/src/PrestissimoFileFetcher.php @@ -0,0 +1,66 @@ +io = $io; + $this->config = $config; + } + + public function fetch($version, $destination) { + if (class_exists(CurlMulti::class)) { + $this->fetchWithPrestissimo($version, $destination); + return; + } + parent::fetch($version, $destination); + } + + protected function fetchWithPrestissimo($version, $destination) { + $requests = []; + array_walk($this->filenames, function ($filename) use ($version, $destination, &$requests) { + $url = $this->getUri($filename, $version); + $this->fs->ensureDirectoryExists($destination . '/' . dirname($filename)); + $requests[] = new CopyRequest($url, $destination . '/' . $filename, false, $this->io, $this->config); + }); + + $successCnt = $failureCnt = 0; + $totalCnt = count($requests); + + $multi = new CurlMulti; + $multi->setRequests($requests); + do { + $multi->setupEventLoop(); + $multi->wait(); + $result = $multi->getFinishedResults(); + $successCnt += $result['successCnt']; + $failureCnt += $result['failureCnt']; + foreach ($result['urls'] as $url) { + $this->io->writeError(" $successCnt/$totalCnt:\t$url", true, \Composer\IO\IOInterface::VERBOSE); + } + } while ($multi->remain()); + } + +} diff --git a/vendor/drupal-composer/drupal-scaffold/tests/FetcherTest.php b/vendor/drupal-composer/drupal-scaffold/tests/FetcherTest.php new file mode 100644 index 000000000..39b3e730c --- /dev/null +++ b/vendor/drupal-composer/drupal-scaffold/tests/FetcherTest.php @@ -0,0 +1,99 @@ +rootDir = realpath(realpath(__DIR__ . '/..')); + + // Prepare temp directory. + $this->fs = new Filesystem(); + $this->tmpDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'drupal-scaffold'; + $this->ensureDirectoryExistsAndClear($this->tmpDir); + + chdir($this->tmpDir); + } + + /** + * Makes sure the given directory exists and has no content. + * + * @param string $directory + */ + protected function ensureDirectoryExistsAndClear($directory) { + if (is_dir($directory)) { + $this->fs->removeDirectory($directory); + } + mkdir($directory, 0777, true); + } + + public function testFetch() { + $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}', ['.htaccess', 'sites/default/default.settings.php']); + $fetcher->fetch('8.1.1', $this->tmpDir); + $this->assertFileExists($this->tmpDir . '/.htaccess'); + $this->assertFileExists($this->tmpDir . '/sites/default/default.settings.php'); + } + + /** + * Tests version specific files. + */ + public function testFetchVersionSpecific() { + $fetcher = new FileFetcher(new RemoteFilesystem(new NullIO()), 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}', ['.eslintrc', '.eslintrc.json']); + + $this->setExpectedException(TransportException::class); + $fetcher->fetch('8.2.x', $this->tmpDir); + + $this->assertFileExists($this->tmpDir . '/.eslintrc'); + $this->assertFileNotExists($this->tmpDir . '/.eslintrc.json'); + + // Remove downloaded files to retest with 8.3.x. + @unlink($this->tmpDir . '/.eslintrc'); + + $this->setExpectedException(TransportException::class); + $fetcher->fetch('8.3.x', $this->tmpDir); + + $this->assertFileExists($this->tmpDir . '/.eslintrc.json'); + $this->assertFileNotExists($this->tmpDir . '/.eslintrc'); + } + + public function testInitialFetch() { + $fetcher = new InitialFileFetcher(new RemoteFilesystem(new NullIO()), 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}', ['sites/default/default.settings.php' => 'sites/default/settings.php']); + $fetcher->fetch('8.1.1', $this->tmpDir); + $this->assertFileExists($this->tmpDir . '/sites/default/settings.php'); + } +} diff --git a/vendor/drupal-composer/drupal-scaffold/tests/PluginTest.php b/vendor/drupal-composer/drupal-scaffold/tests/PluginTest.php new file mode 100644 index 000000000..704649160 --- /dev/null +++ b/vendor/drupal-composer/drupal-scaffold/tests/PluginTest.php @@ -0,0 +1,185 @@ +rootDir = realpath(realpath(__DIR__ . '/..')); + + // Prepare temp directory. + $this->fs = new Filesystem(); + $this->tmpDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'drupal-scaffold'; + $this->ensureDirectoryExistsAndClear($this->tmpDir); + + $this->writeTestReleaseTag(); + $this->writeComposerJSON(); + + chdir($this->tmpDir); + } + + /** + * tearDown + * + * @return void + */ + public function tearDown() + { + $this->fs->removeDirectory($this->tmpDir); + $this->git(sprintf('tag -d "%s"', $this->tmpReleaseTag)); + } + + /** + * Tests a simple composer install without core, but adding core later. + */ + public function testComposerInstallAndUpdate() { + $exampleScaffoldFile = $this->tmpDir . DIRECTORY_SEPARATOR . 'index.php'; + $this->assertFileNotExists($exampleScaffoldFile, 'Scaffold file should not be exist.'); + $this->composer('install'); + $this->assertFileExists($this->tmpDir . DIRECTORY_SEPARATOR . 'core', 'Drupal core is installed.'); + $this->assertFileExists($exampleScaffoldFile, 'Scaffold file should be automatically installed.'); + $this->fs->remove($exampleScaffoldFile); + $this->assertFileNotExists($exampleScaffoldFile, 'Scaffold file should not be exist.'); + $this->composer('drupal-scaffold'); + $this->assertFileExists($exampleScaffoldFile, 'Scaffold file should be installed by "drupal-scaffold" command.'); + + foreach (['8.0.1', '8.1.x-dev'] as $version) { + // We touch a scaffold file, so we can check the file was modified after + // the scaffold update. + touch($exampleScaffoldFile); + $mtime_touched = filemtime($exampleScaffoldFile); + // Requiring a newer version triggers "composer update" + $this->composer('require --update-with-dependencies drupal/core:"' . $version .'"'); + clearstatcache(); + $mtime_after = filemtime($exampleScaffoldFile); + $this->assertNotEquals($mtime_after, $mtime_touched, 'Scaffold file was modified by composer update. (' . $version . ')'); + } + + // We touch a scaffold file, so we can check the file was modified after + // the custom commandscaffold update. + touch($exampleScaffoldFile); + clearstatcache(); + $mtime_touched = filemtime($exampleScaffoldFile); + $this->composer('drupal-scaffold'); + clearstatcache(); + $mtime_after = filemtime($exampleScaffoldFile); + $this->assertNotEquals($mtime_after, $mtime_touched, 'Scaffold file was modified by custom command.'); + } + + /** + * Writes the default composer json to the temp direcoty. + */ + protected function writeComposerJSON() { + $json = json_encode($this->composerJSONDefaults(), JSON_PRETTY_PRINT); + // Write composer.json. + file_put_contents($this->tmpDir . '/composer.json', $json); + } + + /** + * Writes a tag for the current commit, so we can reference it directly in the + * composer.json. + */ + protected function writeTestReleaseTag() { + // Tag the current state. + $this->tmpReleaseTag = '999.0.' . time(); + $this->git(sprintf('tag -a "%s" -m "%s"', $this->tmpReleaseTag, 'Tag for testing this exact commit')); + } + + /** + * Provides the default composer.json data. + * + * @return array + */ + protected function composerJSONDefaults() { + return array( + 'repositories' => array( + array( + 'type' => 'vcs', + 'url' => $this->rootDir, + ) + ), + 'require' => array( + 'drupal-composer/drupal-scaffold' => $this->tmpReleaseTag, + 'composer/installers' => '^1.0.20', + 'drupal/core' => '8.0.0', + ), + 'scripts' => array( + 'drupal-scaffold' => 'DrupalComposer\\DrupalScaffold\\Plugin::scaffold' + ), + 'minimum-stability' => 'dev', + ); + } + + /** + * Wrapper for the composer command. + * + * @param string $command + * Composer command name, arguments and/or options + */ + protected function composer($command) { + chdir($this->tmpDir); + passthru(escapeshellcmd($this->rootDir . '/vendor/bin/composer ' . $command), $exit_code); + if ($exit_code !== 0) { + throw new \Exception('Composer returned a non-zero exit code'); + } + } + + /** + * Wrapper for git command in the root directory. + * + * @param $command + * Git command name, arguments and/or options. + */ + protected function git($command) { + chdir($this->rootDir); + passthru(escapeshellcmd('git ' . $command), $exit_code); + if ($exit_code !== 0) { + throw new \Exception('Git returned a non-zero exit code'); + } + } + + /** + * Makes sure the given directory exists and has no content. + * + * @param string $directory + */ + protected function ensureDirectoryExistsAndClear($directory) { + if (is_dir($directory)) { + $this->fs->removeDirectory($directory); + } + mkdir($directory, 0777, true); + } +} diff --git a/vendor/drupal/console-core/composer.json b/vendor/drupal/console-core/composer.json index ae07f36a5..359ac1fc6 100644 --- a/vendor/drupal/console-core/composer.json +++ b/vendor/drupal/console-core/composer.json @@ -37,7 +37,7 @@ }, "require": { "php": "^5.5.9 || ^7.0", - "drupal/console-en" : "1.0.0-rc16", + "drupal/console-en" : "1.0.0-rc21", "dflydev/dot-access-configuration": "1.0.1", "stecman/symfony-console-completion": "~0.7", "symfony/console": ">=2.7 <3.0", @@ -51,13 +51,12 @@ "symfony/yaml": ">=2.7 <3.0", "symfony/event-dispatcher": ">=2.7 <3.0", "twig/twig": "^1.23.1", - "webflo/drupal-finder": "0.*" + "webflo/drupal-finder": "^0.3.0" }, "minimum-stability": "dev", "prefer-stable": true, "autoload": { "files": [ - "src/constants.php", "src/functions.php" ], "psr-4": {"Drupal\\Console\\Core\\": "src"} diff --git a/vendor/drupal/console-core/composer.lock b/vendor/drupal/console-core/composer.lock index 16f68bcc4..1b4ecd8a4 100644 --- a/vendor/drupal/console-core/composer.lock +++ b/vendor/drupal/console-core/composer.lock @@ -4,7 +4,7 @@ "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": "b3fef964398b7a8304e2c4e649756b86", + "content-hash": "5378635239d17fe962f215288baee221", "packages": [ { "name": "dflydev/dot-access-configuration", @@ -179,16 +179,16 @@ }, { "name": "drupal/console-en", - "version": "1.0.0-rc16", + "version": "1.0.0-rc21", "source": { "type": "git", "url": "https://github.com/hechoendrupal/drupal-console-en.git", - "reference": "32c1e4c31500ba4ccd5e68bd74977fd6258c3e37" + "reference": "b6f563b8760c3b19aad22dd213a9cfba2f2c75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-en/zipball/32c1e4c31500ba4ccd5e68bd74977fd6258c3e37", - "reference": "32c1e4c31500ba4ccd5e68bd74977fd6258c3e37", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-en/zipball/b6f563b8760c3b19aad22dd213a9cfba2f2c75d0", + "reference": "b6f563b8760c3b19aad22dd213a9cfba2f2c75d0", "shasum": "" }, "type": "drupal-console-language", @@ -229,7 +229,7 @@ "drupal", "symfony" ], - "time": "2017-02-09T16:02:27+00:00" + "time": "2017-05-20T23:29:05+00:00" }, { "name": "psr/log", @@ -1002,16 +1002,16 @@ }, { "name": "webflo/drupal-finder", - "version": "0.2.1", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/webflo/drupal-finder.git", - "reference": "4bd98f7e7b1d30e284e55f51d5d0c8712f676348" + "reference": "6ef150707aad1755d91f9b0d2108bcc16661e76b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/4bd98f7e7b1d30e284e55f51d5d0c8712f676348", - "reference": "4bd98f7e7b1d30e284e55f51d5d0c8712f676348", + "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/6ef150707aad1755d91f9b0d2108bcc16661e76b", + "reference": "6ef150707aad1755d91f9b0d2108bcc16661e76b", "shasum": "" }, "require-dev": { @@ -1035,7 +1035,7 @@ } ], "description": "Helper class to locate a Drupal installation from a given path.", - "time": "2016-11-28T18:50:45+00:00" + "time": "2017-05-04T08:54:02+00:00" } ], "packages-dev": [], diff --git a/vendor/drupal/console-core/src/Application.php b/vendor/drupal/console-core/src/Application.php index d23d01fe8..6e20fcd3a 100644 --- a/vendor/drupal/console-core/src/Application.php +++ b/vendor/drupal/console-core/src/Application.php @@ -295,7 +295,7 @@ class Application extends BaseApplication $autoWireForcedCommands = $configuration ->get('application.autowire.commands.forced'); - if(!is_array($autoWireForcedCommands)){ + if (!is_array($autoWireForcedCommands)) { return; } diff --git a/vendor/drupal/console-core/src/Bootstrap/DrupalConsoleCore.php b/vendor/drupal/console-core/src/Bootstrap/DrupalConsoleCore.php index d35c262e7..16ad4f1d5 100644 --- a/vendor/drupal/console-core/src/Bootstrap/DrupalConsoleCore.php +++ b/vendor/drupal/console-core/src/Bootstrap/DrupalConsoleCore.php @@ -13,6 +13,7 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; /** * Class DrupalConsoleCore + * * @package Drupal\Console\Core\Bootstrap */ class DrupalConsoleCore @@ -29,6 +30,7 @@ class DrupalConsoleCore /** * DrupalConsole constructor. + * * @param $root * @param $appRoot */ @@ -45,15 +47,18 @@ class DrupalConsoleCore { $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator($this->root)); - $loader->load($this->root.DRUPAL_CONSOLE_CORE.'/services.yml'); - if (file_exists($this->root.'/services.yml')) { - $loader->load('services.yml'); - } - if (file_exists($this->root.DRUPAL_CONSOLE.'/services-drupal-install.yml')) { - $loader->load( - $this->root . DRUPAL_CONSOLE . '/services-drupal-install.yml' - ); + $servicesFiles = [ + $this->root.DRUPAL_CONSOLE_CORE.'/services.yml', + $this->root.'/services.yml', + $this->root.DRUPAL_CONSOLE.'/uninstall.services.yml', + $this->root.DRUPAL_CONSOLE.'/extend.console.uninstall.services.yml' + ]; + + foreach ($servicesFiles as $servicesFile) { + if (file_exists($servicesFile)) { + $loader->load($servicesFile); + } } $container->get('console.configuration_manager') @@ -82,7 +87,7 @@ class DrupalConsoleCore $autoloadFile = $directory . 'vendor/autoload.php'; if (is_file($autoloadFile)) { include_once $autoloadFile; - $extendServicesFile = $directory . 'extend.console.services.yml'; + $extendServicesFile = $directory . 'extend.console.uninstall.services.yml'; if (is_file($extendServicesFile)) { $loader->load($extendServicesFile); } diff --git a/vendor/drupal/console-core/src/Command/Chain/ChainCommand.php b/vendor/drupal/console-core/src/Command/Chain/ChainCommand.php index fa13b64cb..5fdf71113 100644 --- a/vendor/drupal/console-core/src/Command/Chain/ChainCommand.php +++ b/vendor/drupal/console-core/src/Command/Chain/ChainCommand.php @@ -11,6 +11,7 @@ use Dflydev\PlaceholderResolver\DataSource\ArrayDataSource; use Dflydev\PlaceholderResolver\RegexPlaceholderResolver; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Command\Command; use Symfony\Component\Filesystem\Filesystem; @@ -23,6 +24,7 @@ use Drupal\Console\Core\Command\Shared\CommandTrait; /** * Class ChainCommand + * * @package Drupal\Console\Core\Command\Chain */ class ChainCommand extends Command @@ -42,6 +44,7 @@ class ChainCommand extends Command /** * ChainCommand constructor. + * * @param ChainQueue $chainQueue * @param ChainDiscovery $chainDiscovery */ @@ -291,6 +294,9 @@ class ChainCommand extends Command $commands = $configData['commands']; } + $chainInlineOptions = $input->getOptions(); + unset($chainInlineOptions['file']); + foreach ($commands as $command) { $moduleInputs = []; $arguments = !empty($command['arguments']) ? $command['arguments'] : []; @@ -304,20 +310,42 @@ class ChainCommand extends Command $moduleInputs['--'.$key] = is_null($value) ? '' : $value; } - $parameterOptions = $input->getOptions(); - unset($parameterOptions['file']); - foreach ($parameterOptions as $key => $value) { - if ($value===true) { - $moduleInputs['--' . $key] = true; + // Get application global options + foreach ($this->getApplication()->getDefinition()->getOptions() as $option) { + $optionName = $option->getName(); + if (array_key_exists($optionName, $chainInlineOptions)) { + $optionValue = $chainInlineOptions[$optionName]; + // Set global option only if is not available in command options + if (!isset($moduleInputs['--' . $optionName]) && $optionValue) { + $moduleInputs['--' . $optionName] = $optionValue; + } } } - $this->chainQueue->addCommand( - $command['command'], - $moduleInputs, - $interactive, - $learning - ); + $application = $this->getApplication(); + $callCommand = $application->find($command['command']); + + if (!$callCommand) { + continue; + } + + $io->text($command['command']); + $io->newLine(); + + $input = new ArrayInput($moduleInputs); + if (!is_null($interactive)) { + $input->setInteractive($interactive); + } + + $allowFailure = array_key_exists('allow_failure', $command)?$command['allow_failure']:false; + try { + $callCommand->run($input, $io); + } catch (\Exception $e) { + if (!$allowFailure) { + $io->error($e->getMessage()); + return 1; + } + } } return 0; diff --git a/vendor/drupal/console-core/src/Command/Chain/ChainDebugCommand.php b/vendor/drupal/console-core/src/Command/Chain/ChainDebugCommand.php index d5936707f..f5a7a48c4 100644 --- a/vendor/drupal/console-core/src/Command/Chain/ChainDebugCommand.php +++ b/vendor/drupal/console-core/src/Command/Chain/ChainDebugCommand.php @@ -16,6 +16,7 @@ use Drupal\Console\Core\Command\Shared\CommandTrait; /** * Class ChainDebugCommand + * * @package Drupal\Console\Core\Command\Chain */ class ChainDebugCommand extends Command diff --git a/vendor/drupal/console-core/src/Command/CheckCommand.php b/vendor/drupal/console-core/src/Command/CheckCommand.php index aab2f3844..33fd6205e 100644 --- a/vendor/drupal/console-core/src/Command/CheckCommand.php +++ b/vendor/drupal/console-core/src/Command/CheckCommand.php @@ -18,6 +18,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class CheckCommand + * * @package Drupal\Console\Core\Command */ class CheckCommand extends BaseCommand @@ -41,6 +42,7 @@ class CheckCommand extends BaseCommand /** * CheckCommand constructor. + * * @param RequirementChecker $requirementChecker * @param ChainQueue $chainQueue * @param ConfigurationManager $configurationManager @@ -77,23 +79,17 @@ class CheckCommand extends BaseCommand $checks = $this->requirementChecker->getCheckResult(); if (!$checks) { $phpCheckFile = $this->configurationManager->getHomeDirectory().'/.console/phpcheck.yml'; - $phpCheckFileDisplay = realpath($this->configurationManager->getHomeDirectory()).'/.console/phpcheck.yml'; if (!file_exists($phpCheckFile)) { $phpCheckFile = $this->configurationManager->getApplicationDirectory(). DRUPAL_CONSOLE_CORE. 'config/dist/phpcheck.yml'; - - $phpCheckFileDisplay = - realpath($this->configurationManager->getApplicationDirectory()). - DRUPAL_CONSOLE_CORE. - 'config/dist/phpcheck.yml'; } $io->newLine(); $io->info($this->trans('commands.check.messages.file')); - $io->comment($phpCheckFileDisplay); + $io->comment($phpCheckFile); $checks = $this->requirementChecker->validate($phpCheckFile); } diff --git a/vendor/drupal/console-core/src/Command/Exclude/DrupliconCommand.php b/vendor/drupal/console-core/src/Command/Exclude/DrupliconCommand.php index 516155ce4..540c361bb 100644 --- a/vendor/drupal/console-core/src/Command/Exclude/DrupliconCommand.php +++ b/vendor/drupal/console-core/src/Command/Exclude/DrupliconCommand.php @@ -17,6 +17,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class DrupliconCommand + * * @package Drupal\Console\Core\Command\Exclude */ class DrupliconCommand extends Command @@ -34,6 +35,7 @@ class DrupliconCommand extends Command /** * DrupliconCommand constructor. + * * @param string $appRoot * @param TwigRenderer $renderer */ diff --git a/vendor/drupal/console-core/src/Command/Exclude/DrushCommand.php b/vendor/drupal/console-core/src/Command/Exclude/DrushCommand.php index 8d0820082..833b829f5 100644 --- a/vendor/drupal/console-core/src/Command/Exclude/DrushCommand.php +++ b/vendor/drupal/console-core/src/Command/Exclude/DrushCommand.php @@ -18,6 +18,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class DrushCommand + * * @package Drupal\Console\Core\Command\Exclude */ class DrushCommand extends Command @@ -36,6 +37,7 @@ class DrushCommand extends Command /** * DrushCommand constructor. + * * @param ConfigurationManager $configurationManager * @param ChainQueue $chainQueue */ diff --git a/vendor/drupal/console-core/src/Command/Exclude/ElephpantCommand.php b/vendor/drupal/console-core/src/Command/Exclude/ElephpantCommand.php index 0afc81490..8d15be403 100644 --- a/vendor/drupal/console-core/src/Command/Exclude/ElephpantCommand.php +++ b/vendor/drupal/console-core/src/Command/Exclude/ElephpantCommand.php @@ -17,6 +17,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class ElephpantCommand + * * @package Drupal\Console\Core\Command\Exclude */ class ElephpantCommand extends Command @@ -35,6 +36,7 @@ class ElephpantCommand extends Command /** * DrupliconCommand constructor. + * * @param string $appRoot * @param TwigRenderer $renderer */ diff --git a/vendor/drupal/console-core/src/Command/Exec/ExecCommand.php b/vendor/drupal/console-core/src/Command/Exec/ExecCommand.php index 1c54ef493..4b3f283f5 100644 --- a/vendor/drupal/console-core/src/Command/Exec/ExecCommand.php +++ b/vendor/drupal/console-core/src/Command/Exec/ExecCommand.php @@ -19,6 +19,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class ExecCommand + * * @package Drupal\Console\Core\Command\Exec */ class ExecCommand extends Command @@ -32,6 +33,7 @@ class ExecCommand extends Command /** * ExecCommand constructor. + * * @param ShellProcess $shellProcess */ public function __construct(ShellProcess $shellProcess) diff --git a/vendor/drupal/console-core/src/Command/HelpCommand.php b/vendor/drupal/console-core/src/Command/HelpCommand.php index a13fef660..c497341ba 100644 --- a/vendor/drupal/console-core/src/Command/HelpCommand.php +++ b/vendor/drupal/console-core/src/Command/HelpCommand.php @@ -90,12 +90,12 @@ class HelpCommand extends Command private function createDefinition() { return new InputDefinition( - array( + [ new InputArgument('command_name', InputArgument::OPTIONAL, $this->trans('commands.help.arguments.command_name'), 'help'), new InputOption('xml', null, InputOption::VALUE_NONE, $this->trans('commands.help.options.xml')), new InputOption('raw', null, InputOption::VALUE_NONE, $this->trans('commands.help.options.raw')), new InputOption('format', null, InputOption::VALUE_REQUIRED, $this->trans('commands.help.options.format'), 'txt'), - ) + ] ); } } diff --git a/vendor/drupal/console-core/src/Command/InitCommand.php b/vendor/drupal/console-core/src/Command/InitCommand.php index 4df95bc21..9da25d3ee 100644 --- a/vendor/drupal/console-core/src/Command/InitCommand.php +++ b/vendor/drupal/console-core/src/Command/InitCommand.php @@ -21,6 +21,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class InitCommand + * * @package Drupal\Console\Core\Command */ class InitCommand extends Command @@ -55,6 +56,8 @@ class InitCommand extends Command private $configParameters = [ 'language' => 'en', 'temp' => '/tmp', + 'chain' => false, + 'sites' => false, 'learning' => false, 'generate_inline' => false, 'generate_chain' => false @@ -62,6 +65,7 @@ class InitCommand extends Command /** * InitCommand constructor. + * * @param ShowFile $showFile * @param ConfigurationManager $configurationManager * @param InitGenerator $generator @@ -146,8 +150,18 @@ class InitCommand extends Command ); $this->configParameters['learning'] = $io->confirm( + $this->trans('commands.init.questions.chain'), + false + ); + + $this->configParameters['sites'] = $io->confirm( + $this->trans('commands.init.questions.sites'), + false + ); + + $this->configParameters['chain'] = $io->confirm( $this->trans('commands.init.questions.learning'), - true + false ); $this->configParameters['generate_inline'] = $io->confirm( @@ -191,6 +205,12 @@ class InitCommand extends Command DRUPAL_CONSOLE_CORE ) ); + if (!$this->configParameters['chain']) { + $finder->exclude('chain'); + } + if (!$this->configParameters['sites']) { + $finder->exclude('sites'); + } $finder->files(); foreach ($finder as $configFile) { @@ -219,7 +239,7 @@ class InitCommand extends Command $executableName = null; if ($autocomplete) { - $processBuilder = new ProcessBuilder(array('bash')); + $processBuilder = new ProcessBuilder(['bash']); $process = $processBuilder->getProcess(); $process->setCommandLine('echo $_'); $process->run(); diff --git a/vendor/drupal/console-core/src/Command/ListCommand.php b/vendor/drupal/console-core/src/Command/ListCommand.php index 8ea58ebab..883c3d42b 100644 --- a/vendor/drupal/console-core/src/Command/ListCommand.php +++ b/vendor/drupal/console-core/src/Command/ListCommand.php @@ -17,6 +17,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class ListCommand + * * @package Drupal\Console\Core\Command */ class ListCommand extends Command @@ -76,12 +77,12 @@ class ListCommand extends Command private function createDefinition() { return new InputDefinition( - array( + [ new InputArgument('namespace', InputArgument::OPTIONAL, $this->trans('commands.list.arguments.namespace')), new InputOption('xml', null, InputOption::VALUE_NONE, $this->trans('commands.list.options.xml')), new InputOption('raw', null, InputOption::VALUE_NONE, $this->trans('commands.list.options.raw')), new InputOption('format', null, InputOption::VALUE_REQUIRED, $this->trans('commands.list.options.format'), 'txt'), - ) + ] ); } } diff --git a/vendor/drupal/console-core/src/Command/Settings/DebugCommand.php b/vendor/drupal/console-core/src/Command/Settings/DebugCommand.php index 50f62f4fc..ca35077f0 100644 --- a/vendor/drupal/console-core/src/Command/Settings/DebugCommand.php +++ b/vendor/drupal/console-core/src/Command/Settings/DebugCommand.php @@ -17,6 +17,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class DebugCommand + * * @package Drupal\Console\Core\Command\Settings */ class DebugCommand extends Command @@ -35,6 +36,7 @@ class DebugCommand extends Command /** * CheckCommand constructor. + * * @param ConfigurationManager $configurationManager * @param NestedArray $nestedArray */ diff --git a/vendor/drupal/console-core/src/Command/Settings/SetCommand.php b/vendor/drupal/console-core/src/Command/Settings/SetCommand.php index 3b4191720..0fc9ba68e 100644 --- a/vendor/drupal/console-core/src/Command/Settings/SetCommand.php +++ b/vendor/drupal/console-core/src/Command/Settings/SetCommand.php @@ -20,6 +20,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class SetCommand + * * @package Drupal\Console\Core\Command\Settings */ class SetCommand extends Command @@ -38,6 +39,7 @@ class SetCommand extends Command /** * CheckCommand constructor. + * * @param ConfigurationManager $configurationManager * @param NestedArray $nestedArray */ diff --git a/vendor/drupal/console-core/src/Command/Shared/ContainerAwareCommandTrait.php b/vendor/drupal/console-core/src/Command/Shared/ContainerAwareCommandTrait.php index 4945550c1..321e1ea3b 100644 --- a/vendor/drupal/console-core/src/Command/Shared/ContainerAwareCommandTrait.php +++ b/vendor/drupal/console-core/src/Command/Shared/ContainerAwareCommandTrait.php @@ -9,6 +9,7 @@ namespace Drupal\Console\Core\Command\Shared; /** * Class CommandTrait + * * @package Drupal\Console\Core\Command */ trait ContainerAwareCommandTrait diff --git a/vendor/drupal/console-core/src/Command/Shared/InputTrait.php b/vendor/drupal/console-core/src/Command/Shared/InputTrait.php index abe8aa0ad..5d0907fbb 100644 --- a/vendor/drupal/console-core/src/Command/Shared/InputTrait.php +++ b/vendor/drupal/console-core/src/Command/Shared/InputTrait.php @@ -9,6 +9,7 @@ namespace Drupal\Console\Core\Command\Shared; /** * Class InputTrait + * * @package Drupal\Console\Core\Command */ trait InputTrait diff --git a/vendor/drupal/console-core/src/Command/Site/DebugCommand.php b/vendor/drupal/console-core/src/Command/Site/DebugCommand.php index c91af67b0..74ecad33b 100644 --- a/vendor/drupal/console-core/src/Command/Site/DebugCommand.php +++ b/vendor/drupal/console-core/src/Command/Site/DebugCommand.php @@ -56,6 +56,12 @@ class DebugCommand extends Command $this->trans('commands.site.debug.options.target'), null ) + ->addArgument( + 'property', + InputArgument::OPTIONAL, + $this->trans('commands.site.debug.options.property'), + null + ) ->setHelp($this->trans('commands.site.debug.help')); } @@ -74,6 +80,7 @@ class DebugCommand extends Command return 1; } + // --target argument $target = $input->getArgument('target'); if (!$target) { @@ -93,6 +100,20 @@ class DebugCommand extends Command return 1; } + // --property argument, allows the user to fetch specific properties of the selected site + $property = $input->getArgument('property'); + if ($property) { + $property_keys = explode('.', $property); + + $val = $targetConfig; + foreach ($property_keys as $property_key) { + $val = &$val[$property_key]; + } + + $io->writeln($val); + return 0; + } + $io->info($target); $dumper = new Dumper(); $io->writeln($dumper->dump($targetConfig, 2)); diff --git a/vendor/drupal/console-core/src/Command/Yaml/DiffCommand.php b/vendor/drupal/console-core/src/Command/Yaml/DiffCommand.php index 98f39f2ff..47192f7ea 100644 --- a/vendor/drupal/console-core/src/Command/Yaml/DiffCommand.php +++ b/vendor/drupal/console-core/src/Command/Yaml/DiffCommand.php @@ -28,6 +28,7 @@ class DiffCommand extends Command /** * DiffCommand constructor. + * * @param NestedArray $nestedArray */ public function __construct(NestedArray $nestedArray) @@ -156,7 +157,7 @@ class DiffCommand extends Command return; } // FLAT YAML file to display full yaml to be used with command yaml:update:key or yaml:update:value - $diffFlatten = array(); + $diffFlatten = []; $keyFlatten = ''; $this->nestedArray->yamlFlattenArray($diff, $diffFlatten, $keyFlatten); diff --git a/vendor/drupal/console-core/src/Command/Yaml/GetValueCommand.php b/vendor/drupal/console-core/src/Command/Yaml/GetValueCommand.php index a02634ebb..e389dc33f 100644 --- a/vendor/drupal/console-core/src/Command/Yaml/GetValueCommand.php +++ b/vendor/drupal/console-core/src/Command/Yaml/GetValueCommand.php @@ -27,6 +27,7 @@ class GetValueCommand extends Command /** * GetValueCommand constructor. + * * @param NestedArray $nestedArray */ public function __construct(NestedArray $nestedArray) diff --git a/vendor/drupal/console-core/src/Command/Yaml/MergeCommand.php b/vendor/drupal/console-core/src/Command/Yaml/MergeCommand.php index 082509260..da655a769 100644 --- a/vendor/drupal/console-core/src/Command/Yaml/MergeCommand.php +++ b/vendor/drupal/console-core/src/Command/Yaml/MergeCommand.php @@ -15,6 +15,7 @@ use Symfony\Component\Yaml\Parser; use Symfony\Component\Console\Command\Command; use Drupal\Console\Core\Command\Shared\CommandTrait; use Drupal\Console\Core\Style\DrupalStyle; +use Symfony\Component\Filesystem\Filesystem; class MergeCommand extends Command { @@ -44,10 +45,28 @@ class MergeCommand extends Command $yaml = new Parser(); $dumper = new Dumper(); - $final_yaml = array(); + $final_yaml = []; $yaml_destination = realpath($input->getArgument('yaml-destination')); $yaml_files = $input->getArgument('yaml-files'); + if (!$yaml_destination) { + $fs = new Filesystem(); + try { + $fs->touch($input->getArgument('yaml-destination')); + $yaml_destination = realpath($input->getArgument('yaml-destination')); + } catch (\Exception $e) { + $io->error( + sprintf( + '%s: %s', + $this->trans('commands.yaml.merge.messages.error-writing'), + $e->getMessage() + ) + ); + + return; + } + } + if (count($yaml_files) < 2) { $io->error($this->trans('commands.yaml.merge.messages.two-files-required')); @@ -155,7 +174,7 @@ class MergeCommand extends Command $yaml_files = $input->getArgument('yaml-files'); if (!$yaml_files) { - $yaml_files = array(); + $yaml_files = []; while (true) { // Set the string key based on among files provided diff --git a/vendor/drupal/console-core/src/Command/Yaml/SplitCommand.php b/vendor/drupal/console-core/src/Command/Yaml/SplitCommand.php index bc2614546..a1d066c5b 100644 --- a/vendor/drupal/console-core/src/Command/Yaml/SplitCommand.php +++ b/vendor/drupal/console-core/src/Command/Yaml/SplitCommand.php @@ -29,6 +29,7 @@ class SplitCommand extends Command /** * SplitCommand constructor. + * * @param NestedArray $nestedArray */ public function __construct(NestedArray $nestedArray) @@ -138,7 +139,7 @@ class SplitCommand extends Command // Set minimum level to split $indent_level = empty($indent_level) ? 1 : $indent_level; - $yaml_split = array(); + $yaml_split = []; $key_flatten = ''; $initial_level = 1; diff --git a/vendor/drupal/console-core/src/Command/Yaml/UnsetKeyCommand.php b/vendor/drupal/console-core/src/Command/Yaml/UnsetKeyCommand.php index 40d00138c..3b36a78ae 100644 --- a/vendor/drupal/console-core/src/Command/Yaml/UnsetKeyCommand.php +++ b/vendor/drupal/console-core/src/Command/Yaml/UnsetKeyCommand.php @@ -28,6 +28,7 @@ class UnsetKeyCommand extends Command /** * UnsetKeyCommand constructor. + * * @param NestedArray $nestedArray */ public function __construct(NestedArray $nestedArray) diff --git a/vendor/drupal/console-core/src/Command/Yaml/UpdateKeyCommand.php b/vendor/drupal/console-core/src/Command/Yaml/UpdateKeyCommand.php index 761b59a20..7f6410a65 100644 --- a/vendor/drupal/console-core/src/Command/Yaml/UpdateKeyCommand.php +++ b/vendor/drupal/console-core/src/Command/Yaml/UpdateKeyCommand.php @@ -28,6 +28,7 @@ class UpdateKeyCommand extends Command /** * UpdateKeyCommand constructor. + * * @param NestedArray $nestedArray */ public function __construct(NestedArray $nestedArray) diff --git a/vendor/drupal/console-core/src/Command/Yaml/UpdateValueCommand.php b/vendor/drupal/console-core/src/Command/Yaml/UpdateValueCommand.php index 2e17cb73a..db23b9237 100644 --- a/vendor/drupal/console-core/src/Command/Yaml/UpdateValueCommand.php +++ b/vendor/drupal/console-core/src/Command/Yaml/UpdateValueCommand.php @@ -28,6 +28,7 @@ class UpdateValueCommand extends Command /** * UpdateValueCommand constructor. + * * @param NestedArray $nestedArray */ public function __construct(NestedArray $nestedArray) diff --git a/vendor/drupal/console-core/src/Descriptor/TextDescriptor.php b/vendor/drupal/console-core/src/Descriptor/TextDescriptor.php index 002b1473e..d02d07760 100644 --- a/vendor/drupal/console-core/src/Descriptor/TextDescriptor.php +++ b/vendor/drupal/console-core/src/Descriptor/TextDescriptor.php @@ -29,7 +29,7 @@ class TextDescriptor extends Descriptor /** * {@inheritdoc} */ - protected function describeInputArgument(InputArgument $argument, array $options = array()) + protected function describeInputArgument(InputArgument $argument, array $options = []) { if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) { $default = sprintf(' [default: %s]', $this->formatDefaultValue($argument->getDefault())); @@ -56,7 +56,7 @@ class TextDescriptor extends Descriptor /** * {@inheritdoc} */ - protected function describeInputOption(InputOption $option, array $options = array()) + protected function describeInputOption(InputOption $option, array $options = []) { if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) { $default = sprintf(' [default: %s]', $this->formatDefaultValue($option->getDefault())); @@ -70,7 +70,7 @@ class TextDescriptor extends Descriptor $value = '['.$value.']'; } } - $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions(array($option)); + $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions([$option]); $synopsis = sprintf( '%s%s', $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : ' ', @@ -96,7 +96,7 @@ class TextDescriptor extends Descriptor /** * {@inheritdoc} */ - protected function describeInputDefinition(InputDefinition $definition, array $options = array()) + protected function describeInputDefinition(InputDefinition $definition, array $options = []) { $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions()); foreach ($definition->getArguments() as $argument) { @@ -106,7 +106,7 @@ class TextDescriptor extends Descriptor $this->writeText($options['translator']->trans('commands.list.messages.arguments'), $options); $this->writeText("\n"); foreach ($definition->getArguments() as $argument) { - $this->describeInputArgument($argument, array_merge($options, array('total_width' => $totalWidth))); + $this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth])); $this->writeText("\n"); } } @@ -114,7 +114,7 @@ class TextDescriptor extends Descriptor $this->writeText("\n"); } if ($definition->getOptions()) { - $laterOptions = array(); + $laterOptions = []; $this->writeText($options['translator']->trans('commands.list.messages.options'), $options); foreach ($definition->getOptions() as $option) { if (strlen($option->getShortcut()) > 1) { @@ -122,27 +122,54 @@ class TextDescriptor extends Descriptor continue; } $this->writeText("\n"); - $this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth))); + $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); } foreach ($laterOptions as $option) { $this->writeText("\n"); - $this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth))); + $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); } } } /** * {@inheritdoc} */ - protected function describeCommand(Command $command, array $options = array()) + protected function describeCommand(Command $command, array $options = []) { + $namespace = substr( + $command->getName(), + 0, + (strpos($command->getName(), ':')?:0) + ); + $commandData = $command->getApplication()->getData(); + $commands = $commandData['commands'][$namespace]; + $examples = []; + foreach ($commands as $item) { + if ($item['name'] == $command->getName()) { + $examples = $item['examples']; + break; + } + } + $command->getSynopsis(true); $command->getSynopsis(false); $command->mergeApplicationDefinition(false); $this->writeText($command->trans('commands.list.messages.usage'), $options); - foreach (array_merge(array($command->getSynopsis(true)), $command->getAliases(), $command->getUsages()) as $usage) { - $this->writeText("\n"); + foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $usage) { $this->writeText(' '.$usage, $options); + $this->writeText("\n"); } + if ($examples) { + $this->writeText("\n"); + $this->writeText("Examples:", $options); + foreach ($examples as $example) { + $this->writeText("\n"); + $this->writeText(' '.$example['description']); + $this->writeText("\n"); + $this->writeText(' '.$example['execution']); + $this->writeText("\n"); + } + } + $this->writeText("\n"); $definition = $command->getNativeDefinition(); if ($definition->getOptions() || $definition->getArguments()) { @@ -161,7 +188,7 @@ class TextDescriptor extends Descriptor /** * {@inheritdoc} */ - protected function describeApplication(Application $application, array $options = array()) + protected function describeApplication(Application $application, array $options = []) { $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; $description = new ApplicationDescription($application, $describedNamespace); @@ -184,8 +211,7 @@ class TextDescriptor extends Descriptor $width = $this->getColumnWidth($description->getCommands()) + 4; if ($describedNamespace) { $this->writeText(sprintf($application->trans('commands.list.messages.comment'), $describedNamespace), $options); - } - else { + } else { $this->writeText($application->trans('commands.list.messages.available-commands'), $options); } @@ -208,8 +234,7 @@ class TextDescriptor extends Descriptor $this->writeText(' '.$namespace['id'].'', $options); } foreach ($namespace['commands'] as $name) { - - if (ApplicationDescription::GLOBAL_NAMESPACE == $namespace['id']){ + if (ApplicationDescription::GLOBAL_NAMESPACE == $namespace['id']) { if (!in_array($name, $singleCommands)) { continue; } @@ -217,7 +242,7 @@ class TextDescriptor extends Descriptor $this->writeText("\n"); $alias = ''; - if ($description->getCommand($name)->getAliases()){ + if ($description->getCommand($name)->getAliases()) { $alias = sprintf( '(%s)', implode(',', $description->getCommand($name)->getAliases()) @@ -225,7 +250,8 @@ class TextDescriptor extends Descriptor } $spacingWidth = $width - strlen($name.$alias); $this->writeText( - sprintf(' %s %s %s%s', + sprintf( + ' %s %s %s%s', $name, $alias, str_repeat(' ', $spacingWidth), @@ -241,7 +267,7 @@ class TextDescriptor extends Descriptor /** * {@inheritdoc} */ - private function writeText($content, array $options = array()) + private function writeText($content, array $options = []) { $this->write( isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content, diff --git a/vendor/drupal/console-core/src/EventSubscriber/CallCommandListener.php b/vendor/drupal/console-core/src/EventSubscriber/CallCommandListener.php index aead3164c..fe7c07543 100644 --- a/vendor/drupal/console-core/src/EventSubscriber/CallCommandListener.php +++ b/vendor/drupal/console-core/src/EventSubscriber/CallCommandListener.php @@ -17,6 +17,7 @@ use Drupal\Console\Core\Style\DrupalStyle; /** * Class CallCommandListener + * * @package Drupal\Console\Core\EventSubscriber */ class CallCommandListener implements EventSubscriberInterface @@ -28,6 +29,7 @@ class CallCommandListener implements EventSubscriberInterface /** * CallCommandListener constructor. + * * @param ChainQueue $chainQueue */ public function __construct(ChainQueue $chainQueue) @@ -46,14 +48,14 @@ class CallCommandListener implements EventSubscriberInterface $io = new DrupalStyle($event->getInput(), $event->getOutput()); if (!$command instanceof Command) { - return; + return 0; } $application = $command->getApplication(); $commands = $this->chainQueue->getCommands(); if (!$commands) { - return; + return 0; } foreach ($commands as $chainedCommand) { @@ -69,7 +71,15 @@ class CallCommandListener implements EventSubscriberInterface } $io->text($chainedCommand['name']); - $callCommand->run($input, $io); + $allowFailure = array_key_exists('allow_failure', $chainedCommand)?$chainedCommand['allow_failure']:false; + try { + $callCommand->run($input, $io); + } catch (\Exception $e) { + if (!$allowFailure) { + $io->error($e->getMessage()); + return 1; + } + } } } diff --git a/vendor/drupal/console-core/src/EventSubscriber/DefaultValueEventListener.php b/vendor/drupal/console-core/src/EventSubscriber/DefaultValueEventListener.php index b1c09d2d0..f948962b9 100644 --- a/vendor/drupal/console-core/src/EventSubscriber/DefaultValueEventListener.php +++ b/vendor/drupal/console-core/src/EventSubscriber/DefaultValueEventListener.php @@ -15,6 +15,7 @@ use Drupal\Console\Core\Utils\ConfigurationManager; /** * Class DefaultValueEventListener + * * @package Drupal\Console\Core\EventSubscriber */ class DefaultValueEventListener implements EventSubscriberInterface @@ -36,6 +37,7 @@ class DefaultValueEventListener implements EventSubscriberInterface /** * DefaultValueEventListener constructor. + * * @param ConfigurationManager $configurationManager */ public function __construct( diff --git a/vendor/drupal/console-core/src/EventSubscriber/ShowGeneratedFilesListener.php b/vendor/drupal/console-core/src/EventSubscriber/ShowGeneratedFilesListener.php index b0acc718b..56ffdce89 100644 --- a/vendor/drupal/console-core/src/EventSubscriber/ShowGeneratedFilesListener.php +++ b/vendor/drupal/console-core/src/EventSubscriber/ShowGeneratedFilesListener.php @@ -17,6 +17,7 @@ use Drupal\Console\Core\Utils\ShowFile; /** * Class ShowGeneratedFilesListener + * * @package Drupal\Console\Core\EventSubscriber */ class ShowGeneratedFilesListener implements EventSubscriberInterface @@ -33,6 +34,7 @@ class ShowGeneratedFilesListener implements EventSubscriberInterface /** * ShowGeneratedFilesListener constructor. + * * @param FileQueue $fileQueue * @param ShowFile $showFile */ diff --git a/vendor/drupal/console-core/src/Generator/Generator.php b/vendor/drupal/console-core/src/Generator/Generator.php index 42fc305b9..1f559e6eb 100644 --- a/vendor/drupal/console-core/src/Generator/Generator.php +++ b/vendor/drupal/console-core/src/Generator/Generator.php @@ -12,6 +12,7 @@ use Drupal\Console\Core\Utils\FileQueue; /** * Class Generator + * * @package Drupal\Console\Core\Generator */ abstract class Generator diff --git a/vendor/drupal/console-core/src/Generator/InitGenerator.php b/vendor/drupal/console-core/src/Generator/InitGenerator.php index ff8d3fc38..f3cbf4c7e 100644 --- a/vendor/drupal/console-core/src/Generator/InitGenerator.php +++ b/vendor/drupal/console-core/src/Generator/InitGenerator.php @@ -8,6 +8,7 @@ namespace Drupal\Console\Core\Generator; /** * Class InitGenerator + * * @package Drupal\Console\Core\Generator */ class InitGenerator extends Generator diff --git a/vendor/drupal/console-core/src/Helper/DescriptorHelper.php b/vendor/drupal/console-core/src/Helper/DescriptorHelper.php index 40e7f0cee..a77510f64 100644 --- a/vendor/drupal/console-core/src/Helper/DescriptorHelper.php +++ b/vendor/drupal/console-core/src/Helper/DescriptorHelper.php @@ -22,7 +22,7 @@ class DescriptorHelper extends BaseHelper /** * @var DescriptorInterface[] */ - private $descriptors = array(); + private $descriptors = []; /** * Constructor. */ @@ -47,13 +47,13 @@ class DescriptorHelper extends BaseHelper * * @throws \InvalidArgumentException when the given format is not supported */ - public function describe(OutputInterface $output, $object, array $options = array()) + public function describe(OutputInterface $output, $object, array $options = []) { $options = array_merge( - array( + [ 'raw_text' => false, 'format' => 'txt', - ), $options + ], $options ); if (!isset($this->descriptors[$options['format']])) { throw new \InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format'])); diff --git a/vendor/drupal/console-core/src/Helper/DrupalChoiceQuestionHelper.php b/vendor/drupal/console-core/src/Helper/DrupalChoiceQuestionHelper.php index 788a81d93..8e8edfe9c 100644 --- a/vendor/drupal/console-core/src/Helper/DrupalChoiceQuestionHelper.php +++ b/vendor/drupal/console-core/src/Helper/DrupalChoiceQuestionHelper.php @@ -12,6 +12,7 @@ use Symfony\Component\Console\Question\Question; /** * Class DrupalChoiceQuestionHelper + * * @package Drupal\Console\Core\Helper */ class DrupalChoiceQuestionHelper extends SymfonyQuestionHelper diff --git a/vendor/drupal/console-core/src/Style/DrupalStyle.php b/vendor/drupal/console-core/src/Style/DrupalStyle.php index 636b3e864..c626d216e 100644 --- a/vendor/drupal/console-core/src/Style/DrupalStyle.php +++ b/vendor/drupal/console-core/src/Style/DrupalStyle.php @@ -16,6 +16,7 @@ use Drupal\Console\Core\Helper\DrupalChoiceQuestionHelper; /** * Class DrupalStyle + * * @package Drupal\Console\Core\Style */ class DrupalStyle extends SymfonyStyle @@ -221,31 +222,35 @@ class DrupalStyle extends SymfonyStyle parent::text($message); } - public function successLite($message, $newLine = false) { + public function successLite($message, $newLine = false) + { $message = sprintf('✔ %s', $message); parent::text($message); - if ($newLine){ + if ($newLine) { parent::newLine(); } } - public function errorLite($message, $newLine = false) { + public function errorLite($message, $newLine = false) + { $message = sprintf('✘ %s', $message); parent::text($message); - if ($newLine){ + if ($newLine) { parent::newLine(); } } - public function warningLite($message, $newLine = false) { + public function warningLite($message, $newLine = false) + { $message = sprintf('! %s', $message); parent::text($message); - if ($newLine){ + if ($newLine) { parent::newLine(); } } - public function customLite($message, $prefix = '*', $style = '', $newLine = false) { + public function customLite($message, $prefix = '*', $style = '', $newLine = false) + { if ($style) { $message = sprintf( '<%s>%s %s', @@ -262,7 +267,7 @@ class DrupalStyle extends SymfonyStyle ); } parent::text($message); - if ($newLine){ + if ($newLine) { parent::newLine(); } } diff --git a/vendor/drupal/console-core/src/Utils/ArgvInputReader.php b/vendor/drupal/console-core/src/Utils/ArgvInputReader.php index f5c7c41e3..73fd269e2 100644 --- a/vendor/drupal/console-core/src/Utils/ArgvInputReader.php +++ b/vendor/drupal/console-core/src/Utils/ArgvInputReader.php @@ -151,6 +151,7 @@ class ArgvInputReader $source = $input->getParameterOption(['--source', '-s'], null); $target = $input->getParameterOption(['--target', '-t'], null); $root = $input->getParameterOption(['--root'], null); + $debug = $input->getParameterOption(['--debug'], false); $uri = $input->getParameterOption(['--uri', '-l']) ?: 'default'; if ($uri && !preg_match('/^(http|https):\/\//', $uri)) { $uri = sprintf('http://%s', $uri); @@ -159,6 +160,7 @@ class ArgvInputReader $this->set('command', $input->getFirstArgument()); $this->set('root', $root); $this->set('uri', $uri); + $this->set('debug', $debug); $this->set('source', $source); $this->set('target', $target); } diff --git a/vendor/drupal/console-core/src/Utils/ChainDiscovery.php b/vendor/drupal/console-core/src/Utils/ChainDiscovery.php index 24fc68a06..306fb4538 100644 --- a/vendor/drupal/console-core/src/Utils/ChainDiscovery.php +++ b/vendor/drupal/console-core/src/Utils/ChainDiscovery.php @@ -11,6 +11,7 @@ use Symfony\Component\Yaml\Yaml; /** * Class ChainDiscovery + * * @package Drupal\Console\Core\Utils */ class ChainDiscovery diff --git a/vendor/drupal/console-core/src/Utils/ChainQueue.php b/vendor/drupal/console-core/src/Utils/ChainQueue.php index 77cf63d36..86e9f0567 100644 --- a/vendor/drupal/console-core/src/Utils/ChainQueue.php +++ b/vendor/drupal/console-core/src/Utils/ChainQueue.php @@ -9,6 +9,7 @@ namespace Drupal\Console\Core\Utils; /** * Class ChainQueue + * * @package Drupal\Console\Core\Helper */ class ChainQueue diff --git a/vendor/drupal/console-core/src/Utils/ConfigurationManager.php b/vendor/drupal/console-core/src/Utils/ConfigurationManager.php index 5ab016546..abb2fe836 100644 --- a/vendor/drupal/console-core/src/Utils/ConfigurationManager.php +++ b/vendor/drupal/console-core/src/Utils/ConfigurationManager.php @@ -301,7 +301,8 @@ class ConfigurationManager $this->importConfigurationFile($extendFile); } - public function importConfigurationFile($configFile) { + public function importConfigurationFile($configFile) + { if (is_file($configFile) && file_get_contents($configFile)!='') { $builder = new YamlFileConfigurationBuilder([$configFile]); $this->configuration->import($builder->build()); @@ -338,5 +339,4 @@ class ConfigurationManager return $this->sites; } - } diff --git a/vendor/drupal/console-core/src/Utils/DrupalFinder.php b/vendor/drupal/console-core/src/Utils/DrupalFinder.php new file mode 100644 index 000000000..1619bf9cf --- /dev/null +++ b/vendor/drupal/console-core/src/Utils/DrupalFinder.php @@ -0,0 +1,47 @@ +getComposerRoot(); + $vendorDir = str_replace( + $composerRoot .'/', '', $this->getVendorDir() + ); + if (!defined("DRUPAL_CONSOLE_CORE")) { + define( + "DRUPAL_CONSOLE_CORE", + "/{$vendorDir}/drupal/console-core/" + ); + } + if (!defined("DRUPAL_CONSOLE")) { + define("DRUPAL_CONSOLE", "/{$vendorDir}/drupal/console/"); + } + if (!defined("DRUPAL_CONSOLE_LANGUAGE")) { + define( + "DRUPAL_CONSOLE_LANGUAGE", + "/{$vendorDir}/drupal/console-%s/translations/" + ); + } + + return true; + } + + return false; + } +} diff --git a/vendor/drupal/console-core/src/Utils/FileQueue.php b/vendor/drupal/console-core/src/Utils/FileQueue.php index 1d60da3b0..53fea3261 100644 --- a/vendor/drupal/console-core/src/Utils/FileQueue.php +++ b/vendor/drupal/console-core/src/Utils/FileQueue.php @@ -9,6 +9,7 @@ namespace Drupal\Console\Core\Utils; /** * Class FileQueue + * * @package Drupal\Console\Core\Utils */ class FileQueue diff --git a/vendor/drupal/console-core/src/Utils/NestedArray.php b/vendor/drupal/console-core/src/Utils/NestedArray.php index 5904b8e11..3684d94a0 100644 --- a/vendor/drupal/console-core/src/Utils/NestedArray.php +++ b/vendor/drupal/console-core/src/Utils/NestedArray.php @@ -9,6 +9,7 @@ namespace Drupal\Console\Core\Utils; /** * Class NestedArray + * * @package Drupal\Console\Core\Utils */ class NestedArray @@ -159,7 +160,7 @@ class NestedArray // PHP auto-creates container arrays and NULL entries without error if $ref // is NULL, but throws an error if $ref is set, but not an array. if ($force && isset($ref) && !is_array($ref)) { - $ref = array(); + $ref = []; } $ref = &$ref[$parent]; } @@ -168,6 +169,7 @@ class NestedArray /** * Replace a YAML key maintaining values + * * @param array $array * @param array $parents * @param $new_key @@ -194,7 +196,7 @@ class NestedArray */ public function arrayDiff($array1, $array2, $negate = false, &$statistics) { - $result = array(); + $result = []; foreach ($array1 as $key => $val) { if (isset($array2[$key])) { if (is_array($val) && $array2[$key]) { @@ -233,6 +235,7 @@ class NestedArray /** * Flat a yaml file + * * @param array $array * @param array $flatten_array * @param string $key_flatten @@ -477,7 +480,7 @@ class NestedArray */ public static function mergeDeepArray(array $arrays, $preserve_integer_keys = false) { - $result = array(); + $result = []; foreach ($arrays as $array) { foreach ($array as $key => $value) { // Renumber integer keys as array_merge_recursive() does unless @@ -488,7 +491,7 @@ class NestedArray } // Recurse when both values are arrays. elseif (isset($result[$key]) && is_array($result[$key]) && is_array($value)) { - $result[$key] = self::mergeDeepArray(array($result[$key], $value), $preserve_integer_keys); + $result[$key] = self::mergeDeepArray([$result[$key], $value], $preserve_integer_keys); } // Otherwise, use the latter value, overriding any previous value. else { diff --git a/vendor/drupal/console-core/src/Utils/RequirementChecker.php b/vendor/drupal/console-core/src/Utils/RequirementChecker.php index 16838f25c..24a4b11a2 100644 --- a/vendor/drupal/console-core/src/Utils/RequirementChecker.php +++ b/vendor/drupal/console-core/src/Utils/RequirementChecker.php @@ -6,6 +6,7 @@ use Symfony\Component\Yaml\Parser; /** * Class RequirementChecker + * * @package Drupal\Console\Core\Utils */ class RequirementChecker diff --git a/vendor/drupal/console-core/src/Utils/StringConverter.php b/vendor/drupal/console-core/src/Utils/StringConverter.php index c19ae95c5..c1c71763a 100644 --- a/vendor/drupal/console-core/src/Utils/StringConverter.php +++ b/vendor/drupal/console-core/src/Utils/StringConverter.php @@ -9,6 +9,7 @@ namespace Drupal\Console\Core\Utils; /** * Class StringConverter + * * @package Drupal\Console\Core\Utils */ class StringConverter diff --git a/vendor/drupal/console-core/src/constants.php b/vendor/drupal/console-core/src/constants.php deleted file mode 100644 index d5317f290..000000000 --- a/vendor/drupal/console-core/src/constants.php +++ /dev/null @@ -1,6 +0,0 @@ -=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2017-01-02T20:30:24+00:00" + }, + { + "name": "symfony/yaml", + "version": "v2.8.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "322a8c2dfbca15ad6b1b27e182899f98ec0e0153" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/322a8c2dfbca15ad6b1b27e182899f98ec0e0153", + "reference": "322a8c2dfbca15ad6b1b27e182899f98ec0e0153", + "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": "2017-01-21T16:40:50+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/vendor/drupal/console-extend-plugin/phpqa.yml b/vendor/drupal/console-extend-plugin/phpqa.yml new file mode 100644 index 000000000..0edc3519c --- /dev/null +++ b/vendor/drupal/console-extend-plugin/phpqa.yml @@ -0,0 +1,69 @@ +application: + method: + git: + enabled: true + exception: false + composer: + enabled: true + exception: false + analyzer: + parallel-lint: + enabled: true + exception: true + options: + e: 'php' + exclude: /vendor + arguments: + php-cs-fixer: + enabled: true + exception: false + options: + level: psr2 + arguments: + prefixes: + - fix + postfixes: + phpcbf: + enabled: true + exception: false + options: + standard: PSR2 + severity: 0 + ignore: /vendor + arguments: + - '-n' + phpcs: + enabled: false + exception: false + options: + standard: PSR2 + severity: 0 + ignore: /vendor + arguments: + - '-n' + phpmd: + enabled: false + exception: false + options: + arguments: + prefixes: + postfixes: + - 'text' + - 'cleancode,codesize,unusedcode,naming,controversial,design' + phploc: + enabled: false + exception: false + phpcpd: + enabled: false + exception: false + phpdcd: + enabled: false + exception: false + phpunit: + enabled: true + exception: true + file: + configuration: phpunit.xml.dist + single-execution: true + options: + arguments: diff --git a/vendor/drupal/console-extend-plugin/src/Extender.php b/vendor/drupal/console-extend-plugin/src/Extender.php index 5685fea13..84e8a4fe6 100644 --- a/vendor/drupal/console-extend-plugin/src/Extender.php +++ b/vendor/drupal/console-extend-plugin/src/Extender.php @@ -5,10 +5,16 @@ namespace Drupal\Console\Composer\Plugin; use Composer\Composer; use Composer\IO\IOInterface; use Composer\Plugin\PluginInterface; -use Composer\Installer\PackageEvent; -use Composer\Installer\PackageEvents; +use Composer\Script\Event; +use Composer\Script\ScriptEvents; use Composer\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Yaml\Yaml; +use Symfony\Component\Finder\Finder; + +// Explicitly require ExtenderManager here. +// When this package is uninstalled, ExtenderManager needs to be available any +// time this class is available. +require_once __DIR__ . '/ExtenderManager.php'; class Extender implements PluginInterface, EventSubscriberInterface { @@ -39,30 +45,42 @@ class Extender implements PluginInterface, EventSubscriberInterface */ public static function getSubscribedEvents() { - return array( - PackageEvents::POST_PACKAGE_INSTALL => "processPackages", - PackageEvents::POST_PACKAGE_UPDATE => "processPackages", - PackageEvents::POST_PACKAGE_UNINSTALL => "processPackages", - ); + return [ + ScriptEvents::POST_INSTALL_CMD => "processPackages", + ScriptEvents::POST_UPDATE_CMD => "processPackages", + ]; } /** - * @param PackageEvent $event + * @param Event $event * @throws \Exception */ - public function processPackages(PackageEvent $event) + public function processPackages(Event $event) { $extenderManager = new ExtenderManager(); - $directory = realpath(__DIR__.'/../../../../'); - $extenderManager->processProjectPackages($directory); - - if (is_dir($directory.'/vendor/drupal/console')) { - $directory = $directory.'/vendor/drupal/console'; - } else { - $configFile = $directory.'/console.config.yml'; - $servicesFile = $directory.'/console.services.yml'; - $extenderManager->addConfigFile($configFile); - $extenderManager->addServicesFile($servicesFile); + + $composer = $event->getComposer(); + $installationManager = $composer->getInstallationManager(); + $repositoryManager = $composer->getRepositoryManager(); + $localRepository = $repositoryManager->getLocalRepository(); + + foreach ($localRepository->getPackages() as $package) { + if ($installationManager->isPackageInstalled($localRepository, $package)) { + if ($package->getType() === 'drupal-console-library') { + $extenderManager->addServicesFile($installationManager->getInstallPath($package) . '/console.services.yml'); + $extenderManager->addConfigFile($installationManager->getInstallPath($package) . '/console.config.yml'); + } + } + } + + if ($consolePackage = $localRepository->findPackage('drupal/console', '*')) { + if ($localRepository->hasPackage($consolePackage)) { + $directory = $installationManager->getInstallPath($consolePackage); + } + } + if (empty($directory)) { + // cwd should be the project root. This is the same logic Symfony uses. + $directory = getcwd(); } $configFile = $directory . '/extend.console.config.yml'; @@ -109,5 +127,34 @@ class Extender implements PluginInterface, EventSubscriberInterface ); $this->io->write('Creating services cache file: ' . $servicesUninstallFile); } + + $this->removeCacheFiles(); + } + + protected function removeCacheFiles() + { + if (is_dir(getcwd().'/console/cache/')) { + try { + $finder = new Finder(); + $finder->files() + ->in(getcwd() . '/console/cache/') + ->ignoreUnreadableDirs(); + + foreach ($finder as $file) { + unlink($file->getPathName()); + } + + $finder->directories() + ->in(getcwd() . '/console/cache/') + ->ignoreUnreadableDirs(); + + foreach ($finder as $directory) { + rmdir($directory); + } + + } catch (\InvalidArgumentException $argumentException) { + $this->io->write('Cache files can not be deleted'); + } + } } } diff --git a/vendor/drupal/console-extend-plugin/src/ExtenderManager.php b/vendor/drupal/console-extend-plugin/src/ExtenderManager.php index 928cfe4ba..9792a750f 100644 --- a/vendor/drupal/console-extend-plugin/src/ExtenderManager.php +++ b/vendor/drupal/console-extend-plugin/src/ExtenderManager.php @@ -130,7 +130,8 @@ class ExtenderManager $finder->files() ->name('composer.json') ->contains('drupal-console-library') - ->in($directory); + ->in($directory) + ->ignoreUnreadableDirs(); foreach ($finder as $file) { $this->processComposerFile($file->getPathName()); diff --git a/vendor/drupal/console/.gitignore b/vendor/drupal/console/.gitignore index 940e4f062..850cec01f 100644 --- a/vendor/drupal/console/.gitignore +++ b/vendor/drupal/console/.gitignore @@ -11,6 +11,8 @@ /bin/pdepend /bin/php-cs-fixer /bin/phpmd +/bin/php-parse +/bin/psysh PATCHES.txt # Develop @@ -30,5 +32,4 @@ autoload.local.php /nbproject/ # drupal/console-extend-plugin generated files -extend.console.config.yml -extend.console.services.yml +extend.console.*.yml diff --git a/vendor/drupal/console/.travis.yml b/vendor/drupal/console/.travis.yml index b68f71021..c37288a28 100644 --- a/vendor/drupal/console/.travis.yml +++ b/vendor/drupal/console/.travis.yml @@ -5,14 +5,16 @@ language: php php: - 5.5.9 - 5.6 - - 7 + - 7.0 + - 7.1 - hhvm matrix: fast_finish: true allow_failures: - php: hhvm - - php: 7 + - php: 7.0 + - php: 7.1 env: global: diff --git a/vendor/drupal/console/README.md b/vendor/drupal/console/README.md index 5851a45c6..d4480197d 100644 --- a/vendor/drupal/console/README.md +++ b/vendor/drupal/console/README.md @@ -5,12 +5,9 @@ - [Drupal Console](#drupal-console) - [Required PHP version](#required-php-version) - [Drupal Console documentation](#documentation) - - [Download as new dependency](#download-as-new-dependency) - - [Download using DrupalComposer](#download-using-drupalcomposer) - - [Update DrupalConsole](#update-drupalconsole) - - [Install Drupal Console Launcher](#install-drupal-console-launcher) - - [Update DrupalConsole Launcher](#update-drupalconsole-launcher) - - [Run Drupal Console](#running-drupal-console) + - [Download Drupal Console](#download) + - [Run Drupal Console](#run) + - [Contributors](#contributors) - [Supporting organizations](#supporting-organizations) @@ -41,53 +38,15 @@ More information about using this project at the [official documentation](http:/ ## Required PHP Version PHP 5.5.9 or higher is required to use the Drupal Console application. -## Download as new dependency -``` -# Change directory to Drupal site -cd /path/to/drupal8.dev - -# Download DrupalConsole -composer require drupal/console:~1.0 \ ---prefer-dist \ ---optimize-autoloader \ ---sort-packages -``` - -## Download using DrupalComposer -``` -composer create-project \ -drupal-composer/drupal-project:8.x-dev \ -drupal8.dev \ ---prefer-dist \ ---no-progress \ ---no-interaction -``` - -## Update DrupalConsole - -``` -composer update drupal/console --with-dependencies -``` +## Download -## Install Drupal Console Launcher -``` -curl https://drupalconsole.com/installer -L -o drupal.phar -mv drupal.phar /usr/local/bin/drupal -chmod +x /usr/local/bin/drupal -``` -NOTE: If you don't have curl you can try -``` -php -r "readfile('https://drupalconsole.com/installer');" > drupal.phar -``` +[Install Drupal Console Using Composer](https://docs.drupalconsole.com/en/getting/composer.html) +[Install Drupal Console Launcher](https://docs.drupalconsole.com/en/getting/launcher.html) -## Update DrupalConsole Launcher  -``` -drupal self-update -``` -> NOTE: `drupal` is the alias name you used when installed the DrupalConsole Launcher. +[Installing Drupal Console on Windows](https://docs.drupalconsole.com/en/getting/windows.html) -## Run Drupal Console +## Run Using the DrupalConsole Launcher ``` drupal @@ -127,14 +86,16 @@ source "$HOME/.console/console.rc" 2>/dev/null ln -s ~/.console/drupal.fish ~/.config/fish/completions/drupal.fish ``` +## Contributors + +[Full list of contributors](https://drupalconsole.com/contributors) + ## Supporting Organizations [![weKnow](https://www.drupal.org/files/weKnow-logo_5.png)](http://weknowinc.com) [![Anexus](https://www.drupal.org/files/anexus-logo.png)](http://www.anexusit.com/) -[![Indava](https://www.drupal.org/files/indava-logo.png)](http://www.indava.com/) - -[![FFW](https://www.drupal.org/files/ffw-logo.png)](https://ffwagency.com) +[All supporting organizations](https://drupalconsole.com/supporting-organizations) > Drupal is a registered trademark of Dries Buytaert. diff --git a/vendor/drupal/console/Test/Generator/ProfileGeneratorTest.php b/vendor/drupal/console/Test/Generator/ProfileGeneratorTest.php index 15735a4b6..c6ea12ddd 100644 --- a/vendor/drupal/console/Test/Generator/ProfileGeneratorTest.php +++ b/vendor/drupal/console/Test/Generator/ProfileGeneratorTest.php @@ -37,6 +37,7 @@ class ProfileGeneratorTest extends GeneratorTest $description, $core, $dependencies, + $themes, $distribution ) { $generator = new ProfileGenerator(); @@ -51,6 +52,7 @@ class ProfileGeneratorTest extends GeneratorTest $description, $core, $dependencies, + $themes, $distribution ); diff --git a/vendor/drupal/console/bin/drupal.php b/vendor/drupal/console/bin/drupal.php index 35c172344..6c5b26be9 100644 --- a/vendor/drupal/console/bin/drupal.php +++ b/vendor/drupal/console/bin/drupal.php @@ -1,10 +1,10 @@ hasParameterOption(['--debug']); - $drupalFinder = new DrupalFinder(); if (!$drupalFinder->locateRoot(getcwd())) { echo ' DrupalConsole must be executed within a Drupal Site.'.PHP_EOL; @@ -43,12 +40,20 @@ if (!$drupalFinder->locateRoot(getcwd())) { exit(1); } -$composerRoot = $drupalFinder->getComposerRoot(); -$drupalRoot = $drupalFinder->getDrupalRoot(); -chdir($drupalRoot); +chdir($drupalFinder->getDrupalRoot()); + +$configurationManager = new ConfigurationManager(); +$configuration = $configurationManager + ->loadConfigurationFromDirectory($drupalFinder->getComposerRoot()); + +$argvInputReader = new ArgvInputReader(); +if ($configuration && $options = $configuration->get('application.options') ?: []) { + $argvInputReader->setOptionsFromConfiguration($options); +} +$argvInputReader->setOptionsAsArgv(); -$drupal = new Drupal($autoload, $composerRoot, $drupalRoot); -$container = $drupal->boot($debug); +$drupal = new Drupal($autoload, $drupalFinder); +$container = $drupal->boot(); if (!$container) { echo ' Something was wrong. Drupal can not be bootstrap.'; @@ -56,14 +61,6 @@ if (!$container) { exit(1); } -$configuration = $container->get('console.configuration_manager') - ->getConfiguration(); - -$argvInputReader = new ArgvInputReader(); -if ($options = $configuration->get('application.options') ?: []) { - $argvInputReader->setOptionsFromConfiguration($options); -} -$argvInputReader->setOptionsAsArgv(); $application = new Application($container); $application->setDefaultCommand('about'); $application->run(); diff --git a/vendor/drupal/console/bin/php-parse b/vendor/drupal/console/bin/php-parse deleted file mode 120000 index 726f6347e..000000000 --- a/vendor/drupal/console/bin/php-parse +++ /dev/null @@ -1 +0,0 @@ -../vendor/nikic/php-parser/bin/php-parse \ No newline at end of file diff --git a/vendor/drupal/console/bin/psysh b/vendor/drupal/console/bin/psysh deleted file mode 120000 index b732dc399..000000000 --- a/vendor/drupal/console/bin/psysh +++ /dev/null @@ -1 +0,0 @@ -../vendor/psy/psysh/bin/psysh \ No newline at end of file diff --git a/vendor/drupal/console/composer.json b/vendor/drupal/console/composer.json index 0e529681c..1179f47a8 100644 --- a/vendor/drupal/console/composer.json +++ b/vendor/drupal/console/composer.json @@ -37,23 +37,24 @@ }, "require": { "php": "^5.5.9 || ^7.0", - "drupal/console-core" : "1.0.0-rc16", - "drupal/console-extend-plugin": "~0", "alchemy/zippy": "0.4.3", - "doctrine/collections":"1.3.0", "composer/installers": "~1.0", + "doctrine/annotations": "1.2.*", + "doctrine/collections": "~1.3", + "drupal/console-core": "1.0.0-rc21", + "drupal/console-extend-plugin": "~0", + "gabordemooij/redbean": "~4.3", + "guzzlehttp/guzzle": "~6.1", + "psy/psysh": "0.6.* || ~0.8", "symfony/css-selector": ">=2.7 <3.0", "symfony/dom-crawler": ">=2.7 <3.3", - "symfony/http-foundation": ">=2.7 <3.0", - "guzzlehttp/guzzle": "~6.1", - "gabordemooij/redbean": "~4.3", - "doctrine/annotations": "1.2.*", "symfony/expression-language": ">=2.7 <3.0", - "psy/psysh": "0.6.* || ~0.8" + "symfony/http-foundation": ">=2.7 <3.0" }, "bin": ["bin/drupal"], "config": { - "bin-dir": "bin/" + "bin-dir": "bin/", + "sort-packages": true }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/vendor/drupal/console/composer.lock b/vendor/drupal/console/composer.lock index 61e751184..2b1c2ae56 100644 --- a/vendor/drupal/console/composer.lock +++ b/vendor/drupal/console/composer.lock @@ -4,7 +4,7 @@ "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": "a60765f5a4f4065da528f6b28607c785", + "content-hash": "119866a8bfb1f845f07e1e4d5de4dd03", "packages": [ { "name": "alchemy/zippy", @@ -571,21 +571,21 @@ }, { "name": "drupal/console-core", - "version": "1.0.0-rc16", + "version": "1.0.0-rc21", "source": { "type": "git", "url": "https://github.com/hechoendrupal/drupal-console-core.git", - "reference": "42690f652b3a61d7d15fe9b785b946f3eb9227bf" + "reference": "a473a27292110e5f50e0ae8df36d38449ce55903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-core/zipball/42690f652b3a61d7d15fe9b785b946f3eb9227bf", - "reference": "42690f652b3a61d7d15fe9b785b946f3eb9227bf", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-core/zipball/a473a27292110e5f50e0ae8df36d38449ce55903", + "reference": "a473a27292110e5f50e0ae8df36d38449ce55903", "shasum": "" }, "require": { "dflydev/dot-access-configuration": "1.0.1", - "drupal/console-en": "1.0.0-rc16", + "drupal/console-en": "1.0.0-rc21", "php": "^5.5.9 || ^7.0", "stecman/symfony-console-completion": "~0.7", "symfony/config": ">=2.7 <3.0", @@ -599,12 +599,11 @@ "symfony/translation": ">=2.7 <3.0", "symfony/yaml": ">=2.7 <3.0", "twig/twig": "^1.23.1", - "webflo/drupal-finder": "0.*" + "webflo/drupal-finder": "^0.3.0" }, "type": "project", "autoload": { "files": [ - "src/constants.php", "src/functions.php" ], "psr-4": { @@ -648,20 +647,20 @@ "drupal", "symfony" ], - "time": "2017-02-09T18:22:32+00:00" + "time": "2017-06-07T15:57:23+00:00" }, { "name": "drupal/console-en", - "version": "1.0.0-rc16", + "version": "1.0.0-rc21", "source": { "type": "git", "url": "https://github.com/hechoendrupal/drupal-console-en.git", - "reference": "32c1e4c31500ba4ccd5e68bd74977fd6258c3e37" + "reference": "b6f563b8760c3b19aad22dd213a9cfba2f2c75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-en/zipball/32c1e4c31500ba4ccd5e68bd74977fd6258c3e37", - "reference": "32c1e4c31500ba4ccd5e68bd74977fd6258c3e37", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-en/zipball/b6f563b8760c3b19aad22dd213a9cfba2f2c75d0", + "reference": "b6f563b8760c3b19aad22dd213a9cfba2f2c75d0", "shasum": "" }, "type": "drupal-console-language", @@ -702,20 +701,20 @@ "drupal", "symfony" ], - "time": "2017-02-09T16:02:27+00:00" + "time": "2017-05-20T23:29:05+00:00" }, { "name": "drupal/console-extend-plugin", - "version": "0.2.0", + "version": "0.6.0", "source": { "type": "git", "url": "https://github.com/hechoendrupal/drupal-console-extend-plugin.git", - "reference": "3c6b873205c6e33f24b33807901d3287a4ff9a02" + "reference": "4e7f57650eefc53eb02c89360bbc1f675c901a73" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hechoendrupal/drupal-console-extend-plugin/zipball/3c6b873205c6e33f24b33807901d3287a4ff9a02", - "reference": "3c6b873205c6e33f24b33807901d3287a4ff9a02", + "url": "https://api.github.com/repos/hechoendrupal/drupal-console-extend-plugin/zipball/4e7f57650eefc53eb02c89360bbc1f675c901a73", + "reference": "4e7f57650eefc53eb02c89360bbc1f675c901a73", "shasum": "" }, "require": { @@ -743,7 +742,7 @@ } ], "description": "Drupal Console Extend Plugin", - "time": "2017-02-09T17:09:50+00:00" + "time": "2017-05-02T14:17:00+00:00" }, { "name": "gabordemooij/redbean", @@ -1354,16 +1353,16 @@ }, { "name": "symfony/config", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "4537f2413348fe271c2c4b09da219ed615d79f9c" + "reference": "0b8541d18507d10204a08384640ff6df3c739ebe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/4537f2413348fe271c2c4b09da219ed615d79f9c", - "reference": "4537f2413348fe271c2c4b09da219ed615d79f9c", + "url": "https://api.github.com/repos/symfony/config/zipball/0b8541d18507d10204a08384640ff6df3c739ebe", + "reference": "0b8541d18507d10204a08384640ff6df3c739ebe", "shasum": "" }, "require": { @@ -1406,25 +1405,25 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:30:24+00:00" + "time": "2017-04-12T14:07:15+00:00" }, { "name": "symfony/console", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912" + "reference": "2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2e18b8903d9c498ba02e1dfa73f64d4894bb6912", - "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912", + "url": "https://api.github.com/repos/symfony/console/zipball/2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e", + "reference": "2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e", "shasum": "" }, "require": { "php": ">=5.3.9", - "symfony/debug": "~2.7,>=2.7.2|~3.0.0", + "symfony/debug": "^2.7.2|~3.0.0", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { @@ -1467,7 +1466,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-01-08T20:43:03+00:00" + "time": "2017-04-26T01:38:53+00:00" }, { "name": "symfony/css-selector", @@ -1524,16 +1523,16 @@ }, { "name": "symfony/debug", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "567681e2c4e5431704e884e4be25a95fd900770f" + "reference": "344f50ce827413b3640bfcb1e37386a67d06ea1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/567681e2c4e5431704e884e4be25a95fd900770f", - "reference": "567681e2c4e5431704e884e4be25a95fd900770f", + "url": "https://api.github.com/repos/symfony/debug/zipball/344f50ce827413b3640bfcb1e37386a67d06ea1f", + "reference": "344f50ce827413b3640bfcb1e37386a67d06ea1f", "shasum": "" }, "require": { @@ -1545,7 +1544,7 @@ }, "require-dev": { "symfony/class-loader": "~2.2|~3.0.0", - "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0" + "symfony/http-kernel": "~2.3.24|~2.5.9|^2.6.2|~3.0.0" }, "type": "library", "extra": { @@ -1577,20 +1576,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:30:24+00:00" + "time": "2017-04-19T19:56:30+00:00" }, { "name": "symfony/dependency-injection", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "b75356611675364607d697f314850d9d870a84aa" + "reference": "e1c722dfe4dd04453aeb6b7a6deefb400c878394" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b75356611675364607d697f314850d9d870a84aa", - "reference": "b75356611675364607d697f314850d9d870a84aa", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e1c722dfe4dd04453aeb6b7a6deefb400c878394", + "reference": "e1c722dfe4dd04453aeb6b7a6deefb400c878394", "shasum": "" }, "require": { @@ -1640,7 +1639,7 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2017-01-10T14:27:01+00:00" + "time": "2017-04-26T01:38:53+00:00" }, { "name": "symfony/dom-crawler", @@ -1700,16 +1699,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "74877977f90fb9c3e46378d5764217c55f32df34" + "reference": "7fc8e2b4118ff316550596357325dfd92a51f531" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74877977f90fb9c3e46378d5764217c55f32df34", - "reference": "74877977f90fb9c3e46378d5764217c55f32df34", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7fc8e2b4118ff316550596357325dfd92a51f531", + "reference": "7fc8e2b4118ff316550596357325dfd92a51f531", "shasum": "" }, "require": { @@ -1717,7 +1716,7 @@ }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5|~3.0.0", + "symfony/config": "^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" @@ -1756,7 +1755,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:30:24+00:00" + "time": "2017-04-26T16:56:54+00:00" }, { "name": "symfony/expression-language", @@ -1809,16 +1808,16 @@ }, { "name": "symfony/filesystem", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "5b77d49ab76e5b12743b359ef4b4a712e6f5360d" + "reference": "dc40154e26a0116995e4f2f0c71cb9c2fe0775a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/5b77d49ab76e5b12743b359ef4b4a712e6f5360d", - "reference": "5b77d49ab76e5b12743b359ef4b4a712e6f5360d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/dc40154e26a0116995e4f2f0c71cb9c2fe0775a3", + "reference": "dc40154e26a0116995e4f2f0c71cb9c2fe0775a3", "shasum": "" }, "require": { @@ -1854,20 +1853,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2017-01-08T20:43:03+00:00" + "time": "2017-04-12T14:07:15+00:00" }, { "name": "symfony/finder", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "355fccac526522dc5fca8ecf0e62749a149f3b8b" + "reference": "16d55394b31547e4a8494551b85c9b9915545347" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/355fccac526522dc5fca8ecf0e62749a149f3b8b", - "reference": "355fccac526522dc5fca8ecf0e62749a149f3b8b", + "url": "https://api.github.com/repos/symfony/finder/zipball/16d55394b31547e4a8494551b85c9b9915545347", + "reference": "16d55394b31547e4a8494551b85c9b9915545347", "shasum": "" }, "require": { @@ -1903,7 +1902,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:30:24+00:00" + "time": "2017-04-12T14:07:15+00:00" }, { "name": "symfony/http-foundation", @@ -2135,16 +2134,16 @@ }, { "name": "symfony/process", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231" + "reference": "aff35fb3dee799c84a7313c576b72208b046ef8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ebb3c2abe0940a703f08e0cbe373f62d97d40231", - "reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231", + "url": "https://api.github.com/repos/symfony/process/zipball/aff35fb3dee799c84a7313c576b72208b046ef8d", + "reference": "aff35fb3dee799c84a7313c576b72208b046ef8d", "shasum": "" }, "require": { @@ -2180,20 +2179,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:30:24+00:00" + "time": "2017-04-12T14:07:15+00:00" }, { "name": "symfony/translation", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "b4ac4a393f6970cc157fba17be537380de396a86" + "reference": "32b7c0bffc07772cf1a902e3464ef77117fa07c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/b4ac4a393f6970cc157fba17be537380de396a86", - "reference": "b4ac4a393f6970cc157fba17be537380de396a86", + "url": "https://api.github.com/repos/symfony/translation/zipball/32b7c0bffc07772cf1a902e3464ef77117fa07c7", + "reference": "32b7c0bffc07772cf1a902e3464ef77117fa07c7", "shasum": "" }, "require": { @@ -2206,7 +2205,7 @@ "require-dev": { "psr/log": "~1.0", "symfony/config": "~2.8", - "symfony/intl": "~2.4|~3.0.0", + "symfony/intl": "~2.7.25|^2.8.18|~3.2.5", "symfony/yaml": "~2.2|~3.0.0" }, "suggest": { @@ -2244,7 +2243,7 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:30:24+00:00" + "time": "2017-04-12T14:07:15+00:00" }, { "name": "symfony/var-dumper", @@ -2311,16 +2310,16 @@ }, { "name": "symfony/yaml", - "version": "v2.8.16", + "version": "v2.8.20", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2" + "reference": "93ccdde79f4b079c7558da4656a3cb1c50c68e02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2", - "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2", + "url": "https://api.github.com/repos/symfony/yaml/zipball/93ccdde79f4b079c7558da4656a3cb1c50c68e02", + "reference": "93ccdde79f4b079c7558da4656a3cb1c50c68e02", "shasum": "" }, "require": { @@ -2356,33 +2355,34 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-01-03T13:49:52+00:00" + "time": "2017-05-01T14:31:55+00:00" }, { "name": "twig/twig", - "version": "v1.31.0", + "version": "v1.33.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7" + "reference": "dd6ca96227917e1e85b41c7c3cc6507b411e0927" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/ddc9e3e20ee9c0b6908f401ac8353635b750eca7", - "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/dd6ca96227917e1e85b41c7c3cc6507b411e0927", + "reference": "dd6ca96227917e1e85b41c7c3cc6507b411e0927", "shasum": "" }, "require": { "php": ">=5.2.7" }, "require-dev": { + "psr/container": "^1.0", "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~3.2" + "symfony/phpunit-bridge": "~3.3@dev" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.31-dev" + "dev-master": "1.33-dev" } }, "autoload": { @@ -2417,20 +2417,20 @@ "keywords": [ "templating" ], - "time": "2017-01-11T19:36:15+00:00" + "time": "2017-04-20T17:39:48+00:00" }, { "name": "webflo/drupal-finder", - "version": "0.2.1", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/webflo/drupal-finder.git", - "reference": "4bd98f7e7b1d30e284e55f51d5d0c8712f676348" + "reference": "6ef150707aad1755d91f9b0d2108bcc16661e76b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/4bd98f7e7b1d30e284e55f51d5d0c8712f676348", - "reference": "4bd98f7e7b1d30e284e55f51d5d0c8712f676348", + "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/6ef150707aad1755d91f9b0d2108bcc16661e76b", + "reference": "6ef150707aad1755d91f9b0d2108bcc16661e76b", "shasum": "" }, "require-dev": { @@ -2454,7 +2454,7 @@ } ], "description": "Helper class to locate a Drupal installation from a given path.", - "time": "2016-11-28T18:50:45+00:00" + "time": "2017-05-04T08:54:02+00:00" } ], "packages-dev": [], diff --git a/vendor/drupal/console/config/services/drupal-console/config.yml b/vendor/drupal/console/config/services/drupal-console/config.yml index f0156a685..1bd38a653 100644 --- a/vendor/drupal/console/config/services/drupal-console/config.yml +++ b/vendor/drupal/console/config/services/drupal-console/config.yml @@ -21,7 +21,7 @@ services: - { name: drupal.command } console.config_export: class: Drupal\Console\Command\Config\ExportCommand - arguments: ['@config.manager'] + arguments: ['@config.manager', '@config.storage'] tags: - { name: drupal.command } console.config_export_content_type: @@ -31,7 +31,7 @@ services: - { name: drupal.command } console.config_export_single: class: Drupal\Console\Command\Config\ExportSingleCommand - arguments: ['@entity_type.manager', '@config.storage'] + arguments: ['@entity_type.manager', '@config.storage', '@console.extension_manager'] tags: - { name: drupal.command } console.config_export_view: diff --git a/vendor/drupal/console/config/services/drupal-console/feature.yml b/vendor/drupal/console/config/services/drupal-console/feature.yml index 9351c3b5c..b102fbf8a 100644 --- a/vendor/drupal/console/config/services/drupal-console/feature.yml +++ b/vendor/drupal/console/config/services/drupal-console/feature.yml @@ -1,9 +1,9 @@ services: - feature_debug: + console.feature_debug: class: Drupal\Console\Command\Features\DebugCommand tags: - { name: drupal.command } - feature_import: + console.feature_import: class: Drupal\Console\Command\Features\ImportCommand tags: - { name: drupal.command } diff --git a/vendor/drupal/console/config/services/drupal-console/generate.yml b/vendor/drupal/console/config/services/drupal-console/generate.yml index f5894a994..499a63246 100644 --- a/vendor/drupal/console/config/services/drupal-console/generate.yml +++ b/vendor/drupal/console/config/services/drupal-console/generate.yml @@ -1,7 +1,7 @@ services: console.generate_module: class: Drupal\Console\Command\Generate\ModuleCommand - arguments: ['@console.module_generator', '@console.validator', '@app.root', '@console.string_converter', '@console.drupal_api', '@http_client', '@console.site'] + arguments: ['@console.module_generator', '@console.validator', '@app.root', '@console.string_converter', '@console.drupal_api'] tags: - { name: drupal.command } console.generate_modulefile: @@ -141,7 +141,7 @@ services: - { name: drupal.command } console.generate_profile: class: Drupal\Console\Command\Generate\ProfileCommand - arguments: ['@console.extension_manager', '@console.profile_generator', '@console.string_converter', '@console.validator', '@app.root', '@console.site', '@http_client'] + arguments: ['@console.extension_manager', '@console.profile_generator', '@console.string_converter', '@console.validator', '@app.root'] tags: - { name: drupal.command } console.generate_route_subscriber: @@ -176,7 +176,7 @@ services: - { name: drupal.command } console.generate_command: class: Drupal\Console\Command\Generate\CommandCommand - arguments: ['@console.command_generator', '@console.extension_manager', '@console.validator', '@console.string_converter' ] + arguments: ['@console.command_generator', '@console.extension_manager', '@console.validator', '@console.string_converter', '@console.site'] tags: - { name: drupal.command } console.generate_ckeditorbutton: diff --git a/vendor/drupal/console/config/services/drupal-console/locale.yml b/vendor/drupal/console/config/services/drupal-console/locale.yml index c88f66310..a498b84e9 100644 --- a/vendor/drupal/console/config/services/drupal-console/locale.yml +++ b/vendor/drupal/console/config/services/drupal-console/locale.yml @@ -1,15 +1,15 @@ services: - translation_status: + console.translation_status: class: Drupal\Console\Command\Locale\TranslationStatusCommand arguments: ['@console.site', '@console.extension_manager'] tags: - { name: drupal.command } - language_delete: + console.language_delete: class: Drupal\Console\Command\Locale\LanguageDeleteCommand arguments: ['@console.site', '@entity_type.manager', '@module_handler'] tags: - { name: drupal.command } - language_add: + console.language_add: class: Drupal\Console\Command\Locale\LanguageAddCommand arguments: ['@console.site', '@module_handler'] tags: diff --git a/vendor/drupal/console/config/services/drupal-console/module.yml b/vendor/drupal/console/config/services/drupal-console/module.yml index 574e82970..8c79ef33c 100644 --- a/vendor/drupal/console/config/services/drupal-console/module.yml +++ b/vendor/drupal/console/config/services/drupal-console/module.yml @@ -1,36 +1,35 @@ services: - module_debug: + console.module_debug: class: Drupal\Console\Command\Module\DebugCommand arguments: ['@console.configuration_manager', '@console.site', '@http_client'] tags: - { name: drupal.command } - module_dependency_install: + console.module_dependency_install: class: Drupal\Console\Command\Module\InstallDependencyCommand arguments: ['@console.site', '@console.validator', '@module_installer', '@console.chain_queue'] tags: - { name: drupal.command } - - module_download: + console.module_download: class: Drupal\Console\Command\Module\DownloadCommand arguments: ['@console.drupal_api', '@http_client', '@app.root', '@console.extension_manager', '@console.validator', '@console.site', '@console.configuration_manager', '@console.shell_process', '@console.root'] tags: - { name: drupal.command } - module_install: + console.module_install: class: Drupal\Console\Command\Module\InstallCommand arguments: ['@console.site', '@console.validator', '@module_installer', '@console.drupal_api', '@console.extension_manager', '@app.root', '@console.chain_queue'] tags: - { name: drupal.command } - module_path: + console.module_path: class: Drupal\Console\Command\Module\PathCommand arguments: ['@console.extension_manager'] tags: - { name: drupal.command } - module_uninstall: + console.module_uninstall: class: Drupal\Console\Command\Module\UninstallCommand - arguments: ['@console.site','@module_installer', '@console.chain_queue', '@config.factory'] + arguments: ['@console.site','@module_installer', '@console.chain_queue', '@config.factory', '@console.extension_manager'] tags: - { name: drupal.command } - module_update: + console.module_update: class: Drupal\Console\Command\Module\UpdateCommand arguments: ['@console.shell_process', '@console.root'] tags: diff --git a/vendor/drupal/console/config/services/drupal-console/router.yml b/vendor/drupal/console/config/services/drupal-console/router.yml index b79bf43f1..62304e501 100644 --- a/vendor/drupal/console/config/services/drupal-console/router.yml +++ b/vendor/drupal/console/config/services/drupal-console/router.yml @@ -1,5 +1,5 @@ services: - router_debug: + console.router_debug: class: Drupal\Console\Command\Router\DebugCommand arguments: ['@router.route_provider'] tags: diff --git a/vendor/drupal/console/config/services/drupal-console/site.yml b/vendor/drupal/console/config/services/drupal-console/site.yml index fa790d922..17ad4e7a6 100644 --- a/vendor/drupal/console/config/services/drupal-console/site.yml +++ b/vendor/drupal/console/config/services/drupal-console/site.yml @@ -9,11 +9,11 @@ services: arguments: ['@state', '@console.chain_queue'] tags: - { name: drupal.command } -# console.site_mode: -# class: Drupal\Console\Command\Site\ModeCommand -# arguments: ['@config.factory', '@console.configuration_manager', '@app.root', '@console.chain_queue'] -# tags: -# - { name: drupal.command } + console.site_mode: + class: Drupal\Console\Command\Site\ModeCommand + arguments: ['@config.factory', '@console.configuration_manager', '@app.root', '@console.chain_queue'] + tags: + - { name: drupal.command } console.site_statistics: class: Drupal\Console\Command\Site\StatisticsCommand arguments: ['@console.drupal_api', '@entity.query', '@console.extension_manager', '@module_handler'] diff --git a/vendor/drupal/console/config/services/drupal-console/theme.yml b/vendor/drupal/console/config/services/drupal-console/theme.yml index 9306e8844..abe36c413 100644 --- a/vendor/drupal/console/config/services/drupal-console/theme.yml +++ b/vendor/drupal/console/config/services/drupal-console/theme.yml @@ -1,25 +1,25 @@ services: - theme_debug: + console.theme_debug: class: Drupal\Console\Command\Theme\DebugCommand arguments: ['@config.factory', '@theme_handler'] tags: - { name: drupal.command } - theme_download: + console.theme_download: class: Drupal\Console\Command\Theme\DownloadCommand arguments: ['@console.drupal_api', '@http_client', '@app.root'] tags: - { name: drupal.command } - theme_install: + console.theme_install: class: Drupal\Console\Command\Theme\InstallCommand arguments: ['@config.factory', '@theme_handler', '@console.chain_queue'] tags: - { name: drupal.command } - theme_path: + console.theme_path: class: Drupal\Console\Command\Theme\PathCommand arguments: ['@console.extension_manager'] tags: - { name: drupal.command } - theme_uninstall: + console.theme_uninstall: class: Drupal\Console\Command\Theme\UninstallCommand arguments: ['@config.factory', '@theme_handler', '@console.chain_queue'] tags: diff --git a/vendor/drupal/console/config/services/drupal-core/migrate.yml b/vendor/drupal/console/config/services/drupal-core/migrate.yml index 42d5746bb..feae3909a 100644 --- a/vendor/drupal/console/config/services/drupal-core/migrate.yml +++ b/vendor/drupal/console/config/services/drupal-core/migrate.yml @@ -1,20 +1,20 @@ services: - migrate_rollback: + console.migrate_rollback: class: Drupal\Console\Command\Migrate\RollBackCommand arguments: ['@plugin.manager.migration'] tags: - { name: drupal.command } - migrate_execute: + console.migrate_execute: class: Drupal\Console\Command\Migrate\ExecuteCommand arguments: ['@plugin.manager.migration'] tags: - { name: drupal.command } - migrate_debug: + console.migrate_debug: class: Drupal\Console\Command\Migrate\DebugCommand arguments: ['@plugin.manager.migration'] tags: - { name: drupal.command } - migrate_setup: + console.migrate_setup: class: Drupal\Console\Command\Migrate\SetupCommand arguments: ['@state', '@plugin.manager.migration'] tags: diff --git a/vendor/drupal/console/config/services/drupal-core/rest.yml b/vendor/drupal/console/config/services/drupal-core/rest.yml index a5446b6ac..8a5935470 100644 --- a/vendor/drupal/console/config/services/drupal-core/rest.yml +++ b/vendor/drupal/console/config/services/drupal-core/rest.yml @@ -1,15 +1,15 @@ services: - rest_debug: + console.rest_debug: class: Drupal\Console\Command\Rest\DebugCommand arguments: ['@plugin.manager.rest'] tags: - { name: drupal.command } - rest_disable: + console.rest_disable: class: Drupal\Console\Command\Rest\DisableCommand arguments: ['@config.factory', '@plugin.manager.rest'] tags: - { name: drupal.command } - rest_enable: + console.rest_enable: class: Drupal\Console\Command\Rest\EnableCommand arguments: ['@plugin.manager.rest', '@authentication_collector', '@config.factory', '%serializer.formats%', '@entity.manager'] tags: diff --git a/vendor/drupal/console/config/services/drupal-core/simpletest.yml b/vendor/drupal/console/config/services/drupal-core/simpletest.yml index 20d3f34b8..862b856a6 100644 --- a/vendor/drupal/console/config/services/drupal-core/simpletest.yml +++ b/vendor/drupal/console/config/services/drupal-core/simpletest.yml @@ -1,10 +1,10 @@ services: - test_debug: + console.test_debug: class: Drupal\Console\Command\Test\DebugCommand arguments: ['@test_discovery'] tags: - { name: drupal.command } - test_run: + console.test_run: class: Drupal\Console\Command\Test\RunCommand arguments: ['@app.root', '@test_discovery', '@module_handler', '@date.formatter'] tags: diff --git a/vendor/drupal/console/services.yml b/vendor/drupal/console/services.yml index 32e03500b..e71584db1 100644 --- a/vendor/drupal/console/services.yml +++ b/vendor/drupal/console/services.yml @@ -5,7 +5,7 @@ services: class: RedBeanPHP\R console.validator: class: Drupal\Console\Utils\Validator - arguments: ['@console.extension_manager'] + arguments: ['@console.extension_manager', '@console.translator_manager'] console.drupal_api: class: Drupal\Console\Utils\DrupalApi arguments: ['@app.root', '@entity_type.manager', '@http_client'] diff --git a/vendor/drupal/console/src/Annotations/DrupalCommand.php b/vendor/drupal/console/src/Annotations/DrupalCommand.php index 5163c53c3..32d472436 100644 --- a/vendor/drupal/console/src/Annotations/DrupalCommand.php +++ b/vendor/drupal/console/src/Annotations/DrupalCommand.php @@ -12,7 +12,6 @@ use Doctrine\Common\Annotations\Annotation; * @Annotation * @Target("CLASS") */ - class DrupalCommand { /** diff --git a/vendor/drupal/console/src/Application.php b/vendor/drupal/console/src/Application.php index 5085bb5d1..fb22aa39a 100644 --- a/vendor/drupal/console/src/Application.php +++ b/vendor/drupal/console/src/Application.php @@ -25,13 +25,35 @@ class Application extends BaseApplication /** * @var string */ - const VERSION = '1.0.0-rc16'; + const VERSION = '1.0.0-rc21'; public function __construct(ContainerInterface $container) { parent::__construct($container, $this::NAME, $this::VERSION); } + /** + * Returns the long version of the application. + * + * @return string The long application version + */ + public function getLongVersion() + { + $output = ''; + + if ('UNKNOWN' !== $this->getName()) { + if ('UNKNOWN' !== $this->getVersion()) { + $output .= sprintf('%s version %s', $this->getName(), $this->getVersion()); + } else { + $output .= sprintf('%s', $this->getName()); + } + } else { + $output .= 'Console Tool'; + } + + return $output; + } + /** * {@inheritdoc} */ diff --git a/vendor/drupal/console/src/Bootstrap/AddServicesCompilerPass.php b/vendor/drupal/console/src/Bootstrap/AddServicesCompilerPass.php index e86f85d27..1cc60db48 100644 --- a/vendor/drupal/console/src/Bootstrap/AddServicesCompilerPass.php +++ b/vendor/drupal/console/src/Bootstrap/AddServicesCompilerPass.php @@ -2,6 +2,7 @@ namespace Drupal\Console\Bootstrap; +use Drupal\Console\Utils\Site; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -56,23 +57,32 @@ class AddServicesCompilerPass implements CompilerPassInterface new FileLocator($this->root) ); - $loader->load($this->root. DRUPAL_CONSOLE_CORE . 'services.yml'); - $loader->load($this->root. DRUPAL_CONSOLE . 'services-drupal-install.yml'); - $loader->load($this->root. DRUPAL_CONSOLE . 'services.yml'); + $servicesFiles = [ + $this->root. DRUPAL_CONSOLE_CORE . 'services.yml', + $this->root. DRUPAL_CONSOLE . 'uninstall.services.yml', + $this->root. DRUPAL_CONSOLE . 'services.yml', +// $this->root. DRUPAL_CONSOLE . 'extend.console.uninstall.services.yml', + ]; + + foreach ($servicesFiles as $servicesFile) { + if (file_exists($servicesFile)) { + $loader->load($servicesFile); + } + } $container->get('console.configuration_manager') ->loadConfiguration($this->root) ->getConfiguration(); - $cacheDirectory = $container->get('console.site')->getCacheDirectory(); - $consoleServicesFile = $cacheDirectory.'/console.services.yml'; + /** + * @var Site $site + */ + $site = $container->get('console.site'); - if (!$this->rebuild && file_exists($consoleServicesFile)) { - $loader->load($consoleServicesFile); + if (!$this->rebuild && $site->cachedServicesFileExists()) { + $loader->load($site->cachedServicesFile()); } else { - if (file_exists($consoleServicesFile)) { - unlink($consoleServicesFile); - } + $site->removeCachedServicesFile(); $finder = new Finder(); $finder->files() ->name('*.yml') @@ -149,15 +159,16 @@ class AddServicesCompilerPass implements CompilerPassInterface } } - if ($servicesData && is_writable($cacheDirectory)) { + if ($servicesData && is_writable($site->getCacheDirectory())) { file_put_contents( - $consoleServicesFile, + $site->cachedServicesFile(), Yaml::dump($servicesData, 4, 2) ); } } - $consoleExtendServicesFile = $this->root. DRUPAL_CONSOLE .'/extend.console.services.yml'; + $consoleExtendServicesFile = $this->root . DRUPAL_CONSOLE . '/extend.console.services.yml'; + if (file_exists($consoleExtendServicesFile)) { $loader->load($consoleExtendServicesFile); } diff --git a/vendor/drupal/console/src/Bootstrap/Drupal.php b/vendor/drupal/console/src/Bootstrap/Drupal.php index b17767562..48ba2fe58 100644 --- a/vendor/drupal/console/src/Bootstrap/Drupal.php +++ b/vendor/drupal/console/src/Bootstrap/Drupal.php @@ -10,37 +10,52 @@ use Drupal\Console\Core\Style\DrupalStyle; use Drupal\Console\Core\Utils\ArgvInputReader; use Drupal\Console\Core\Bootstrap\DrupalConsoleCore; use Drupal\Console\Utils\ExtendExtensionManager; +use Drupal\Console\Core\Utils\DrupalFinder; class Drupal { protected $autoload; - protected $root; - protected $appRoot; + + /** + * @var DrupalFinder + */ + protected $drupalFinder; /** * Drupal constructor. * * @param $autoload - * @param $root - * @param $appRoot + * @param $drupalFinder */ - public function __construct($autoload, $root, $appRoot) + public function __construct($autoload, DrupalFinder $drupalFinder) { $this->autoload = $autoload; - $this->root = $root; - $this->appRoot = $appRoot; + $this->drupalFinder = $drupalFinder; } - public function boot($debug) + public function boot() { $output = new ConsoleOutput(); $input = new ArrayInput([]); $io = new DrupalStyle($input, $output); $argvInputReader = new ArgvInputReader(); + $command = $argvInputReader->get('command'); + $uri = $argvInputReader->get('uri'); + $debug = $argvInputReader->get('debug', false); + + if ($debug) { + $binaryPath = $this->drupalFinder->getVendorDir() . + '/drupal/console/bin/drupal'; + $io->writeln("Per-Site path: $binaryPath"); + $io->newLine(); + } if (!class_exists('Drupal\Core\DrupalKernel')) { - $io->error('Class Drupal\Core\DrupalKernel do not exists.'); - $drupal = new DrupalConsoleCore($this->root, $this->appRoot); + $io->error('Class Drupal\Core\DrupalKernel does not exist.'); + $drupal = new DrupalConsoleCore( + $this->drupalFinder->getComposerRoot(), + $this->drupalFinder->getDrupalRoot() + ); return $drupal->boot(); } @@ -57,8 +72,7 @@ class Drupal $_SERVER['DEVDESKTOP_DRUPAL_SETTINGS_DIR'] = $devDesktopSettingsDir; } } - $argvInputReader = new ArgvInputReader(); - $command = $argvInputReader->get('command'); + $rebuildServicesFile = false; if ($command=='cache:rebuild' || $command=='cr') { $rebuildServicesFile = true; @@ -67,27 +81,30 @@ class Drupal if ($debug) { $io->writeln('➤ Creating request'); } - $uri = $argvInputReader->get('uri'); - if ($uri && $uri != 'http://default') { - if (substr($uri, -1) != '/') { - $uri .= '/'; - } - $uri .= 'index.php'; - $request = Request::create($uri, 'GET', [], [], [], ['SCRIPT_NAME' => $this->appRoot . '/index.php']); - } else { - $request = Request::createFromGlobals(); - } + + $_SERVER['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST); + $_SERVER['SERVER_PORT'] = null; + $_SERVER['REQUEST_URI'] = '/'; + $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; + $_SERVER['REQUEST_METHOD'] = 'GET'; + $_SERVER['SERVER_SOFTWARE'] = null; + $_SERVER['HTTP_USER_AGENT'] = null; + $_SERVER['PHP_SELF'] = $_SERVER['REQUEST_URI'] . 'index.php'; + $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF']; + $_SERVER['SCRIPT_FILENAME'] = $this->drupalFinder->getDrupalRoot() . '/index.php'; + $request = Request::createFromGlobals(); if ($debug) { $io->writeln("\r\033[K\033[1A\r✔"); $io->writeln('➤ Creating Drupal kernel'); } + $drupalKernel = DrupalKernel::createFromRequest( $request, $this->autoload, 'prod', false, - $this->appRoot + $this->drupalFinder->getDrupalRoot() ); if ($debug) { $io->writeln("\r\033[K\033[1A\r✔"); @@ -96,13 +113,14 @@ class Drupal $drupalKernel->addServiceModifier( new DrupalServiceModifier( - $this->root, - $this->appRoot, + $this->drupalFinder->getComposerRoot(), + $this->drupalFinder->getDrupalRoot(), 'drupal.command', 'drupal.generator', $rebuildServicesFile ) ); + if ($debug) { $io->writeln("\r\033[K\033[1A\r✔"); $io->writeln('➤ Rebuilding container'); @@ -116,7 +134,10 @@ class Drupal } $container = $drupalKernel->getContainer(); - $container->set('console.root', $this->root); + $container->set( + 'console.root', + $this->drupalFinder->getComposerRoot() + ); AnnotationRegistry::registerLoader([$this->autoload, "loadClass"]); @@ -126,10 +147,10 @@ class Drupal $container->get('console.translator_manager') ->loadCoreLanguage( $configuration->get('application.language'), - $this->root + $this->drupalFinder->getComposerRoot() ); - $consoleExtendConfigFile = $this->root . DRUPAL_CONSOLE .'/extend.console.config.yml'; + $consoleExtendConfigFile = $this->drupalFinder->getComposerRoot() . DRUPAL_CONSOLE .'/extend.console.config.yml'; if (file_exists($consoleExtendConfigFile)) { $container->get('console.configuration_manager') ->importConfigurationFile($consoleExtendConfigFile); @@ -138,19 +159,23 @@ class Drupal $container->get('console.renderer') ->setSkeletonDirs( [ - $this->root.DRUPAL_CONSOLE.'/templates/', - $this->root.DRUPAL_CONSOLE_CORE.'/templates/' + $this->drupalFinder->getComposerRoot().DRUPAL_CONSOLE.'/templates/', + $this->drupalFinder->getComposerRoot().DRUPAL_CONSOLE_CORE.'/templates/' ] ); return $container; } catch (\Exception $e) { - if ($argvInputReader->get('command') == 'list') { + if ($command == 'list') { $io->error($e->getMessage()); } - $drupal = new DrupalConsoleCore($this->root, $this->appRoot); + $drupal = new DrupalConsoleCore( + $this->drupalFinder->getComposerRoot(), + $this->drupalFinder->getDrupalRoot() + ); $container = $drupal->boot(); $container->set('class_loader', $this->autoload); + return $container; } } diff --git a/vendor/drupal/console/src/Command/Breakpoints/DebugCommand.php b/vendor/drupal/console/src/Command/Breakpoints/DebugCommand.php index fd23dd52d..bbdbe86bd 100644 --- a/vendor/drupal/console/src/Command/Breakpoints/DebugCommand.php +++ b/vendor/drupal/console/src/Command/Breakpoints/DebugCommand.php @@ -106,12 +106,7 @@ class DebugCommand extends Command array_values($this->breakpointManager->getGroupProviders($group)) ); - if ($typeExtension == 'theme') { - $projectPath = drupal_get_path('theme', $group); - } - if ($typeExtension == 'module') { - $projectPath = drupal_get_path('module', $group); - } + $projectPath = drupal_get_path($typeExtension, $group); $extensionFile = sprintf( '%s/%s/%s.breakpoints.yml', diff --git a/vendor/drupal/console/src/Command/Cache/RebuildCommand.php b/vendor/drupal/console/src/Command/Cache/RebuildCommand.php index c3a98ab3d..3ad5f0b98 100644 --- a/vendor/drupal/console/src/Command/Cache/RebuildCommand.php +++ b/vendor/drupal/console/src/Command/Cache/RebuildCommand.php @@ -84,7 +84,7 @@ class RebuildCommand extends Command protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); - $cache = $input->getArgument('cache'); + $cache = $input->getArgument('cache')?:'all'; $this->site->loadLegacyFile('/core/includes/utility.inc'); if ($cache && !$this->drupalApi->isValidCache($cache)) { diff --git a/vendor/drupal/console/src/Command/Config/EditCommand.php b/vendor/drupal/console/src/Command/Config/EditCommand.php index 5f0c1bebe..d142d7111 100644 --- a/vendor/drupal/console/src/Command/Config/EditCommand.php +++ b/vendor/drupal/console/src/Command/Config/EditCommand.php @@ -97,7 +97,7 @@ class EditCommand extends Command if (!$configName) { $io->error($this->trans('commands.config.edit.messages.no-config')); - return; + return 1; } try { @@ -106,7 +106,7 @@ class EditCommand extends Command } catch (IOExceptionInterface $e) { $io->error($this->trans('commands.config.edit.messages.no-directory').' '.$e->getPath()); - return; + return 1; } if (!$editor) { $editor = $this->getEditor(); @@ -122,9 +122,13 @@ class EditCommand extends Command $config->save(); $fileSystem->remove($configFile); } + if (!$process->isSuccessful()) { $io->error($process->getErrorOutput()); + return 1; } + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Config/ExportCommand.php b/vendor/drupal/console/src/Command/Config/ExportCommand.php index 8544d6cf6..38fbe692e 100644 --- a/vendor/drupal/console/src/Command/Config/ExportCommand.php +++ b/vendor/drupal/console/src/Command/Config/ExportCommand.php @@ -9,6 +9,8 @@ namespace Drupal\Console\Command\Config; use Drupal\Core\Archiver\ArchiveTar; use Drupal\Component\Serialization\Yaml; +use Drupal\Core\Config\ConfigManagerInterface; +use Drupal\Core\Config\StorageInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -27,15 +29,22 @@ class ExportCommand extends Command */ protected $configManager; + /** + * @var StorageInterface + */ + protected $storage; + /** * ExportCommand constructor. * - * @param ConfigManager $configManager + * @param ConfigManagerInterface $configManager + * @param StorageInterface $storage */ - public function __construct(ConfigManager $configManager) + public function __construct(ConfigManagerInterface $configManager, StorageInterface $storage) { - $this->configManager = $configManager; parent::__construct(); + $this->configManager = $configManager; + $this->storage = $storage; } /** @@ -54,17 +63,17 @@ class ExportCommand extends Command ) ->addOption( 'tar', - false, + null, InputOption::VALUE_NONE, $this->trans('commands.config.export.arguments.tar') )->addOption( 'remove-uuid', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.config.export.single.options.remove-uuid') )->addOption( 'remove-config-hash', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.config.export.single.options.remove-config-hash') ); @@ -98,6 +107,9 @@ class ExportCommand extends Command ); } + // Remove previous yaml files before creating new ones + array_map('unlink', glob($directory . '/*')); + if ($tar) { $dateTime = new \DateTime(); @@ -112,30 +124,42 @@ class ExportCommand extends Command try { // Get raw configuration data without overrides. foreach ($this->configManager->getConfigFactory()->listAll() as $name) { + $configName = "$name.yml"; $configData = $this->configManager->getConfigFactory()->get($name)->getRawData(); - $configName = sprintf('%s.yml', $name); - if ($removeUuid) { unset($configData['uuid']); } - if ($removeHash) { unset($configData['_core']['default_config_hash']); } - $ymlData = Yaml::encode($configData); if ($tar) { - $archiveTar->addString( - $configName, - $ymlData - ); - continue; + $archiveTar->addString($configName, $ymlData); + } else { + file_put_contents("$directory/$configName", $ymlData); + } + } + // Get all override data from the remaining collections. + foreach ($this->storage->getAllCollectionNames() as $collection) { + $collection_storage = $this->storage->createCollection($collection); + foreach ($collection_storage->listAll() as $name) { + $configName = str_replace('.', '/', $collection) . "/$name.yml"; + $configData = $collection_storage->read($name); + if ($removeUuid) { + unset($configData['uuid']); + } + if ($removeHash) { + unset($configData['_core']['default_config_hash']); + } + + $ymlData = Yaml::encode($configData); + if ($tar) { + $archiveTar->addString($configName, $ymlData); + } else { + file_put_contents("$directory/$configName", $ymlData); + } } - - $configFileName = sprintf('%s/%s', $directory, $configName); - - file_put_contents($configFileName, $ymlData); } } catch (\Exception $e) { $io->error($e->getMessage()); diff --git a/vendor/drupal/console/src/Command/Config/ExportContentTypeCommand.php b/vendor/drupal/console/src/Command/Config/ExportContentTypeCommand.php index 130533f5a..6382238f3 100644 --- a/vendor/drupal/console/src/Command/Config/ExportContentTypeCommand.php +++ b/vendor/drupal/console/src/Command/Config/ExportContentTypeCommand.php @@ -69,14 +69,14 @@ class ExportContentTypeCommand extends Command $this ->setName('config:export:content:type') ->setDescription($this->trans('commands.config.export.content.type.description')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addArgument( 'content-type', InputArgument::REQUIRED, $this->trans('commands.config.export.content.type.arguments.content-type') )->addOption( 'optional-config', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.config.export.content.type.options.optional-config') ); diff --git a/vendor/drupal/console/src/Command/Config/ExportSingleCommand.php b/vendor/drupal/console/src/Command/Config/ExportSingleCommand.php index a3b728811..4e632eee8 100644 --- a/vendor/drupal/console/src/Command/Config/ExportSingleCommand.php +++ b/vendor/drupal/console/src/Command/Config/ExportSingleCommand.php @@ -18,6 +18,7 @@ use Drupal\Core\Config\CachedStorage; use Drupal\Console\Core\Style\DrupalStyle; use Drupal\Console\Core\Command\Shared\CommandTrait; use Drupal\Console\Command\Shared\ExportTrait; +use Drupal\Console\Extension\Manager; class ExportSingleCommand extends Command { @@ -46,13 +47,16 @@ class ExportSingleCommand extends Command * * @param EntityTypeManagerInterface $entityTypeManager * @param CachedStorage $configStorage + * @param Manager $extensionManager */ public function __construct( EntityTypeManagerInterface $entityTypeManager, - CachedStorage $configStorage + CachedStorage $configStorage, + Manager $extensionManager ) { $this->entityTypeManager = $entityTypeManager; $this->configStorage = $configStorage; + $this->extensionManager = $extensionManager; parent::__construct(); } @@ -66,37 +70,37 @@ class ExportSingleCommand extends Command ->setDescription($this->trans('commands.config.export.single.description')) ->addOption( 'name', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.config.export.single.options.name') )->addOption( 'directory', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.config.export.arguments.directory') )->addOption( 'module', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.common.options.module') )->addOption( 'include-dependencies', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.config.export.single.options.include-dependencies') )->addOption( 'optional', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.config.export.single.options.optional') )->addOption( 'remove-uuid', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.config.export.single.options.remove-uuid') )->addOption( 'remove-config-hash', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.config.export.single.options.remove-config-hash') ); diff --git a/vendor/drupal/console/src/Command/Config/ExportViewCommand.php b/vendor/drupal/console/src/Command/Config/ExportViewCommand.php index 246b09e26..f0b0c0e36 100644 --- a/vendor/drupal/console/src/Command/Config/ExportViewCommand.php +++ b/vendor/drupal/console/src/Command/Config/ExportViewCommand.php @@ -69,7 +69,7 @@ class ExportViewCommand extends Command ->setName('config:export:view') ->setDescription($this->trans('commands.config.export.view.description')) ->addOption( - 'module', '', + 'module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) @@ -80,13 +80,13 @@ class ExportViewCommand extends Command ) ->addOption( 'optional-config', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.config.export.view.options.optional-config') ) ->addOption( 'include-module-dependencies', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.config.export.view.options.include-module-dependencies') ); diff --git a/vendor/drupal/console/src/Command/Config/ImportCommand.php b/vendor/drupal/console/src/Command/Config/ImportCommand.php index 373b3d587..8f5ad6010 100644 --- a/vendor/drupal/console/src/Command/Config/ImportCommand.php +++ b/vendor/drupal/console/src/Command/Config/ImportCommand.php @@ -70,7 +70,7 @@ class ImportCommand extends Command ) ->addOption( 'remove-files', - false, + null, InputOption::VALUE_NONE, $this->trans('commands.config.import.options.remove-files') ); @@ -130,7 +130,7 @@ class ImportCommand extends Command $config_importer->import(); return true; } catch (ConfigImporterException $e) { - $message = 'The import failed due for the following reasons:' . "\n"; + $message = 'The import failed due to the following reasons:' . "\n"; $message .= implode("\n", $config_importer->getErrors()); $io->error( sprintf( diff --git a/vendor/drupal/console/src/Command/Config/ImportSingleCommand.php b/vendor/drupal/console/src/Command/Config/ImportSingleCommand.php index 6204a3d85..6b5668f5a 100644 --- a/vendor/drupal/console/src/Command/Config/ImportSingleCommand.php +++ b/vendor/drupal/console/src/Command/Config/ImportSingleCommand.php @@ -70,7 +70,7 @@ class ImportSingleCommand extends Command $this->trans('commands.config.import.single.options.file') )->addOption( 'directory', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.config.import.arguments.directory') ); @@ -84,6 +84,7 @@ class ImportSingleCommand extends Command $io = new DrupalStyle($input, $output); $name = $input->getOption('name'); + $name = is_array($name) ? $name : [$name]; $directory = $input->getOption('directory'); $file = $input->getOption('file'); @@ -103,10 +104,14 @@ class ImportSingleCommand extends Command $nameItem = substr($nameItem, 0, -4); } - $configFile = $directory.DIRECTORY_SEPARATOR.$nameItem.'.yml'; + $configFile = count($name) == 1 ? + $file : + $directory.DIRECTORY_SEPARATOR.$nameItem.'.yml'; + if (file_exists($configFile)) { $value = $ymlFile->parse(file_get_contents($configFile)); - $source_storage->replaceData($nameItem, $value); + $source_storage->delete($nameItem); + $source_storage->write($nameItem, $value); continue; } @@ -120,6 +125,7 @@ class ImportSingleCommand extends Command $this->configManager ); + if ($this->configImport($io, $storageComparer)) { $io->success( sprintf( @@ -168,7 +174,7 @@ class ImportSingleCommand extends Command return true; } } catch (ConfigImporterException $e) { - $message = 'The import failed due for the following reasons:' . "\n"; + $message = 'The import failed due to the following reasons:' . "\n"; $message .= implode("\n", $configImporter->getErrors()); $io->error( sprintf( diff --git a/vendor/drupal/console/src/Command/Config/SettingsDebugCommand.php b/vendor/drupal/console/src/Command/Config/SettingsDebugCommand.php index 15c7b5e8a..57367e80b 100644 --- a/vendor/drupal/console/src/Command/Config/SettingsDebugCommand.php +++ b/vendor/drupal/console/src/Command/Config/SettingsDebugCommand.php @@ -65,8 +65,9 @@ class SettingsDebugCommand extends Command $io->newLine(); foreach ($settingKeys as $settingKey) { - $io->comment($settingKey, false); - $io->simple(Yaml::encode($this->settings->get($settingKey))); + $settingValue = $this->settings->get($settingKey); + $io->comment($settingKey . ': ', is_array($settingValue)); + $io->write(Yaml::encode($settingValue)); } $io->newLine(); } diff --git a/vendor/drupal/console/src/Command/ContainerDebugCommand.php b/vendor/drupal/console/src/Command/ContainerDebugCommand.php index db128a41a..61519abc2 100644 --- a/vendor/drupal/console/src/Command/ContainerDebugCommand.php +++ b/vendor/drupal/console/src/Command/ContainerDebugCommand.php @@ -43,6 +43,14 @@ class ContainerDebugCommand extends Command 'service', InputArgument::OPTIONAL, $this->trans('commands.container.debug.arguments.service') + )->addArgument( + 'method', + InputArgument::OPTIONAL, + $this->trans('commands.container.debug.arguments.method') + )->addArgument( + 'arguments', + InputArgument::OPTIONAL, + $this->trans('commands.container.debug.arguments.arguments') ); } @@ -54,6 +62,8 @@ class ContainerDebugCommand extends Command $io = new DrupalStyle($input, $output); $service = $input->getArgument('service'); $parameters = $input->getOption('parameters'); + $method = $input->getArgument('method'); + $args = $input->getArgument('arguments'); if ($parameters) { $parameterList = $this->getParameterList(); @@ -63,25 +73,77 @@ class ContainerDebugCommand extends Command return 0; } - $tableHeader = []; - if ($service) { - $tableRows = $this->getServiceDetail($service); - $io->table($tableHeader, $tableRows, 'compact'); + if ($method) { + $tableHeader = []; + $callbackRow = $this->getCallbackReturnList($service, $method, $args); + $io->table($tableHeader, $callbackRow, 'compact'); return 0; - } + } else { + $tableHeader = []; + if ($service) { + $tableRows = $this->getServiceDetail($service); + $io->table($tableHeader, $tableRows, 'compact'); - $tableHeader = [ - $this->trans('commands.container.debug.messages.service_id'), - $this->trans('commands.container.debug.messages.class_name') - ]; + return 0; + } - $tableRows = $this->getServiceList(); - $io->table($tableHeader, $tableRows, 'compact'); + $tableHeader = [ + $this->trans('commands.container.debug.messages.service_id'), + $this->trans('commands.container.debug.messages.class_name') + ]; + + $tableRows = $this->getServiceList(); + $io->table($tableHeader, $tableRows, 'compact'); + } return 0; } + private function getCallbackReturnList($service, $method, $args) + { + if ($args != null) { + $parsedArgs = json_decode($args, true); + if (!is_array($parsedArgs)) { + $parsedArgs = explode(",", $args); + } + } else { + $parsedArgs = null; + } + $serviceInstance = \Drupal::service($service); + + if (!method_exists($serviceInstance, $method)) { + throw new \Symfony\Component\DependencyInjection\Exception\BadMethodCallException($this->trans('commands.container.debug.errors.method_not_exists')); + + return $serviceDetail; + } + $serviceDetail[] = [ + ''.$this->trans('commands.container.debug.messages.service').'', + ''.$service.'' + ]; + $serviceDetail[] = [ + ''.$this->trans('commands.container.debug.messages.class').'', + ''.get_class($serviceInstance).'' + ]; + $methods = [$method]; + $this->extendArgumentList($serviceInstance, $methods); + $serviceDetail[] = [ + ''.$this->trans('commands.container.debug.messages.method').'', + ''.$methods[0].'' + ]; + if ($parsedArgs) { + $serviceDetail[] = [ + ''.$this->trans('commands.container.debug.messages.arguments').'', + json_encode($parsedArgs, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) + ]; + } + $return = call_user_func_array([$serviceInstance,$method], $parsedArgs); + $serviceDetail[] = [ + ''.$this->trans('commands.container.debug.messages.return').'', + json_encode($return, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) + ]; + return $serviceDetail; + } private function getServiceList() { $services = []; @@ -91,8 +153,13 @@ class ContainerDebugCommand extends Command foreach ($serviceDefinitions as $serviceId => $serviceDefinition) { $services[] = [$serviceId, $serviceDefinition->getClass()]; } + usort($services, [$this, 'compareService']); return $services; } + private function compareService($a, $b) + { + return strcmp($a[0], $b[0]); + } private function getServiceDetail($service) { @@ -101,39 +168,83 @@ class ContainerDebugCommand extends Command if ($serviceInstance) { $serviceDetail[] = [ - $this->trans('commands.container.debug.messages.service'), - $service + ''.$this->trans('commands.container.debug.messages.service').'', + ''.$service.'' ]; $serviceDetail[] = [ - $this->trans('commands.container.debug.messages.class'), - get_class($serviceInstance) - ]; - $serviceDetail[] = [ - $this->trans('commands.container.debug.messages.interface'), - Yaml::dump(class_implements($serviceInstance)) + ''.$this->trans('commands.container.debug.messages.class').'', + ''.get_class($serviceInstance).'' ]; + $interface = str_replace("{ }", "", Yaml::dump(class_implements($serviceInstance))); + if (!empty($interface)) { + $serviceDetail[] = [ + ''.$this->trans('commands.container.debug.messages.interface').'', + ''.$interface.'' + ]; + } if ($parent = get_parent_class($serviceInstance)) { $serviceDetail[] = [ - $this->trans('commands.container.debug.messages.parent'), - $parent + ''.$this->trans('commands.container.debug.messages.parent').'', + ''.$parent.'' ]; } if ($vars = get_class_vars($serviceInstance)) { $serviceDetail[] = [ - $this->trans('commands.container.debug.messages.variables'), - Yaml::dump($vars) + ''.$this->trans('commands.container.debug.messages.variables').'', + ''.Yaml::dump($vars).'' ]; } if ($methods = get_class_methods($serviceInstance)) { + sort($methods); + $this->extendArgumentList($serviceInstance, $methods); $serviceDetail[] = [ - $this->trans('commands.container.debug.messages.methods'), - Yaml::dump($methods) + ''.$this->trans('commands.container.debug.messages.methods').'', + ''.implode("\n", $methods).'' ]; } + } else { + throw new \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException($service); + + return $serviceDetail; } return $serviceDetail; } + private function extendArgumentList($serviceInstance, &$methods) + { + foreach ($methods as $k => $m) { + $reflection = new \ReflectionMethod($serviceInstance, $m); + $params = $reflection->getParameters(); + $p = []; + + for ($i = 0; $i < count($params); $i++) { + if ($params[$i]->isDefaultValueAvailable()) { + $defaultVar = $params[$i]->getDefaultValue(); + $defaultVar = " = ".str_replace(["\n","array ("], ["", "array("], var_export($def, true)).''; + } else { + $defaultVar = ''; + } + if (method_exists($params[$i], 'hasType') && method_exists($params[$i], 'getType')) { + if ($params[$i]->hasType()) { + $defaultType = ''.strval($params[$i]->getType()).' '; + } else { + $defaultType = ''; + } + } else { + $defaultType = ''; + } + if ($params[$i]->isPassedByReference()) { + $parameterReference = '&'; + } else { + $parameterReference = ''; + } + $p[] = $defaultType.$parameterReference.''.'$'.$params[$i]->getName().''.$defaultVar; + } + if ($reflection->isPublic()) { + $methods[$k] = ''.$methods[$k]."(".implode(', ', $p).") "; + } + } + } private function getParameterList() { diff --git a/vendor/drupal/console/src/Command/Create/NodesCommand.php b/vendor/drupal/console/src/Command/Create/NodesCommand.php index fe8ca08e0..36f3d98a4 100644 --- a/vendor/drupal/console/src/Command/Create/NodesCommand.php +++ b/vendor/drupal/console/src/Command/Create/NodesCommand.php @@ -12,6 +12,7 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command; +use Drupal\Console\Annotations\DrupalCommand; use Drupal\Console\Core\Command\Shared\CommandTrait; use Drupal\Console\Command\Shared\CreateTrait; use Drupal\Console\Utils\Create\NodeData; @@ -23,6 +24,11 @@ use Drupal\Core\Language\LanguageInterface; * Class NodesCommand * * @package Drupal\Console\Command\Generate + * + * @DrupalCommand( + * extension = "node", + * extensionType = "module" + * ) */ class NodesCommand extends Command { @@ -151,16 +157,17 @@ class NodesCommand extends Command } // Language module is enabled or not. - $language_module_enabled = \Drupal::moduleHandler()->moduleExists('language'); + $languageModuleEnabled = \Drupal::moduleHandler() + ->moduleExists('language'); // If language module is enabled. - if ($language_module_enabled) { + if ($languageModuleEnabled) { // Get available languages on site. - $available_languages = \Drupal::languageManager()->getLanguages(); + $languages = \Drupal::languageManager()->getLanguages(); // Holds the available languages. $language_list = []; - foreach ($available_languages as $lang) { + foreach ($languages as $lang) { $language_list[$lang->getId()] = $lang->getName(); } @@ -191,7 +198,7 @@ class NodesCommand extends Command $titleWords = $input->getOption('title-words')?:5; $timeRange = $input->getOption('time-range')?:31536000; $available_types = array_keys($this->drupalApi->getBundles()); - $language = $input->getOption('language'); + $language = $input->getOption('language')?:'und'; foreach ($contentTypes as $type) { if (!in_array($type, $available_types)) { @@ -210,6 +217,8 @@ class NodesCommand extends Command $timeRange, $language ); + + $nodes = is_array($nodes) ? $nodes : [$nodes]; $tableHeader = [ $this->trans('commands.create.nodes.messages.node-id'), diff --git a/vendor/drupal/console/src/Command/Create/TermsCommand.php b/vendor/drupal/console/src/Command/Create/TermsCommand.php index 0822c4a74..a2bd1ab3b 100644 --- a/vendor/drupal/console/src/Command/Create/TermsCommand.php +++ b/vendor/drupal/console/src/Command/Create/TermsCommand.php @@ -24,9 +24,8 @@ use Drupal\Console\Core\Style\DrupalStyle; * @package Drupal\Console\Command\Generate * * @DrupalCommand( - * extension = "features", - * extensionType = "module", - * dependencies={"taxonomy"} + * extension = "taxonomy", + * extensionType = "module" * ) */ class TermsCommand extends Command diff --git a/vendor/drupal/console/src/Command/Cron/DebugCommand.php b/vendor/drupal/console/src/Command/Cron/DebugCommand.php index 7e38a0e30..df06c099a 100644 --- a/vendor/drupal/console/src/Command/Cron/DebugCommand.php +++ b/vendor/drupal/console/src/Command/Cron/DebugCommand.php @@ -56,9 +56,7 @@ class DebugCommand extends Command ); $io->table( - [ - $this->trans('commands.cron.debug.messages.module') - ], + [ $this->trans('commands.cron.debug.messages.module') ], $this->moduleHandler->getImplementations('cron'), 'compact' ); diff --git a/vendor/drupal/console/src/Command/Database/AddCommand.php b/vendor/drupal/console/src/Command/Database/AddCommand.php index d62c17836..1e2087a10 100644 --- a/vendor/drupal/console/src/Command/Database/AddCommand.php +++ b/vendor/drupal/console/src/Command/Database/AddCommand.php @@ -50,43 +50,43 @@ class AddCommand extends Command ->setDescription($this->trans('commands.database.add.description')) ->addOption( 'database', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.database.add.options.database') ) ->addOption( 'username', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.database.add.options.username') ) ->addOption( 'password', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.database.add.options.password') ) ->addOption( 'prefix', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.add.options.prefix') ) ->addOption( 'host', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.add.options.host') ) ->addOption( 'port', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.add.options.port') ) ->addOption( 'driver', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.add.options.driver') ) diff --git a/vendor/drupal/console/src/Command/Database/DatabaseLogBase.php b/vendor/drupal/console/src/Command/Database/DatabaseLogBase.php index 0feb20934..f0d8e5056 100644 --- a/vendor/drupal/console/src/Command/Database/DatabaseLogBase.php +++ b/vendor/drupal/console/src/Command/Database/DatabaseLogBase.php @@ -108,19 +108,19 @@ abstract class DatabaseLogBase extends Command $this ->addOption( 'type', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.log.common.options.type') ) ->addOption( 'severity', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.log.common.options.severity') ) ->addOption( 'user-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.log.common.options.user-id') ); diff --git a/vendor/drupal/console/src/Command/Database/DumpCommand.php b/vendor/drupal/console/src/Command/Database/DumpCommand.php index cc5888be5..b867b517b 100644 --- a/vendor/drupal/console/src/Command/Database/DumpCommand.php +++ b/vendor/drupal/console/src/Command/Database/DumpCommand.php @@ -66,7 +66,7 @@ class DumpCommand extends Command ) ->addOption( 'gz', - false, + null, InputOption::VALUE_NONE, $this->trans('commands.database.dump.options.gz') ) @@ -101,7 +101,7 @@ class DumpCommand extends Command if ($databaseConnection['driver'] == 'mysql') { $command = sprintf( - 'mysqldump --user=%s --password=%s --host=%s --port=%s %s > %s', + 'mysqldump --user="%s" --password="%s" --host="%s" --port="%s" "%s" > "%s"', $databaseConnection['username'], $databaseConnection['password'], $databaseConnection['host'], @@ -111,7 +111,7 @@ class DumpCommand extends Command ); } elseif ($databaseConnection['driver'] == 'pgsql') { $command = sprintf( - 'PGPASSWORD="%s" pg_dumpall -w -U %s -h %s -p %s -l %s -f %s', + 'PGPASSWORD="%s" pg_dumpall -w -U "%s" -h "%s" -p "%s" -l "%s" -f "%s"', $databaseConnection['password'], $databaseConnection['username'], $databaseConnection['host'], diff --git a/vendor/drupal/console/src/Command/Database/LogClearCommand.php b/vendor/drupal/console/src/Command/Database/LogClearCommand.php index ac87b8036..84a1bb3ee 100644 --- a/vendor/drupal/console/src/Command/Database/LogClearCommand.php +++ b/vendor/drupal/console/src/Command/Database/LogClearCommand.php @@ -52,19 +52,19 @@ class LogClearCommand extends Command ) ->addOption( 'type', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.log.clear.options.type') ) ->addOption( 'severity', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.log.clear.options.severity') ) ->addOption( 'user-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.log.clear.options.user-id') ); diff --git a/vendor/drupal/console/src/Command/Database/LogDebugCommand.php b/vendor/drupal/console/src/Command/Database/LogDebugCommand.php index b74cc9c5d..de702d860 100644 --- a/vendor/drupal/console/src/Command/Database/LogDebugCommand.php +++ b/vendor/drupal/console/src/Command/Database/LogDebugCommand.php @@ -65,7 +65,7 @@ class LogDebugCommand extends DatabaseLogBase ) ->addOption( 'asc', - false, + null, InputOption::VALUE_NONE, $this->trans('commands.database.log.debug.options.asc') ) diff --git a/vendor/drupal/console/src/Command/Database/QueryCommand.php b/vendor/drupal/console/src/Command/Database/QueryCommand.php index 6e412b788..d5ee1139e 100644 --- a/vendor/drupal/console/src/Command/Database/QueryCommand.php +++ b/vendor/drupal/console/src/Command/Database/QueryCommand.php @@ -46,13 +46,13 @@ class QueryCommand extends Command $this->trans('commands.database.query.arguments.database'), 'default' ) - ->addOption('quick', '', InputOption::VALUE_NONE, $this->trans('commands.database.query.options.quick')) - ->addOption('debug', '', InputOption::VALUE_NONE, $this->trans('commands.database.query.options.debug')) - ->addOption('html', '', InputOption::VALUE_NONE, $this->trans('commands.database.query.options.html')) - ->addOption('xml', '', InputOption::VALUE_NONE, $this->trans('commands.database.query.options.xml')) - ->addOption('raw', '', InputOption::VALUE_NONE, $this->trans('commands.database.query.options.raw')) - ->addOption('vertical', '', InputOption::VALUE_NONE, $this->trans('commands.database.query.options.vertical')) - ->addOption('batch', '', InputOption::VALUE_NONE, $this->trans('commands.database.query.options.batch')) + ->addOption('quick', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.quick')) + ->addOption('debug', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.debug')) + ->addOption('html', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.html')) + ->addOption('xml', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.xml')) + ->addOption('raw', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.raw')) + ->addOption('vertical', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.vertical')) + ->addOption('batch', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.batch')) ->setHelp($this->trans('commands.database.query.help')); } diff --git a/vendor/drupal/console/src/Command/Database/TableDebugCommand.php b/vendor/drupal/console/src/Command/Database/TableDebugCommand.php index 3621074d7..b6c9533e0 100644 --- a/vendor/drupal/console/src/Command/Database/TableDebugCommand.php +++ b/vendor/drupal/console/src/Command/Database/TableDebugCommand.php @@ -63,7 +63,7 @@ class TableDebugCommand extends Command ->setDescription($this->trans('commands.database.table.debug.description')) ->addOption( 'database', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.database.table.debug.options.database'), 'default' diff --git a/vendor/drupal/console/src/Command/Develop/TranslationPendingCommand.php b/vendor/drupal/console/src/Command/Develop/TranslationPendingCommand.php index 3e479bdcd..a7aa68ea0 100644 --- a/vendor/drupal/console/src/Command/Develop/TranslationPendingCommand.php +++ b/vendor/drupal/console/src/Command/Develop/TranslationPendingCommand.php @@ -77,7 +77,7 @@ class TranslationPendingCommand extends Command ) ->addOption( 'file', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.translation.pending.options.file'), null diff --git a/vendor/drupal/console/src/Command/Develop/TranslationStatsCommand.php b/vendor/drupal/console/src/Command/Develop/TranslationStatsCommand.php index 723ba787d..9d898aff5 100644 --- a/vendor/drupal/console/src/Command/Develop/TranslationStatsCommand.php +++ b/vendor/drupal/console/src/Command/Develop/TranslationStatsCommand.php @@ -85,7 +85,7 @@ class TranslationStatsCommand extends Command ) ->addOption( 'format', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.translation.stats.options.format'), 'table' diff --git a/vendor/drupal/console/src/Command/Develop/TranslationSyncCommand.php b/vendor/drupal/console/src/Command/Develop/TranslationSyncCommand.php index 5d2cd7076..be719800a 100644 --- a/vendor/drupal/console/src/Command/Develop/TranslationSyncCommand.php +++ b/vendor/drupal/console/src/Command/Develop/TranslationSyncCommand.php @@ -64,7 +64,7 @@ class TranslationSyncCommand extends Command ) ->addOption( 'file', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.translation.stats.options.file'), null diff --git a/vendor/drupal/console/src/Command/EventDebugCommand.php b/vendor/drupal/console/src/Command/EventDebugCommand.php index 38c05a43e..71107fe4b 100644 --- a/vendor/drupal/console/src/Command/EventDebugCommand.php +++ b/vendor/drupal/console/src/Command/EventDebugCommand.php @@ -11,6 +11,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Yaml\Yaml; use Drupal\Console\Core\Command\Shared\CommandTrait; use Drupal\Console\Core\Style\DrupalStyle; @@ -78,20 +79,55 @@ class EventDebugCommand extends Command foreach ($dispatcher as $key => $value) { $reflection = new \ReflectionClass(get_class($value[0])); - $listeners[] = [$reflection->getName(), $value[1]]; + $className = $reflection->getName(); + + if (!$reflection->hasMethod('getSubscribedEvents')) { + $reflection = new \ReflectionClass($reflection->getParentClass()); + } + + $eventObject = $reflection->newInstanceWithoutConstructor(); + $reflectionMethod = new \ReflectionMethod( + $reflection->getName(), + 'getSubscribedEvents' + ); + + $subscribedEvents = $reflectionMethod->invoke( + $eventObject + ); + + if (!is_array($subscribedEvents[$event])) { + $subscribedEvents[$event] = [$subscribedEvents[$event]]; + } + + $subscribedEventData = []; + foreach ($subscribedEvents[$event] as $subscribedEvent) { + if (!is_array($subscribedEvent)) { + $subscribedEvent = [$subscribedEvent, 0]; + } + if ($subscribedEvent[0] == $value[1]) { + $subscribedEventData = [ + $subscribedEvent[0] => isset($subscribedEvent[1])?$subscribedEvent[1]:0 + ]; + } + } + + $listeners[] = [ + 'class' => $className, + 'method' => $value[1], + 'events' => Yaml::dump($subscribedEventData, 4, 2) + ]; } $tableHeader = [ $this->trans('commands.event.debug.messages.class'), $this->trans('commands.event.debug.messages.method'), - ]; $tableRows = []; foreach ($listeners as $key => $element) { $tableRows[] = [ - 'class' => $element['0'], - 'method' => $element['1'] + 'class' => $element['class'], + 'events' => $element['events'] ]; } diff --git a/vendor/drupal/console/src/Command/Features/ImportCommand.php b/vendor/drupal/console/src/Command/Features/ImportCommand.php index 31ae21481..275859fb1 100644 --- a/vendor/drupal/console/src/Command/Features/ImportCommand.php +++ b/vendor/drupal/console/src/Command/Features/ImportCommand.php @@ -41,7 +41,7 @@ class ImportCommand extends Command ->setDescription($this->trans('commands.features.import.description')) ->addOption( 'bundle', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.features.import.options.bundle') ) diff --git a/vendor/drupal/console/src/Command/Generate/AuthenticationProviderCommand.php b/vendor/drupal/console/src/Command/Generate/AuthenticationProviderCommand.php index a05aadecb..cb09454a5 100644 --- a/vendor/drupal/console/src/Command/Generate/AuthenticationProviderCommand.php +++ b/vendor/drupal/console/src/Command/Generate/AuthenticationProviderCommand.php @@ -69,16 +69,16 @@ class AuthenticationProviderCommand extends Command ->setName('generate:authentication:provider') ->setDescription($this->trans('commands.generate.authentication.provider.description')) ->setHelp($this->trans('commands.generate.authentication.provider.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.authentication.provider.options.class') ) ->addOption( 'provider-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.authentication.provider.options.provider-id') ); @@ -93,7 +93,7 @@ class AuthenticationProviderCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -101,6 +101,8 @@ class AuthenticationProviderCommand extends Command $provider_id = $input->getOption('provider-id'); $this->generator->generate($module, $class, $provider_id); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/BreakPointCommand.php b/vendor/drupal/console/src/Command/Generate/BreakPointCommand.php index 5ffe47470..bb53df8ef 100644 --- a/vendor/drupal/console/src/Command/Generate/BreakPointCommand.php +++ b/vendor/drupal/console/src/Command/Generate/BreakPointCommand.php @@ -97,13 +97,13 @@ class BreakPointCommand extends Command ->setHelp($this->trans('commands.generate.breakpoint.help')) ->addOption( 'theme', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.breakpoint.options.theme') ) ->addOption( 'breakpoints', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.breakpoint.options.breakpoints') ); @@ -118,7 +118,7 @@ class BreakPointCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $validators = $this->validator; @@ -132,6 +132,8 @@ class BreakPointCommand extends Command $breakpoints, $machine_name ); + + return 0; } /** diff --git a/vendor/drupal/console/src/Command/Generate/CacheContextCommand.php b/vendor/drupal/console/src/Command/Generate/CacheContextCommand.php index c9be2e877..474082006 100644 --- a/vendor/drupal/console/src/Command/Generate/CacheContextCommand.php +++ b/vendor/drupal/console/src/Command/Generate/CacheContextCommand.php @@ -108,7 +108,7 @@ class CacheContextCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); diff --git a/vendor/drupal/console/src/Command/Generate/CommandCommand.php b/vendor/drupal/console/src/Command/Generate/CommandCommand.php index 7255609cd..fc3a914b9 100644 --- a/vendor/drupal/console/src/Command/Generate/CommandCommand.php +++ b/vendor/drupal/console/src/Command/Generate/CommandCommand.php @@ -21,6 +21,7 @@ use Drupal\Console\Core\Utils\StringConverter; use Drupal\Console\Extension\Manager; use Drupal\Console\Core\Style\DrupalStyle; use Drupal\Console\Utils\Validator; +use Drupal\Console\Utils\Site; class CommandCommand extends Command { @@ -50,6 +51,11 @@ class CommandCommand extends Command */ protected $stringConverter; + /** + * @var Site + */ + protected $site; + /** * CommandCommand constructor. * @@ -57,17 +63,20 @@ class CommandCommand extends Command * @param Manager $extensionManager * @param Validator $validator * @param StringConverter $stringConverter + * @param Site $site */ public function __construct( CommandGenerator $generator, Manager $extensionManager, Validator $validator, - StringConverter $stringConverter + StringConverter $stringConverter, + Site $site ) { $this->generator = $generator; $this->extensionManager = $extensionManager; $this->validator = $validator; $this->stringConverter = $stringConverter; + $this->site = $site; parent::__construct(); } @@ -82,37 +91,37 @@ class CommandCommand extends Command ->setHelp($this->trans('commands.generate.command.help')) ->addOption( 'extension', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.extension') ) ->addOption( 'extension-type', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.extension-type') ) ->addOption( 'class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.command.options.class') ) ->addOption( 'name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.command.options.name') ) ->addOption( 'container-aware', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.generate.command.options.container-aware') ) ->addOption( 'services', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.common.options.services') ); @@ -135,7 +144,7 @@ class CommandCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io, $yes)) { - return; + return 1; } // @see use Drupal\Console\Command\Shared\ServicesTrait::buildServices @@ -149,6 +158,10 @@ class CommandCommand extends Command $containerAware, $build_services ); + + $this->site->removeCachedServicesFile(); + + return 0; } /** diff --git a/vendor/drupal/console/src/Command/Generate/ControllerCommand.php b/vendor/drupal/console/src/Command/Generate/ControllerCommand.php index 6ab08915a..02f09391b 100644 --- a/vendor/drupal/console/src/Command/Generate/ControllerCommand.php +++ b/vendor/drupal/console/src/Command/Generate/ControllerCommand.php @@ -97,31 +97,31 @@ class ControllerCommand extends Command ->setHelp($this->trans('commands.generate.controller.help')) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.controller.options.class') ) ->addOption( 'routes', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.generate.controller.options.routes') ) ->addOption( 'services', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.common.options.services') ) ->addOption( 'test', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.generate.controller.options.test') ); @@ -137,10 +137,9 @@ class ControllerCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io, $yes)) { - return; + return 1; } - $learning = $input->hasOption('learning')?$input->getOption('learning'):false; $module = $input->getOption('module'); $class = $input->getOption('class'); $routes = $input->getOption('routes'); @@ -164,6 +163,8 @@ class ControllerCommand extends Command // Run cache rebuild to see changes in Web UI $this->chainQueue->addCommand('router:rebuild', []); + + return 0; } /** diff --git a/vendor/drupal/console/src/Command/Generate/EntityBundleCommand.php b/vendor/drupal/console/src/Command/Generate/EntityBundleCommand.php index 7fc27a58c..b12ef276e 100644 --- a/vendor/drupal/console/src/Command/Generate/EntityBundleCommand.php +++ b/vendor/drupal/console/src/Command/Generate/EntityBundleCommand.php @@ -15,7 +15,6 @@ use Drupal\Console\Command\Shared\ConfirmationTrait; use Drupal\Console\Command\Shared\ModuleTrait; use Drupal\Console\Command\Shared\ServicesTrait; use Drupal\Console\Core\Command\Shared\CommandTrait; -use Drupal\Console\Generator\ContentTypeGenerator; use Drupal\Console\Generator\EntityBundleGenerator; use Drupal\Console\Core\Style\DrupalStyle; use Drupal\Console\Extension\Manager; @@ -28,7 +27,6 @@ class EntityBundleCommand extends Command use ServicesTrait; use ConfirmationTrait; - /** * @var Validator */ @@ -69,16 +67,16 @@ class EntityBundleCommand extends Command ->setName('generate:entity:bundle') ->setDescription($this->trans('commands.generate.entity.bundle.description')) ->setHelp($this->trans('commands.generate.entity.bundle.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'bundle-name', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.entity.bundle.options.bundle-name') ) ->addOption( 'bundle-title', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.entity.bundle.options.bundle-title') ); @@ -93,18 +91,19 @@ class EntityBundleCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); $bundleName = $input->getOption('bundle-name'); $bundleTitle = $input->getOption('bundle-title'); - $learning = $input->hasOption('learning')?$input->getOption('learning'):false; $generator = $this->generator; //TODO: - //$generator->setLearning($learning); + // $generator->setLearning($learning); $generator->generate($module, $bundleName, $bundleTitle); + + return 0; } /** diff --git a/vendor/drupal/console/src/Command/Generate/EventSubscriberCommand.php b/vendor/drupal/console/src/Command/Generate/EventSubscriberCommand.php index e91ee3439..556e9bb20 100644 --- a/vendor/drupal/console/src/Command/Generate/EventSubscriberCommand.php +++ b/vendor/drupal/console/src/Command/Generate/EventSubscriberCommand.php @@ -125,7 +125,7 @@ class EventSubscriberCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); diff --git a/vendor/drupal/console/src/Command/Generate/FormAlterCommand.php b/vendor/drupal/console/src/Command/Generate/FormAlterCommand.php index f838827f6..71c5d8cfd 100644 --- a/vendor/drupal/console/src/Command/Generate/FormAlterCommand.php +++ b/vendor/drupal/console/src/Command/Generate/FormAlterCommand.php @@ -138,19 +138,19 @@ class FormAlterCommand extends Command ->setHelp($this->trans('commands.generate.form.alter.help')) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) ->addOption( 'form-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.form.alter.options.form-id') ) ->addOption( 'inputs', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.common.options.inputs') ); @@ -165,7 +165,7 @@ class FormAlterCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -193,6 +193,8 @@ class FormAlterCommand extends Command ->generate($module, $formId, $inputs, $this->metadata); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/FormCommand.php b/vendor/drupal/console/src/Command/Generate/FormCommand.php index 8014462eb..58a2582a1 100644 --- a/vendor/drupal/console/src/Command/Generate/FormCommand.php +++ b/vendor/drupal/console/src/Command/Generate/FormCommand.php @@ -122,61 +122,67 @@ abstract class FormCommand extends Command ) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.form.options.class') ) ->addOption( 'form-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.form.options.form-id') ) ->addOption( 'services', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.common.options.services') ) + ->addOption( + 'config-file', + null, + InputOption::VALUE_NONE, + $this->trans('commands.generate.form.options.config-file') + ) ->addOption( 'inputs', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.common.options.inputs') ) ->addOption( 'path', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.form.options.path') ) ->addOption( 'menu_link_gen', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.form.options.menu_link_gen') ) ->addOption( 'menu_link_title', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.form.options.menu_link_title') ) ->addOption( 'menu_parent', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.form.options.menu_parent') ) ->addOption( 'menu_link_desc', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.form.options.menu_link_desc') ); @@ -190,6 +196,7 @@ abstract class FormCommand extends Command $module = $input->getOption('module'); $services = $input->getOption('services'); $path = $input->getOption('path'); + $config_file = $input->getOption('config-file'); $class_name = $input->getOption('class'); $form_id = $input->getOption('form-id'); $form_type = $this->formType; @@ -204,7 +211,7 @@ abstract class FormCommand extends Command $this ->generator - ->generate($module, $class_name, $form_id, $form_type, $build_services, $inputs, $path, $menu_link_gen, $menu_link_title, $menu_parent, $menu_link_desc); + ->generate($module, $class_name, $form_id, $form_type, $build_services, $config_file, $inputs, $path, $menu_link_gen, $menu_link_title, $menu_parent, $menu_link_desc); $this->chainQueue->addCommand('router:rebuild', []); } @@ -248,6 +255,17 @@ abstract class FormCommand extends Command // @see use Drupal\Console\Command\Shared\ServicesTrait::servicesQuestion $services = $this->servicesQuestion($io); $input->setOption('services', $services); + + // --config_file option + $config_file = $input->getOption('config-file'); + + if (!$config_file) { + $config_file = $io->confirm( + $this->trans('commands.generate.form.questions.config-file'), + true + ); + $input->setOption('config-file', $config_file); + } // --inputs option $inputs = $input->getOption('inputs'); diff --git a/vendor/drupal/console/src/Command/Generate/HelpCommand.php b/vendor/drupal/console/src/Command/Generate/HelpCommand.php index afbf98a70..678ce7143 100644 --- a/vendor/drupal/console/src/Command/Generate/HelpCommand.php +++ b/vendor/drupal/console/src/Command/Generate/HelpCommand.php @@ -76,13 +76,13 @@ class HelpCommand extends Command ->setHelp($this->trans('commands.generate.help.help')) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) ->addOption( 'description', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.module.options.description') ); @@ -97,7 +97,7 @@ class HelpCommand extends Command // @see use Drupal\Console\Command\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -118,6 +118,8 @@ class HelpCommand extends Command ->generate($module, $description); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/ModuleCommand.php b/vendor/drupal/console/src/Command/Generate/ModuleCommand.php index 1127bcefe..0330fb564 100644 --- a/vendor/drupal/console/src/Command/Generate/ModuleCommand.php +++ b/vendor/drupal/console/src/Command/Generate/ModuleCommand.php @@ -19,9 +19,6 @@ use Drupal\Console\Utils\Validator; use Drupal\Console\Core\Command\Shared\CommandTrait; use Drupal\Console\Core\Utils\StringConverter; use Drupal\Console\Utils\DrupalApi; -use GuzzleHttp\Client; -use Drupal\Console\Utils\Site; -use GuzzleHttp\Exception\ClientException; class ModuleCommand extends Command { @@ -29,13 +26,13 @@ class ModuleCommand extends Command use CommandTrait; /** - * @var ModuleGenerator -*/ + * @var ModuleGenerator + */ protected $generator; /** - * @var Validator -*/ + * @var Validator + */ protected $validator; /** @@ -53,16 +50,6 @@ class ModuleCommand extends Command */ protected $drupalApi; - /** - * @var Client - */ - protected $httpClient; - - /** - * @var Site - */ - protected $site; - /** * @var string */ @@ -77,8 +64,6 @@ class ModuleCommand extends Command * @param $appRoot * @param StringConverter $stringConverter * @param DrupalApi $drupalApi - * @param Client $httpClient - * @param Site $site * @param $twigtemplate */ public function __construct( @@ -87,8 +72,6 @@ class ModuleCommand extends Command $appRoot, StringConverter $stringConverter, DrupalApi $drupalApi, - Client $httpClient, - Site $site, $twigtemplate = null ) { $this->generator = $generator; @@ -96,8 +79,6 @@ class ModuleCommand extends Command $this->appRoot = $appRoot; $this->stringConverter = $stringConverter; $this->drupalApi = $drupalApi; - $this->httpClient = $httpClient; - $this->site = $site; $this->twigtemplate = $twigtemplate; parent::__construct(); } @@ -113,73 +94,74 @@ class ModuleCommand extends Command ->setHelp($this->trans('commands.generate.module.help')) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.module.options.module') ) ->addOption( 'machine-name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.module.options.machine-name') ) ->addOption( 'module-path', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.module.options.module-path') ) ->addOption( 'description', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.module.options.description') ) ->addOption( 'core', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.module.options.core') ) ->addOption( 'package', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.module.options.package') ) ->addOption( 'module-file', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.generate.module.options.module-file') ) ->addOption( 'features-bundle', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.module.options.features-bundle') ) ->addOption( 'composer', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.generate.module.options.composer') ) ->addOption( 'dependencies', - '', + null, InputOption::VALUE_OPTIONAL, - $this->trans('commands.generate.module.options.dependencies') + $this->trans('commands.generate.module.options.dependencies'), + '' ) ->addOption( 'test', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.module.options.test') ) ->addOption( 'twigtemplate', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.module.options.twigtemplate') ); @@ -195,7 +177,7 @@ class ModuleCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io, $yes)) { - return; + return 1; } $module = $this->validator->validateModuleName($input->getOption('module')); @@ -210,24 +192,13 @@ class ModuleCommand extends Command $moduleFile = $input->getOption('module-file'); $featuresBundle = $input->getOption('features-bundle'); $composer = $input->getOption('composer'); + $dependencies = $this->validator->validateExtensions( + $input->getOption('dependencies'), + 'module', + $io + ); $test = $input->getOption('test'); - $twigtemplate = $input->getOption('twigtemplate'); - - // Modules Dependencies, re-factor and share with other commands - $dependencies = $this->validator->validateModuleDependencies($input->getOption('dependencies')); - // Check if all module dependencies are available - if ($dependencies) { - $checked_dependencies = $this->checkDependencies($dependencies['success'], $io); - if (!empty($checked_dependencies['no_modules'])) { - $io->warning( - sprintf( - $this->trans('commands.generate.module.warnings.module-unavailable'), - implode(', ', $checked_dependencies['no_modules']) - ) - ); - } - $dependencies = $dependencies['success']; - } + $twigTemplate = $input->getOption('twigtemplate'); $this->generator->generate( $module, @@ -241,49 +212,10 @@ class ModuleCommand extends Command $composer, $dependencies, $test, - $twigtemplate + $twigTemplate ); - } - - /** - * @param array $dependencies - * @return array - */ - private function checkDependencies(array $dependencies, DrupalStyle $io) - { - $this->site->loadLegacyFile('/core/modules/system/system.module'); - $localModules = []; - - $modules = system_rebuild_module_data(); - foreach ($modules as $module_id => $module) { - array_push($localModules, basename($module->subpath)); - } - - $checkDependencies = [ - 'local_modules' => [], - 'drupal_modules' => [], - 'no_modules' => [], - ]; - - foreach ($dependencies as $module) { - if (in_array($module, $localModules)) { - $checkDependencies['local_modules'][] = $module; - } else { - try { - $response = $this->httpClient->head('https://www.drupal.org/project/' . $module); - $header_link = explode(';', $response->getHeader('link')); - if (empty($header_link[0])) { - $checkDependencies['no_modules'][] = $module; - } else { - $checkDependencies['drupal_modules'][] = $module; - } - } catch (ClientException $e) { - $checkDependencies['no_modules'][] = $module; - } - } - } - return $checkDependencies; + return 0; } /** @@ -303,7 +235,7 @@ class ModuleCommand extends Command } catch (\Exception $error) { $io->error($error->getMessage()); - return; + return 1; } if (!$module) { diff --git a/vendor/drupal/console/src/Command/Generate/ModuleFileCommand.php b/vendor/drupal/console/src/Command/Generate/ModuleFileCommand.php index 33bdf7e5f..3b08b740d 100644 --- a/vendor/drupal/console/src/Command/Generate/ModuleFileCommand.php +++ b/vendor/drupal/console/src/Command/Generate/ModuleFileCommand.php @@ -64,7 +64,7 @@ class ModuleFileCommand extends Command ->setName('generate:module:file') ->setDescription($this->trans('commands.generate.module.file.description')) ->setHelp($this->trans('commands.generate.module.file.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')); + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')); } /** @@ -76,7 +76,7 @@ class ModuleFileCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io, $yes)) { - return; + return 1; } $machine_name = $input->getOption('module'); diff --git a/vendor/drupal/console/src/Command/Generate/PermissionCommand.php b/vendor/drupal/console/src/Command/Generate/PermissionCommand.php index 373d347e4..07ef7172f 100644 --- a/vendor/drupal/console/src/Command/Generate/PermissionCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PermissionCommand.php @@ -70,13 +70,13 @@ class PermissionCommand extends Command ->setHelp($this->trans('commands.generate.permission.help')) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) ->addOption( 'permissions', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.common.options.permissions') ); diff --git a/vendor/drupal/console/src/Command/Generate/PluginBlockCommand.php b/vendor/drupal/console/src/Command/Generate/PluginBlockCommand.php index c32e4ea9d..ff35cb3c2 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginBlockCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginBlockCommand.php @@ -113,40 +113,40 @@ class PluginBlockCommand extends Command ->setName('generate:plugin:block') ->setDescription($this->trans('commands.generate.plugin.block.description')) ->setHelp($this->trans('commands.generate.plugin.block.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.block.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.block.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.block.options.plugin-id') ) ->addOption( 'theme-region', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.block.options.theme-region') ) ->addOption( 'inputs', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.common.options.inputs') ) ->addOption( 'services', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.common.options.services') ); diff --git a/vendor/drupal/console/src/Command/Generate/PluginCKEditorButtonCommand.php b/vendor/drupal/console/src/Command/Generate/PluginCKEditorButtonCommand.php index e6091fdbe..2152dbeac 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginCKEditorButtonCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginCKEditorButtonCommand.php @@ -78,37 +78,37 @@ class PluginCKEditorButtonCommand extends Command ->setHelp($this->trans('commands.generate.plugin.ckeditorbutton.help')) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) ->addOption( 'class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.ckeditorbutton.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.ckeditorbutton.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.ckeditorbutton.options.plugin-id') ) ->addOption( 'button-name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.ckeditorbutton.options.button-name') ) ->addOption( 'button-icon-path', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.ckeditorbutton.options.button-icon-path') ); @@ -123,7 +123,7 @@ class PluginCKEditorButtonCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -138,6 +138,8 @@ class PluginCKEditorButtonCommand extends Command ->generate($module, $class_name, $label, $plugin_id, $button_name, $button_icon_path); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery'], false); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PluginConditionCommand.php b/vendor/drupal/console/src/Command/Generate/PluginConditionCommand.php index 372ee4293..817dff1c1 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginConditionCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginConditionCommand.php @@ -83,40 +83,40 @@ class PluginConditionCommand extends Command ->setName('generate:plugin:condition') ->setDescription($this->trans('commands.generate.plugin.condition.description')) ->setHelp($this->trans('commands.generate.plugin.condition.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.condition.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.condition.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.condition.options.plugin-id') ) ->addOption( 'context-definition-id', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.condition.options.context-definition-id') ) ->addOption( 'context-definition-label', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.condition.options.context-definition-label') ) ->addOption( 'context-definition-required', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.condition.options.context-definition-required') ); @@ -131,7 +131,7 @@ class PluginConditionCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -147,6 +147,8 @@ class PluginConditionCommand extends Command ->generate($module, $class_name, $label, $plugin_id, $context_definition_id, $context_definition_label, $context_definition_required); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PluginFieldCommand.php b/vendor/drupal/console/src/Command/Generate/PluginFieldCommand.php index 3254afed2..664123899 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginFieldCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginFieldCommand.php @@ -65,82 +65,82 @@ class PluginFieldCommand extends Command ->setName('generate:plugin:field') ->setDescription($this->trans('commands.generate.plugin.field.description')) ->setHelp($this->trans('commands.generate.plugin.field.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'type-class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.field.options.type-class') ) ->addOption( 'type-label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.type-label') ) ->addOption( 'type-plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.type-plugin-id') ) ->addOption( 'type-description', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.type-type-description') ) ->addOption( 'formatter-class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.field.options.class') ) ->addOption( 'formatter-label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.formatter-label') ) ->addOption( 'formatter-plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.formatter-plugin-id') ) ->addOption( 'widget-class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.field.options.formatter-class') ) ->addOption( 'widget-label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.widget-label') ) ->addOption( 'widget-plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.widget-plugin-id') ) ->addOption( 'field-type', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.field-type') ) ->addOption( 'default-widget', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.default-widget') ) ->addOption( 'default-formatter', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.field.options.default-formatter') ); @@ -155,7 +155,7 @@ class PluginFieldCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $this->chainQueue @@ -196,6 +196,8 @@ class PluginFieldCommand extends Command ); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery'], false); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PluginFieldFormatterCommand.php b/vendor/drupal/console/src/Command/Generate/PluginFieldFormatterCommand.php index b0e94117c..e930070ef 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginFieldFormatterCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginFieldFormatterCommand.php @@ -88,28 +88,28 @@ class PluginFieldFormatterCommand extends Command ->setName('generate:plugin:fieldformatter') ->setDescription($this->trans('commands.generate.plugin.fieldformatter.description')) ->setHelp($this->trans('commands.generate.plugin.fieldformatter.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.fieldformatter.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldformatter.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldformatter.options.plugin-id') ) ->addOption( 'field-type', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldformatter.options.field-type') ); @@ -124,7 +124,7 @@ class PluginFieldFormatterCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -136,6 +136,8 @@ class PluginFieldFormatterCommand extends Command $this->generator->generate($module, $class_name, $label, $plugin_id, $field_type); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PluginFieldTypeCommand.php b/vendor/drupal/console/src/Command/Generate/PluginFieldTypeCommand.php index d60c4bcb5..5f33c3d7a 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginFieldTypeCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginFieldTypeCommand.php @@ -80,40 +80,40 @@ class PluginFieldTypeCommand extends Command ->setName('generate:plugin:fieldtype') ->setDescription($this->trans('commands.generate.plugin.fieldtype.description')) ->setHelp($this->trans('commands.generate.plugin.fieldtype.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.fieldtype.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldtype.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldtype.options.plugin-id') ) ->addOption( 'description', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldtype.options.description') ) ->addOption( 'default-widget', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldtype.options.default-widget') ) ->addOption( 'default-formatter', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldtype.options.default-formatter') ); @@ -128,7 +128,7 @@ class PluginFieldTypeCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -143,6 +143,8 @@ class PluginFieldTypeCommand extends Command ->generate($module, $class_name, $label, $plugin_id, $description, $default_widget, $default_formatter); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery'], false); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PluginFieldWidgetCommand.php b/vendor/drupal/console/src/Command/Generate/PluginFieldWidgetCommand.php index 89817bcad..48618defd 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginFieldWidgetCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginFieldWidgetCommand.php @@ -93,28 +93,28 @@ class PluginFieldWidgetCommand extends Command ->setName('generate:plugin:fieldwidget') ->setDescription($this->trans('commands.generate.plugin.fieldwidget.description')) ->setHelp($this->trans('commands.generate.plugin.fieldwidget.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.fieldwidget.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldwidget.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldwidget.options.plugin-id') ) ->addOption( 'field-type', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.fieldwidget.options.field-type') ); @@ -129,7 +129,7 @@ class PluginFieldWidgetCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -141,6 +141,8 @@ class PluginFieldWidgetCommand extends Command $this->generator->generate($module, $class_name, $label, $plugin_id, $field_type); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PluginImageEffectCommand.php b/vendor/drupal/console/src/Command/Generate/PluginImageEffectCommand.php index d66a90421..1a0fc1ce4 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginImageEffectCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginImageEffectCommand.php @@ -79,28 +79,28 @@ class PluginImageEffectCommand extends Command ->setName('generate:plugin:imageeffect') ->setDescription($this->trans('commands.generate.plugin.imageeffect.description')) ->setHelp($this->trans('commands.generate.plugin.imageeffect.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.imageeffect.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.imageeffect.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.imageeffect.options.plugin-id') ) ->addOption( 'description', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.imageeffect.options.description') ); @@ -115,7 +115,7 @@ class PluginImageEffectCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); diff --git a/vendor/drupal/console/src/Command/Generate/PluginImageFormatterCommand.php b/vendor/drupal/console/src/Command/Generate/PluginImageFormatterCommand.php index 9672a97e1..8fb340053 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginImageFormatterCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginImageFormatterCommand.php @@ -83,22 +83,22 @@ class PluginImageFormatterCommand extends Command ->setName('generate:plugin:imageformatter') ->setDescription($this->trans('commands.generate.plugin.imageformatter.description')) ->setHelp($this->trans('commands.generate.plugin.imageformatter.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.imageformatter.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.imageformatter.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.imageformatter.options.plugin-id') ); @@ -113,7 +113,7 @@ class PluginImageFormatterCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); diff --git a/vendor/drupal/console/src/Command/Generate/PluginMailCommand.php b/vendor/drupal/console/src/Command/Generate/PluginMailCommand.php index 73cd2f75d..48a47d0d6 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginMailCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginMailCommand.php @@ -92,28 +92,28 @@ class PluginMailCommand extends Command ->setName('generate:plugin:mail') ->setDescription($this->trans('commands.generate.plugin.mail.description')) ->setHelp($this->trans('commands.generate.plugin.mail.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.mail.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.mail.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.mail.options.plugin-id') ) ->addOption( 'services', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.common.options.services') ); diff --git a/vendor/drupal/console/src/Command/Generate/PluginMigrateProcessCommand.php b/vendor/drupal/console/src/Command/Generate/PluginMigrateProcessCommand.php index fccd9e35b..20ba70a60 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginMigrateProcessCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginMigrateProcessCommand.php @@ -73,16 +73,16 @@ class PluginMigrateProcessCommand extends Command ->setName('generate:plugin:migrate:process') ->setDescription($this->trans('commands.generate.plugin.migrate.process.description')) ->setHelp($this->trans('commands.generate.plugin.migrate.process.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.migrate.process.options.class') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.migrate.process.options.plugin-id') ); diff --git a/vendor/drupal/console/src/Command/Generate/PluginMigrateSourceCommand.php b/vendor/drupal/console/src/Command/Generate/PluginMigrateSourceCommand.php index 0bd731479..5de03cccf 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginMigrateSourceCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginMigrateSourceCommand.php @@ -109,40 +109,40 @@ class PluginMigrateSourceCommand extends Command ->setName('generate:plugin:migrate:source') ->setDescription($this->trans('commands.generate.plugin.migrate.source.description')) ->setHelp($this->trans('commands.generate.plugin.migrate.source.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.migrate.source.options.class') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.migrate.source.options.plugin-id') ) ->addOption( 'table', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.migrate.source.options.table') ) ->addOption( 'alias', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.migrate.source.options.alias') ) ->addOption( 'group-by', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.migrate.source.options.group-by') ) ->addOption( 'fields', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.generate.plugin.migrate.source.options.fields') ); diff --git a/vendor/drupal/console/src/Command/Generate/PluginRestResourceCommand.php b/vendor/drupal/console/src/Command/Generate/PluginRestResourceCommand.php index aa187a23d..dfc7ce1ee 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginRestResourceCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginRestResourceCommand.php @@ -83,10 +83,10 @@ class PluginRestResourceCommand extends Command ->setName('generate:plugin:rest:resource') ->setDescription($this->trans('commands.generate.plugin.rest.resource.description')) ->setHelp($this->trans('commands.generate.plugin.rest.resource.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.rest.resource.options.class') ) @@ -98,25 +98,25 @@ class PluginRestResourceCommand extends Command ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.rest.resource.options.plugin-id') ) ->addOption( 'plugin-label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.rest.resource.options.plugin-label') ) ->addOption( 'plugin-url', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.generate.plugin.rest.resource.options.plugin-url') ) ->addOption( 'plugin-states', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.generate.plugin.rest.resource.options.plugin-states') ); @@ -131,7 +131,7 @@ class PluginRestResourceCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -144,6 +144,8 @@ class PluginRestResourceCommand extends Command $this->generator->generate($module, $class_name, $plugin_label, $plugin_id, $plugin_url, $plugin_states); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PluginRulesActionCommand.php b/vendor/drupal/console/src/Command/Generate/PluginRulesActionCommand.php index 4163e51ad..43785e3d5 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginRulesActionCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginRulesActionCommand.php @@ -83,35 +83,35 @@ class PluginRulesActionCommand extends Command ->setName('generate:plugin:rulesaction') ->setDescription($this->trans('commands.generate.plugin.rulesaction.description')) ->setHelp($this->trans('commands.generate.plugin.rulesaction.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.rulesaction.options.class') ) ->addOption( 'label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.rulesaction.options.label') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.rulesaction.options.plugin-id') ) - ->addOption('type', '', InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.rulesaction.options.type')) + ->addOption('type', null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.rulesaction.options.type')) ->addOption( 'category', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.generate.plugin.rulesaction.options.category') ) ->addOption( 'context', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.rulesaction.options.context') ); @@ -126,7 +126,7 @@ class PluginRulesActionCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -140,6 +140,8 @@ class PluginRulesActionCommand extends Command $this->generator->generate($module, $class_name, $label, $plugin_id, $category, $context, $type); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PluginSkeletonCommand.php b/vendor/drupal/console/src/Command/Generate/PluginSkeletonCommand.php index 39494b501..f1fb5ee18 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginSkeletonCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginSkeletonCommand.php @@ -103,25 +103,25 @@ class PluginSkeletonCommand extends Command ->setHelp($this->trans('commands.generate.plugin.skeleton.help')) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) ->addOption( 'plugin-id', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.options.plugin-id') ) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.block.options.class') ) ->addOption( 'services', - '', + null, InputOption::VALUE_OPTIONAL| InputOption::VALUE_IS_ARRAY, $this->trans('commands.common.options.services') ); @@ -137,7 +137,7 @@ class PluginSkeletonCommand extends Command // @see use Drupal\Console\Command\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -175,6 +175,8 @@ class PluginSkeletonCommand extends Command $this->generator->generate($module, $pluginId, $plugin, $className, $pluginMetaData, $buildServices); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PluginTypeAnnotationCommand.php b/vendor/drupal/console/src/Command/Generate/PluginTypeAnnotationCommand.php index 5462596de..109cb2103 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginTypeAnnotationCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginTypeAnnotationCommand.php @@ -73,22 +73,22 @@ class PluginTypeAnnotationCommand extends Command ->setName('generate:plugin:type:annotation') ->setDescription($this->trans('commands.generate.plugin.type.annotation.description')) ->setHelp($this->trans('commands.generate.plugin.type.annotation.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.type.annotation.options.class') ) ->addOption( 'machine-name', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.type.annotation.options.plugin-id') ) ->addOption( 'label', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.type.annotation.options.label') ); diff --git a/vendor/drupal/console/src/Command/Generate/PluginTypeYamlCommand.php b/vendor/drupal/console/src/Command/Generate/PluginTypeYamlCommand.php index 6295481f9..58e79cdee 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginTypeYamlCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginTypeYamlCommand.php @@ -74,22 +74,22 @@ class PluginTypeYamlCommand extends Command ->setName('generate:plugin:type:yaml') ->setDescription($this->trans('commands.generate.plugin.type.yaml.description')) ->setHelp($this->trans('commands.generate.plugin.type.yaml.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.type.yaml.options.class') ) ->addOption( 'plugin-name', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.type.yaml.options.plugin-name') ) ->addOption( 'plugin-file-name', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.type.yaml.options.plugin-file-name') ); diff --git a/vendor/drupal/console/src/Command/Generate/PluginViewsFieldCommand.php b/vendor/drupal/console/src/Command/Generate/PluginViewsFieldCommand.php index c0962a2b7..0dab88a7a 100644 --- a/vendor/drupal/console/src/Command/Generate/PluginViewsFieldCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PluginViewsFieldCommand.php @@ -88,22 +88,22 @@ class PluginViewsFieldCommand extends Command ->setName('generate:plugin:views:field') ->setDescription($this->trans('commands.generate.plugin.views.field.description')) ->setHelp($this->trans('commands.generate.plugin.views.field.help')) - ->addOption('module', '', InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) + ->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module')) ->addOption( 'class', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.plugin.views.field.options.class') ) ->addOption( 'title', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.views.field.options.title') ) ->addOption( 'description', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.plugin.views.field.options.description') ); @@ -118,7 +118,7 @@ class PluginViewsFieldCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -130,6 +130,8 @@ class PluginViewsFieldCommand extends Command $this->generator->generate($module, $class_machine_name, $class_name, $title, $description); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/PostUpdateCommand.php b/vendor/drupal/console/src/Command/Generate/PostUpdateCommand.php index 0a0fba1ad..180a70c0d 100644 --- a/vendor/drupal/console/src/Command/Generate/PostUpdateCommand.php +++ b/vendor/drupal/console/src/Command/Generate/PostUpdateCommand.php @@ -89,13 +89,13 @@ class PostUpdateCommand extends Command ->setHelp($this->trans('commands.generate.post.update.help')) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) ->addOption( 'post-update-name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.post.update.options.post-update-name') ); @@ -110,7 +110,7 @@ class PostUpdateCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -121,6 +121,8 @@ class PostUpdateCommand extends Command $this->generator->generate($module, $postUpdateName); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Generate/ProfileCommand.php b/vendor/drupal/console/src/Command/Generate/ProfileCommand.php index f04a3ea09..5dfbe1509 100644 --- a/vendor/drupal/console/src/Command/Generate/ProfileCommand.php +++ b/vendor/drupal/console/src/Command/Generate/ProfileCommand.php @@ -18,8 +18,6 @@ use Drupal\Console\Core\Command\Shared\CommandTrait; use Drupal\Console\Extension\Manager; use Drupal\Console\Core\Utils\StringConverter; use Drupal\Console\Utils\Validator; -use Drupal\Console\Utils\Site; -use GuzzleHttp\Client; /** * Class ProfileCommand @@ -33,13 +31,13 @@ class ProfileCommand extends Command use CommandTrait; /** - * @var Manager -*/ + * @var Manager + */ protected $extensionManager; /** - * @var ProfileGenerator -*/ + * @var ProfileGenerator + */ protected $generator; /** @@ -48,19 +46,9 @@ class ProfileCommand extends Command protected $stringConverter; /** - * @var Validator -*/ - protected $validator; - - /** - * @var Site + * @var Validator */ - protected $site; - - /** - * @var Client - */ - protected $httpClient; + protected $validator; /** * ProfileCommand constructor. @@ -70,25 +58,19 @@ class ProfileCommand extends Command * @param StringConverter $stringConverter * @param Validator $validator * @param $appRoot - * @param Site $site - * @param Client $httpClient */ public function __construct( Manager $extensionManager, ProfileGenerator $generator, StringConverter $stringConverter, Validator $validator, - $appRoot, - Site $site, - Client $httpClient + $appRoot ) { $this->extensionManager = $extensionManager; $this->generator = $generator; $this->stringConverter = $stringConverter; $this->validator = $validator; $this->appRoot = $appRoot; - $this->site = $site; - $this->httpClient = $httpClient; parent::__construct(); } @@ -103,37 +85,45 @@ class ProfileCommand extends Command ->setHelp($this->trans('commands.generate.profile.help')) ->addOption( 'profile', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.profile.options.profile') ) ->addOption( 'machine-name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.profile.options.machine-name') ) ->addOption( 'description', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.profile.options.description') ) ->addOption( 'core', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.profile.options.core') ) ->addOption( 'dependencies', - false, + null, InputOption::VALUE_OPTIONAL, - $this->trans('commands.generate.profile.options.dependencies') + $this->trans('commands.generate.profile.options.dependencies'), + '' + ) + ->addOption( + 'themes', + null, + InputOption::VALUE_OPTIONAL, + $this->trans('commands.generate.profile.options.themes'), + '' ) ->addOption( 'distribution', - false, + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.profile.options.distribution') ); @@ -147,31 +137,18 @@ class ProfileCommand extends Command $io = new DrupalStyle($input, $output); if (!$this->confirmGeneration($io)) { - return; + return 1; } $profile = $this->validator->validateModuleName($input->getOption('profile')); $machine_name = $this->validator->validateMachineName($input->getOption('machine-name')); $description = $input->getOption('description'); $core = $input->getOption('core'); + $dependencies = $this->validator->validateExtensions($input->getOption('dependencies'), 'module', $io); + $themes = $this->validator->validateExtensions($input->getOption('themes'), 'theme', $io); $distribution = $input->getOption('distribution'); $profile_path = $this->appRoot . '/profiles'; - // Check if all module dependencies are available. - $dependencies = $this->validator->validateModuleDependencies($input->getOption('dependencies')); - if ($dependencies) { - $checked_dependencies = $this->checkDependencies($dependencies['success']); - if (!empty($checked_dependencies['no_modules'])) { - $io->info( - sprintf( - $this->trans('commands.generate.profile.warnings.module-unavailable'), - implode(', ', $checked_dependencies['no_modules']) - ) - ); - } - $dependencies = $dependencies['success']; - } - $this->generator->generate( $profile, $machine_name, @@ -179,47 +156,11 @@ class ProfileCommand extends Command $description, $core, $dependencies, + $themes, $distribution ); } - /** - * @param array $dependencies - * @return array - */ - private function checkDependencies(array $dependencies) - { - $this->site->loadLegacyFile('/core/modules/system/system.module'); - $local_modules = []; - - $modules = system_rebuild_module_data(); - foreach ($modules as $module_id => $module) { - array_push($local_modules, basename($module->subpath)); - } - - $checked_dependencies = [ - 'local_modules' => [], - 'drupal_modules' => [], - 'no_modules' => [], - ]; - - foreach ($dependencies as $module) { - if (in_array($module, $local_modules)) { - $checked_dependencies['local_modules'][] = $module; - } else { - $response = $this->httpClient->head('https://www.drupal.org/project/' . $module); - $header_link = explode(';', $response->getHeader('link')); - if (empty($header_link[0])) { - $checked_dependencies['no_modules'][] = $module; - } else { - $checked_dependencies['drupal_modules'][] = $module; - } - } - } - - return $checked_dependencies; - } - /** * {@inheritdoc} */ @@ -237,7 +178,7 @@ class ProfileCommand extends Command } catch (\Exception $error) { $io->error($error->getMessage()); - return; + return 1; } if (!$profile) { @@ -256,7 +197,7 @@ class ProfileCommand extends Command } catch (\Exception $error) { $io->error($error->getMessage()); - return; + return 1; } if (!$machine_name) { diff --git a/vendor/drupal/console/src/Command/Generate/RouteSubscriberCommand.php b/vendor/drupal/console/src/Command/Generate/RouteSubscriberCommand.php index 505b64e94..1085ea469 100644 --- a/vendor/drupal/console/src/Command/Generate/RouteSubscriberCommand.php +++ b/vendor/drupal/console/src/Command/Generate/RouteSubscriberCommand.php @@ -101,7 +101,7 @@ class RouteSubscriberCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($output)) { - return; + return 1; } $module = $input->getOption('module'); @@ -111,6 +111,8 @@ class RouteSubscriberCommand extends Command $this->generator->generate($module, $name, $class); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']); + + return 0; } /** diff --git a/vendor/drupal/console/src/Command/Generate/ServiceCommand.php b/vendor/drupal/console/src/Command/Generate/ServiceCommand.php index e71edc113..8106f1523 100644 --- a/vendor/drupal/console/src/Command/Generate/ServiceCommand.php +++ b/vendor/drupal/console/src/Command/Generate/ServiceCommand.php @@ -104,13 +104,13 @@ class ServiceCommand extends Command ) ->addOption( 'interface', - false, + null, InputOption::VALUE_NONE, $this->trans('commands.common.service.options.interface') ) ->addOption( 'interface_name', - false, + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.common.service.options.interface_name') ) @@ -137,7 +137,7 @@ class ServiceCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -164,6 +164,8 @@ class ServiceCommand extends Command $this->generator->generate($module, $name, $class, $interface, $interface_name, $build_services, $path_service); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']); + + return 0; } /** diff --git a/vendor/drupal/console/src/Command/Generate/ThemeCommand.php b/vendor/drupal/console/src/Command/Generate/ThemeCommand.php index e70143574..4ec9a7509 100644 --- a/vendor/drupal/console/src/Command/Generate/ThemeCommand.php +++ b/vendor/drupal/console/src/Command/Generate/ThemeCommand.php @@ -112,56 +112,62 @@ class ThemeCommand extends Command ->setHelp($this->trans('commands.generate.theme.help')) ->addOption( 'theme', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.theme.options.module') ) ->addOption( 'machine-name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.theme.options.machine-name') ) ->addOption( 'theme-path', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.theme.options.module-path') ) ->addOption( 'description', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.theme.options.description') ) - ->addOption('core', '', InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.theme.options.core')) + ->addOption('core', null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.theme.options.core')) ->addOption( 'package', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.theme.options.package') ) ->addOption( 'global-library', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.theme.options.global-library') ) + ->addOption( + 'libraries', + null, + InputOption::VALUE_OPTIONAL, + $this->trans('commands.generate.theme.options.libraries') + ) ->addOption( 'base-theme', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.theme.options.base-theme') ) ->addOption( 'regions', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.theme.options.regions') ) ->addOption( 'breakpoints', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.generate.theme.options.breakpoints') ); @@ -176,7 +182,7 @@ class ThemeCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $theme = $this->validator->validateModuleName($input->getOption('theme')); @@ -189,6 +195,7 @@ class ThemeCommand extends Command $package = $input->getOption('package'); $base_theme = $input->getOption('base-theme'); $global_library = $input->getOption('global-library'); + $libraries = $input->getOption('libraries'); $regions = $input->getOption('regions'); $breakpoints = $input->getOption('breakpoints'); @@ -201,9 +208,12 @@ class ThemeCommand extends Command $package, $base_theme, $global_library, + $libraries, $regions, $breakpoints ); + + return 0; } /** @@ -218,7 +228,7 @@ class ThemeCommand extends Command } catch (\Exception $error) { $io->error($error->getMessage()); - return; + return 1; } if (!$theme) { @@ -238,7 +248,7 @@ class ThemeCommand extends Command } catch (\Exception $error) { $io->error($error->getMessage()); - return; + return 1; } if (!$machine_name) { @@ -326,6 +336,21 @@ class ThemeCommand extends Command $input->setOption('global-library', $global_library); } + + // --libraries option. + $libraries = $input->getOption('libraries'); + if (!$libraries) { + if ($io->confirm( + $this->trans('commands.generate.theme.questions.library-add'), + true + ) + ) { + // @see \Drupal\Console\Command\Shared\ThemeRegionTrait::libraryQuestion + $libraries = $this->libraryQuestion($io); + $input->setOption('libraries', $libraries); + } + } + // --regions option. $regions = $input->getOption('regions'); if (!$regions) { diff --git a/vendor/drupal/console/src/Command/Generate/TwigExtensionCommand.php b/vendor/drupal/console/src/Command/Generate/TwigExtensionCommand.php index 843803d4a..182f408b8 100644 --- a/vendor/drupal/console/src/Command/Generate/TwigExtensionCommand.php +++ b/vendor/drupal/console/src/Command/Generate/TwigExtensionCommand.php @@ -126,7 +126,7 @@ class TwigExtensionCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -136,13 +136,14 @@ class TwigExtensionCommand extends Command // Add renderer service as first parameter. array_unshift($services, 'renderer'); - // @see Drupal\Console\Command\Shared\ServicesTrait::buildServices $build_services = $this->buildServices($services); $this->generator->generate($module, $name, $class, $build_services); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']); + + return 0; } /** diff --git a/vendor/drupal/console/src/Command/Generate/UpdateCommand.php b/vendor/drupal/console/src/Command/Generate/UpdateCommand.php index dd1f4eea5..923970a7e 100644 --- a/vendor/drupal/console/src/Command/Generate/UpdateCommand.php +++ b/vendor/drupal/console/src/Command/Generate/UpdateCommand.php @@ -81,13 +81,13 @@ class UpdateCommand extends Command ->setHelp($this->trans('commands.generate.update.help')) ->addOption( 'module', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module') ) ->addOption( 'update-n', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.generate.update.options.update-n') ); @@ -102,7 +102,7 @@ class UpdateCommand extends Command // @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmGeneration if (!$this->confirmGeneration($io)) { - return; + return 1; } $module = $input->getOption('module'); @@ -122,6 +122,8 @@ class UpdateCommand extends Command $this->generator->generate($module, $updateNumber); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']); + + return 0; } protected function interact(InputInterface $input, OutputInterface $output) diff --git a/vendor/drupal/console/src/Command/Locale/TranslationStatusCommand.php b/vendor/drupal/console/src/Command/Locale/TranslationStatusCommand.php index 2d92e833d..95ed676fd 100644 --- a/vendor/drupal/console/src/Command/Locale/TranslationStatusCommand.php +++ b/vendor/drupal/console/src/Command/Locale/TranslationStatusCommand.php @@ -86,11 +86,14 @@ class TranslationStatusCommand extends Command if (!$languages) { $io->info($this->trans('commands.locale.translation.status.messages.no-languages')); - return; - } elseif (empty($status)) { + return 1; + } + + if (empty($status)) { $io->info($this->trans('commands.locale.translation.status.messages.no-translations')); - return; + return 1; } + if ($languages) { $projectsStatus = $this->projectsStatus(); @@ -109,5 +112,7 @@ class TranslationStatusCommand extends Command $io->table($tableHeader, $tableRows, 'compact'); } } + + return 0; } } diff --git a/vendor/drupal/console/src/Command/Migrate/ExecuteCommand.php b/vendor/drupal/console/src/Command/Migrate/ExecuteCommand.php index 325f85515..1c4fb2587 100644 --- a/vendor/drupal/console/src/Command/Migrate/ExecuteCommand.php +++ b/vendor/drupal/console/src/Command/Migrate/ExecuteCommand.php @@ -47,13 +47,6 @@ class ExecuteCommand extends Command parent::__construct(); } - /** - * @DrupalCommand( - * dependencies = { - * "migrate" - * } - * ) - */ protected function configure() { $this @@ -62,62 +55,62 @@ class ExecuteCommand extends Command ->addArgument('migration-ids', InputArgument::IS_ARRAY, $this->trans('commands.migrate.execute.arguments.id')) ->addOption( 'site-url', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.execute.options.site-url') ) ->addOption( 'db-type', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.setup.migrations.options.db-type') ) ->addOption( 'db-host', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.execute.options.db-host') ) ->addOption( 'db-name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.execute.options.db-name') ) ->addOption( 'db-user', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.execute.options.db-user') ) ->addOption( 'db-pass', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.execute.options.db-pass') ) ->addOption( 'db-prefix', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.execute.options.db-prefix') ) ->addOption( 'db-port', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.execute.options.db-port') ) ->addOption( 'exclude', - '', + null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $this->trans('commands.migrate.execute.options.exclude'), [] ) ->addOption( 'source-base_path', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.execute.options.source-base_path') ); @@ -204,7 +197,7 @@ class ExecuteCommand extends Command if (!$drupal_version = $this->getLegacyDrupalVersion($this->migrateConnection)) { $io->error($this->trans('commands.migrate.setup.migrations.questions.not-drupal')); - return; + return 1; } $database = $this->getDBInfo(); @@ -294,7 +287,7 @@ class ExecuteCommand extends Command // If migrations weren't provided finish execution if (empty($migration_ids)) { - return; + return 1; } if (!$this->migrateConnection) { @@ -304,7 +297,7 @@ class ExecuteCommand extends Command if (!$drupal_version = $this->getLegacyDrupalVersion($this->migrateConnection)) { $io->error($this->trans('commands.migrate.setup.migrations.questions.not-drupal')); - return; + return 1; } $version_tag = 'Drupal ' . $drupal_version; @@ -322,7 +315,7 @@ class ExecuteCommand extends Command if (count($migrations) == 0) { $io->error($this->trans('commands.migrate.execute.messages.no-migrations')); - return; + return 1; } foreach ($migrations as $migration_id) { @@ -386,7 +379,11 @@ class ExecuteCommand extends Command } } else { $io->error($this->trans('commands.migrate.execute.messages.fail-load')); + + return 1; } } + + return 0; } } diff --git a/vendor/drupal/console/src/Command/Migrate/RollBackCommand.php b/vendor/drupal/console/src/Command/Migrate/RollBackCommand.php index 1d0b3a6d9..91a2fe202 100644 --- a/vendor/drupal/console/src/Command/Migrate/RollBackCommand.php +++ b/vendor/drupal/console/src/Command/Migrate/RollBackCommand.php @@ -58,7 +58,7 @@ class RollBackCommand extends Command ->addArgument('migration-ids', InputArgument::IS_ARRAY, $this->trans('commands.migrate.rollback.arguments.id')) ->addOption( 'source-base_path', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.setup.options.source-base_path') ); @@ -75,7 +75,7 @@ class RollBackCommand extends Command $migrations_list = array_keys($this->getMigrations($version_tag)); // If migrations weren't provided finish execution if (empty($migration_id)) { - return; + return 1; } @@ -129,6 +129,8 @@ class RollBackCommand extends Command } } } + + return 0; } /** diff --git a/vendor/drupal/console/src/Command/Migrate/SetupCommand.php b/vendor/drupal/console/src/Command/Migrate/SetupCommand.php index 738c5eb43..4430d9387 100644 --- a/vendor/drupal/console/src/Command/Migrate/SetupCommand.php +++ b/vendor/drupal/console/src/Command/Migrate/SetupCommand.php @@ -56,49 +56,49 @@ class SetupCommand extends Command ->setDescription($this->trans('commands.migrate.setup.description')) ->addOption( 'db-type', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.setup.options.db-type') ) ->addOption( 'db-host', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.setup.options.db-host') ) ->addOption( 'db-name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.setup.options.db-name') ) ->addOption( 'db-user', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.setup.options.db-user') ) ->addOption( 'db-pass', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.setup.options.db-pass') ) ->addOption( 'db-prefix', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.setup.options.db-prefix') ) ->addOption( 'db-port', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.migrate.setup.options.db-port') ) ->addOption( 'source-base_path', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.setup.options.source-base_path') ); @@ -183,7 +183,7 @@ class SetupCommand extends Command if (!$drupal_version = $this->getLegacyDrupalVersion($this->migrateConnection)) { $io->error($this->trans('commands.migrate.setup.migrations.questions.not-drupal')); - return; + return 1; } $database = $this->getDBInfo(); @@ -202,5 +202,7 @@ class SetupCommand extends Command ) ); } + + return 0; } } diff --git a/vendor/drupal/console/src/Command/Module/DownloadCommand.php b/vendor/drupal/console/src/Command/Module/DownloadCommand.php index 09aa2e1df..cf799cb4b 100644 --- a/vendor/drupal/console/src/Command/Module/DownloadCommand.php +++ b/vendor/drupal/console/src/Command/Module/DownloadCommand.php @@ -122,19 +122,19 @@ class DownloadCommand extends Command ) ->addOption( 'latest', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.download.options.latest') ) ->addOption( 'composer', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.install.options.composer') ) ->addOption( 'unstable', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.install.options.unstable') ); diff --git a/vendor/drupal/console/src/Command/Module/InstallCommand.php b/vendor/drupal/console/src/Command/Module/InstallCommand.php index 969cad245..1d3f6da19 100644 --- a/vendor/drupal/console/src/Command/Module/InstallCommand.php +++ b/vendor/drupal/console/src/Command/Module/InstallCommand.php @@ -13,7 +13,6 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\ProcessBuilder; -use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Console\Command\Command; use Drupal\Console\Command\Shared\ProjectDownloadTrait; use Drupal\Console\Command\Shared\ModuleTrait; @@ -42,23 +41,23 @@ class InstallCommand extends Command protected $site; /** - * @var Validator -*/ + * @var Validator + */ protected $validator; /** - * @var ModuleInstaller -*/ + * @var ModuleInstaller + */ protected $moduleInstaller; /** - * @var DrupalApi -*/ + * @var DrupalApi + */ protected $drupalApi; /** - * @var Manager -*/ + * @var Manager + */ protected $extensionManager; /** @@ -116,13 +115,13 @@ class InstallCommand extends Command ) ->addOption( 'latest', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.install.options.latest') ) ->addOption( 'composer', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.uninstall.options.composer') ); @@ -187,8 +186,6 @@ class InstallCommand extends Command ) ); throw new \RuntimeException($process->getErrorOutput()); - - return 0; } } @@ -241,6 +238,7 @@ class InstallCommand extends Command return 1; } + $this->site->removeCachedServicesFile(); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']); } } diff --git a/vendor/drupal/console/src/Command/Module/PathCommand.php b/vendor/drupal/console/src/Command/Module/PathCommand.php index a716cde0c..ff1500852 100644 --- a/vendor/drupal/console/src/Command/Module/PathCommand.php +++ b/vendor/drupal/console/src/Command/Module/PathCommand.php @@ -50,7 +50,7 @@ class PathCommand extends Command ) ->addOption( 'absolute', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.path.options.absolute') ); diff --git a/vendor/drupal/console/src/Command/Module/UninstallCommand.php b/vendor/drupal/console/src/Command/Module/UninstallCommand.php index c5d8fac20..6b8bfae37 100755 --- a/vendor/drupal/console/src/Command/Module/UninstallCommand.php +++ b/vendor/drupal/console/src/Command/Module/UninstallCommand.php @@ -8,6 +8,7 @@ namespace Drupal\Console\Command\Module; use Drupal\Console\Core\Command\Shared\CommandTrait; +use Drupal\Console\Extension\Manager; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -16,7 +17,6 @@ use Symfony\Component\Console\Command\Command; use Drupal\Console\Command\Shared\ProjectDownloadTrait; use Drupal\Console\Core\Style\DrupalStyle; use Drupal\Console\Utils\Site; -use Drupal\Console\Utils\Validator; use Drupal\Core\ProxyClass\Extension\ModuleInstaller; use Drupal\Console\Core\Utils\ChainQueue; use Drupal\Core\Config\ConfigFactory; @@ -32,8 +32,8 @@ class UninstallCommand extends Command protected $site; /** - * @var ModuleInstaller -*/ + * @var ModuleInstaller + */ protected $moduleInstaller; /** @@ -42,29 +42,36 @@ class UninstallCommand extends Command protected $chainQueue; /** - * @var ConfigFactory -*/ + * @var ConfigFactory + */ protected $configFactory; + /** + * @var Manager + */ + protected $extensionManager; /** * InstallCommand constructor. * - * @param Site $site - * @param Validator $validator - * @param ChainQueue $chainQueue - * @param ConfigFactory $configFactory + * @param Site $site + * @param ModuleInstaller $moduleInstaller + * @param ChainQueue $chainQueue + * @param ConfigFactory $configFactory + * @param Manager $extensionManager */ public function __construct( Site $site, ModuleInstaller $moduleInstaller, ChainQueue $chainQueue, - ConfigFactory $configFactory + ConfigFactory $configFactory, + Manager $extensionManager ) { $this->site = $site; $this->moduleInstaller = $moduleInstaller; $this->chainQueue = $chainQueue; $this->configFactory = $configFactory; + $this->extensionManager = $extensionManager; parent::__construct(); } @@ -83,13 +90,13 @@ class UninstallCommand extends Command ) ->addOption( 'force', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.uninstall.options.force') ) ->addOption( 'composer', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.uninstall.options.composer') ); @@ -209,6 +216,7 @@ class UninstallCommand extends Command return 1; } + $this->site->removeCachedServicesFile(); $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']); } } diff --git a/vendor/drupal/console/src/Command/Module/UpdateCommand.php b/vendor/drupal/console/src/Command/Module/UpdateCommand.php index 76bcf88e6..a443fa851 100644 --- a/vendor/drupal/console/src/Command/Module/UpdateCommand.php +++ b/vendor/drupal/console/src/Command/Module/UpdateCommand.php @@ -59,13 +59,13 @@ class UpdateCommand extends Command ) ->addOption( 'composer', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.update.options.composer') ) ->addOption( 'simulate', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.module.update.options.simulate') ); diff --git a/vendor/drupal/console/src/Command/Multisite/NewCommand.php b/vendor/drupal/console/src/Command/Multisite/NewCommand.php index 5f8bcf1b5..cabaa4306 100644 --- a/vendor/drupal/console/src/Command/Multisite/NewCommand.php +++ b/vendor/drupal/console/src/Command/Multisite/NewCommand.php @@ -70,7 +70,7 @@ class NewCommand extends Command ) ->addOption( 'copy-default', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.multisite.new.options.copy-default') ); @@ -159,7 +159,7 @@ class NewCommand extends Command throw new FileNotFoundException($this->trans('commands.multisite.new.errors.sites-missing')); } - $sites_file_contents .= "\n\$sites['$uri'] = '$this->directory';"; + $sites_file_contents .= "\n\$sites['$this->directory'] = '$this->directory';"; try { $this->fs->dumpFile($this->appRoot . '/sites/sites.php', $sites_file_contents); @@ -183,7 +183,7 @@ class NewCommand extends Command 'sites/default/settings.php' ) ); - return; + return 1; } if ($this->fs->exists($this->appRoot . '/sites/default/files')) { @@ -200,7 +200,7 @@ class NewCommand extends Command 'sites/' . $this->directory . '/files' ) ); - return; + return 1; } } else { $io->warning($this->trans('commands.multisite.new.warnings.missing-files')); @@ -221,7 +221,7 @@ class NewCommand extends Command 'sites/' . $this->directory . '/settings.php' ) ); - return; + return 1; } $this->chmodSettings($io); @@ -255,7 +255,7 @@ class NewCommand extends Command $this->appRoot . '/sites/' . $this->directory . '/settings.php' ) ); - return; + return 1; } } else { $io->error( @@ -264,7 +264,7 @@ class NewCommand extends Command 'sites/default/default.settings.php' ) ); - return; + return 1; } $this->chmodSettings($io); @@ -275,6 +275,8 @@ class NewCommand extends Command $this->directory ) ); + + return 0; } /** @@ -297,6 +299,8 @@ class NewCommand extends Command $this->appRoot . '/sites/' . $this->directory . '/settings.php' ) ); + + return 1; } } } diff --git a/vendor/drupal/console/src/Command/Rest/DebugCommand.php b/vendor/drupal/console/src/Command/Rest/DebugCommand.php index 708920d3d..dcd8a764f 100644 --- a/vendor/drupal/console/src/Command/Rest/DebugCommand.php +++ b/vendor/drupal/console/src/Command/Rest/DebugCommand.php @@ -58,7 +58,7 @@ class DebugCommand extends Command ) ->addOption( 'authorization', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.rest.debug.options.status') ); diff --git a/vendor/drupal/console/src/Command/Rest/DisableCommand.php b/vendor/drupal/console/src/Command/Rest/DisableCommand.php index 3ed293f6c..68d95aab8 100644 --- a/vendor/drupal/console/src/Command/Rest/DisableCommand.php +++ b/vendor/drupal/console/src/Command/Rest/DisableCommand.php @@ -54,13 +54,6 @@ class DisableCommand extends Command parent::__construct(); } - /** - * @DrupalCommand( - * dependencies = { - * “rest" - * } - * ) - */ protected function configure() { $this diff --git a/vendor/drupal/console/src/Command/ServerCommand.php b/vendor/drupal/console/src/Command/ServerCommand.php index 1d7fcb5e2..e306ceeca 100644 --- a/vendor/drupal/console/src/Command/ServerCommand.php +++ b/vendor/drupal/console/src/Command/ServerCommand.php @@ -15,6 +15,7 @@ use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Console\Command\Command; use Drupal\Console\Core\Command\Shared\CommandTrait; use Drupal\Console\Core\Style\DrupalStyle; +use \Drupal\Console\Core\Utils\ConfigurationManager; /** * Class ServerCommand @@ -25,8 +26,14 @@ class ServerCommand extends Command { use CommandTrait; + /** + * @var string + */ protected $appRoot; + /** + * @var ConfigurationManager + */ protected $configurationManager; /** @@ -65,13 +72,12 @@ class ServerCommand extends Command protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); - $learning = $input->hasOption('learning')?$input->getOption('learning'):false; $address = $this->validatePort($input->getArgument('address')); $finder = new PhpExecutableFinder(); if (false === $binary = $finder->find()) { $io->error($this->trans('commands.server.errors.binary')); - return; + return 1; } $router = $this->getRouterPath(); @@ -90,7 +96,7 @@ class ServerCommand extends Command $io->commentBlock( sprintf( $this->trans('commands.server.messages.listening'), - $address + 'http://'.$address ) ); @@ -99,7 +105,10 @@ class ServerCommand extends Command if (!$process->isSuccessful()) { $io->error($process->getErrorOutput()); + return 1; } + + return 0; } /** @@ -107,22 +116,26 @@ class ServerCommand extends Command */ private function getRouterPath() { - $router = sprintf( - '%s/.console/router.php', - $this->configurationManager->getHomeDirectory() - ); - - if (file_exists($router)) { - return $router; - } - - $router = sprintf( - '%s/config/dist/router.php', - $this->configurationManager->getApplicationDirectory() - ); + $routerPath = [ + sprintf( + '%s/.console/router.php', + $this->configurationManager->getHomeDirectory() + ), + sprintf( + '%s/console/router.php', + $this->configurationManager->getApplicationDirectory() + ), + sprintf( + '%s/%s/config/dist/router.php', + $this->configurationManager->getApplicationDirectory(), + DRUPAL_CONSOLE_CORE + ) + ]; - if (file_exists($router)) { - return $router; + foreach ($routerPath as $router) { + if (file_exists($router)) { + return $router; + } } return null; diff --git a/vendor/drupal/console/src/Command/Shared/ExtensionTrait.php b/vendor/drupal/console/src/Command/Shared/ExtensionTrait.php index 982c41167..2afec4963 100644 --- a/vendor/drupal/console/src/Command/Shared/ExtensionTrait.php +++ b/vendor/drupal/console/src/Command/Shared/ExtensionTrait.php @@ -37,7 +37,7 @@ trait ExtensionTrait ->showInstalled() ->showUninstalled() ->showNoCore() - ->getList(); + ->getList(false); } if ($theme) { @@ -45,7 +45,7 @@ trait ExtensionTrait ->showInstalled() ->showUninstalled() ->showNoCore() - ->getList(); + ->getList(false); } if ($profile) { @@ -54,7 +54,7 @@ trait ExtensionTrait ->showUninstalled() ->showNoCore() ->showCore() - ->getList(); + ->getList(false); } $extensions = array_merge( diff --git a/vendor/drupal/console/src/Command/Shared/FeatureTrait.php b/vendor/drupal/console/src/Command/Shared/FeatureTrait.php index 378f4c0a6..32ab9a8e2 100644 --- a/vendor/drupal/console/src/Command/Shared/FeatureTrait.php +++ b/vendor/drupal/console/src/Command/Shared/FeatureTrait.php @@ -138,14 +138,13 @@ trait FeatureTrait } } - // Process only missing or overriden features + // Process only missing or overridden features $components = $overridden; if (empty($components)) { $io->warning( sprintf( - $this->trans('commands.features.import.messages.nothing'), - $components + $this->trans('commands.features.import.messages.nothing') ) ); @@ -168,7 +167,6 @@ trait FeatureTrait foreach ($components as $component) { foreach ($component as $feature) { if (!isset($config[$feature])) { - //Import missing component. $item = $manager->getConfigType($feature); $type = ConfigurationItem::fromConfigStringToConfigType($item['type']); diff --git a/vendor/drupal/console/src/Command/Shared/FormTrait.php b/vendor/drupal/console/src/Command/Shared/FormTrait.php index 1f09f5a80..a6e9085d6 100644 --- a/vendor/drupal/console/src/Command/Shared/FormTrait.php +++ b/vendor/drupal/console/src/Command/Shared/FormTrait.php @@ -126,7 +126,7 @@ trait FormTrait $input_options_output[$key] = "'$value' => \$this->t('".$value."')"; } - $input_options = 'array('.implode(', ', $input_options_output).')'; + $input_options = '['.implode(', ', $input_options_output).']'; } // Description for input diff --git a/vendor/drupal/console/src/Command/Shared/ThemeRegionTrait.php b/vendor/drupal/console/src/Command/Shared/ThemeRegionTrait.php index cf0e2480e..c4bb8ac97 100644 --- a/vendor/drupal/console/src/Command/Shared/ThemeRegionTrait.php +++ b/vendor/drupal/console/src/Command/Shared/ThemeRegionTrait.php @@ -54,4 +54,43 @@ trait ThemeRegionTrait return $regions; } + + /** + * @param DrupalStyle $io + * + * @return mixed + */ + public function libraryQuestion(DrupalStyle $io) + { + $validators = $this->validator; + $libraries = []; + while (true) { + $libraryName = $io->ask( + $this->trans('commands.generate.theme.questions.library-name') + ); + + $libraryVersion = $io->ask( + $this->trans('commands.generate.theme.questions.library-version'), + '1.0' + ); + + array_push( + $libraries, + [ + 'library_name' => $libraryName, + 'library_version'=> $libraryVersion, + ] + ); + + if (!$io->confirm( + $this->trans('commands.generate.theme.questions.library-add'), + true + ) + ) { + break; + } + } + + return $libraries; + } } diff --git a/vendor/drupal/console/src/Command/Site/InstallCommand.php b/vendor/drupal/console/src/Command/Site/InstallCommand.php index 408d5955c..720fd57d9 100644 --- a/vendor/drupal/console/src/Command/Site/InstallCommand.php +++ b/vendor/drupal/console/src/Command/Site/InstallCommand.php @@ -84,91 +84,91 @@ class InstallCommand extends Command ) ->addOption( 'langcode', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.site.install.options.langcode') ) ->addOption( 'db-type', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.site.install.options.db-type') ) ->addOption( 'db-file', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.site.install.options.db-file') ) ->addOption( 'db-host', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.execute.options.db-host') ) ->addOption( 'db-name', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.execute.options.db-name') ) ->addOption( 'db-user', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.execute.options.db-user') ) ->addOption( 'db-pass', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.execute.options.db-pass') ) ->addOption( 'db-prefix', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.execute.options.db-prefix') ) ->addOption( 'db-port', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.migrate.execute.options.db-port') ) ->addOption( 'site-name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.site.install.options.site-name') ) ->addOption( 'site-mail', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.site.install.options.site-mail') ) ->addOption( 'account-name', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.site.install.options.account-name') ) ->addOption( 'account-mail', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.site.install.options.account-mail') ) ->addOption( 'account-pass', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.site.install.options.account-pass') ) ->addOption( 'force', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.site.install.options.force') ); @@ -447,10 +447,12 @@ class InstallCommand extends Command $this->getApplication()->setContainer($container); } catch (Exception $e) { $io->error($e->getMessage()); - return; + return 1; } $this->restoreSitesFile($io); + + return 0; } /** @@ -461,32 +463,40 @@ class InstallCommand extends Command * appropriate subdir when run from a script and a sites.php file exists. * * @param DrupalStyle $output + * + * @return boolean */ protected function backupSitesFile(DrupalStyle $output) { if (!file_exists($this->appRoot . '/sites/sites.php')) { - return; + return true; } - rename($this->appRoot . '/sites/sites.php', $this->appRoot . '/sites/backup.sites.php'); + $renamed = rename($this->appRoot . '/sites/sites.php', $this->appRoot . '/sites/backup.sites.php'); $output->info($this->trans('commands.site.install.messages.sites-backup')); + + return $renamed; } /** * Restores backup.sites.php to sites.php (if needed). * * @param DrupalStyle $output + * + * @return boolean */ protected function restoreSitesFile(DrupalStyle $output) { if (!file_exists($this->appRoot . '/sites/backup.sites.php')) { - return; + return true; } - rename($this->appRoot . '/sites/backup.sites.php', $this->appRoot . '/sites/sites.php'); + $renamed = rename($this->appRoot . '/sites/backup.sites.php', $this->appRoot . '/sites/sites.php'); $output->info($this->trans('commands.site.install.messages.sites-restore')); + + return $renamed; } protected function runInstaller( @@ -543,10 +553,10 @@ class InstallCommand extends Command install_drupal($autoload, $settings); } catch (AlreadyInstalledException $e) { $io->error($this->trans('commands.site.install.messages.already-installed')); - return; + return 1; } catch (\Exception $e) { $io->error($e->getMessage()); - return; + return 1; } if (!$this->site->multisiteMode($uri)) { @@ -554,5 +564,7 @@ class InstallCommand extends Command } $io->success($this->trans('commands.site.install.messages.installed')); + + return 0; } } diff --git a/vendor/drupal/console/src/Command/Site/ModeCommand.php b/vendor/drupal/console/src/Command/Site/ModeCommand.php index c791f51c9..a362340df 100644 --- a/vendor/drupal/console/src/Command/Site/ModeCommand.php +++ b/vendor/drupal/console/src/Command/Site/ModeCommand.php @@ -4,17 +4,14 @@ * @file * Contains \Drupal\Console\Command\Site\ModeCommand. */ + namespace Drupal\Console\Command\Site; use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Filesystem\Exception\IOExceptionInterface; use Symfony\Component\Yaml\Yaml; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Filesystem\Filesystem; -use Novia713\Maginot\Maginot; use Drupal\Console\Core\Command\Shared\ContainerAwareCommandTrait; use Drupal\Console\Core\Style\DrupalStyle; use Drupal\Console\Core\Utils\ConfigurationManager; @@ -50,7 +47,7 @@ class ModeCommand extends Command * * @param ConfigFactory $configFactory * @param ConfigurationManager $configurationManager - * @param $appRoot + * @param $appRoot, * @param ChainQueue $chainQueue, */ public function __construct( @@ -63,30 +60,6 @@ class ModeCommand extends Command $this->configurationManager = $configurationManager; $this->appRoot = $appRoot; $this->chainQueue = $chainQueue; - - $this->local = null; - - $this->services_file = - $this->appRoot.'/sites/default/services.yml'; - - $this->local_services_file = - $this->appRoot.'/sites/development.services.yml'; - - $this->settings_file = - $this->appRoot.'/sites/default/settings.php'; - - $this->local_settings_file = - $this->appRoot.'/sites/default/settings.local.php'; - - $this->local_settings_file_original = - $this->appRoot.'/sites/example.settings.local.php'; - - $this->fs = new Filesystem(); - $this->maginot = new Maginot(); - $this->yaml = new Yaml(); - - $this->environment = null; - parent::__construct(); } @@ -99,12 +72,6 @@ class ModeCommand extends Command 'environment', InputArgument::REQUIRED, $this->trans('commands.site.mode.arguments.environment') - ) - ->addOption( - 'local', - null, - InputOption::VALUE_NONE, - $this->trans('commands.site.mode.options.local') ); } @@ -112,24 +79,22 @@ class ModeCommand extends Command { $io = new DrupalStyle($input, $output); - $this->environment = $input->getArgument('environment'); - $this->local = $input->getOption('local'); + $environment = $input->getArgument('environment'); - $loadedConfigurations = []; - if (in_array($this->environment, ['dev', 'prod'])) { - $loadedConfigurations = $this->loadConfigurations($this->environment); - } else { + if (!in_array($environment, ['dev', 'prod'])) { $io->error($this->trans('commands.site.mode.messages.invalid-env')); + return 1; } + $loadedConfigurations = $this->loadConfigurations($environment); + $configurationOverrideResult = $this->overrideConfigurations( - $loadedConfigurations['configurations'], - $io + $loadedConfigurations['configurations'] ); foreach ($configurationOverrideResult as $configName => $result) { $io->info( - $this->trans('commands.site.mode.messages.configuration').':', + $this->trans('commands.site.mode.messages.configuration') . ':', false ); $io->comment($configName); @@ -143,7 +108,8 @@ class ModeCommand extends Command $io->table($tableHeader, $result); } - $servicesOverrideResult = $this->overrideServices( + $servicesOverrideResult = $this->processServicesFile( + $environment, $loadedConfigurations['services'], $io ); @@ -165,7 +131,7 @@ class ModeCommand extends Command $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']); } - protected function overrideConfigurations($configurations, $io) + protected function overrideConfigurations($configurations) { $result = []; foreach ($configurations as $configName => $options) { @@ -173,11 +139,11 @@ class ModeCommand extends Command foreach ($options as $key => $value) { $original = $config->get($key); if (is_bool($original)) { - $original = $original ? 'true' : 'false'; + $original = $original? 'true' : 'false'; } $updated = $value; if (is_bool($updated)) { - $updated = $updated ? 'true' : 'false'; + $updated = $updated? 'true' : 'false'; } $result[$configName][] = [ @@ -190,103 +156,10 @@ class ModeCommand extends Command $config->save(); } - $line_include_settings = - ''; - - if ($this->environment == 'dev') { - - // copy sites/example.settings.local.php sites/default/settings.local.php - $this->fs->copy($this->local_settings_file_original, $this->local_settings_file, true); - - // uncomment cache bins in settings.local.php - $this->maginot->unCommentLine( - '# $settings[\'cache\'][\'bins\'][\'render\'] = \'cache.backend.null\';', - $this->local_settings_file - ); - - $this->maginot->unCommentLine( - '// $settings[\'cache\'][\'bins\'][\'render\'] = \'cache.backend.null\';', - $this->local_settings_file - ); - - $this->maginot->unCommentLine( - '# $settings[\'cache\'][\'bins\'][\'dynamic_page_cache\'] = \'cache.backend.null\';', - $this->local_settings_file - ); - - $this->maginot->unCommentLine( - '// $settings[\'cache\'][\'bins\'][\'dynamic_page_cache\'] = \'cache.backend.null\';', - $this->local_settings_file - ); - - // include settings.local.php in settings.php - // -- check first line if it is already this - if ($this->maginot->getFirstLine($this->settings_file)!= $line_include_settings - ) { - chmod($this->settings_file, (int)0775); - $this->maginot->setFirstLine( - $line_include_settings, - $this->settings_file - ); - } - - $io->commentBlock( - sprintf( - '%s', - $this->trans('commands.site.mode.messages.cachebins') - ) - ); - } - if ($this->environment == 'prod') { - if (!$this->local) { - - // comment local.settings.php in settings.php - if ($this->maginot->getFirstLine($this->settings_file)==$line_include_settings - ) { - $this->maginot->deleteFirstLine( - $this->settings_file - ); - } - - - try { - $this->fs->remove( - $this->local_settings_file - ); - //@TODO: msg user "local.settings.php deleted" - } catch (IOExceptionInterface $e) { - echo $e->getMessage(); - } - } else { - - // comment cache bins in local.settings.php, - // we still use local.settings.php for testing PROD - // settings in local - - $this->maginot->CommentLine( - ' $settings[\'cache\'][\'bins\'][\'render\'] = \'cache.backend.null\';', - $this->local_settings_file - ); - - $this->maginot->CommentLine( - ' $settings[\'cache\'][\'bins\'][\'dynamic_page_cache\'] = \'cache.backend.null\';', - $this->local_settings_file - ); - } - } - - /** - * would be better if this were replaced by $config->save? - */ - //@TODO: 0444 should be a better permission for settings.php - chmod($this->settings_file, (int)0644); - //@TODO: 0555 should be a better permission for sites/default - chmod($this->appRoot.'/sites/default/', (int)0755); - return $result; } - protected function overrideServices($servicesSettings, DrupalStyle $io) + protected function processServicesFile($environment, $servicesSettings, DrupalStyle $io) { $directory = sprintf( '%s/%s', @@ -294,10 +167,11 @@ class ModeCommand extends Command \Drupal::service('site.path') ); - $settingsServicesFile = $directory.'/services.yml'; + $settingsServicesFile = $directory . '/services.yml'; + if (!file_exists($settingsServicesFile)) { // Copying default services - $defaultServicesFile = $this->appRoot.'/sites/default/default.services.yml'; + $defaultServicesFile = $this->appRoot . '/sites/default/default.services.yml'; if (!copy($defaultServicesFile, $settingsServicesFile)) { $io->error( sprintf( @@ -311,7 +185,9 @@ class ModeCommand extends Command } } - $services = $this->yaml->parse(file_get_contents($settingsServicesFile)); + $yaml = new Yaml(); + + $services = $yaml->parse(file_get_contents($settingsServicesFile)); $result = []; foreach ($servicesSettings as $service => $parameters) { @@ -338,7 +214,7 @@ class ModeCommand extends Command } } - if (file_put_contents($settingsServicesFile, $this->yaml->dump($services))) { + if (file_put_contents($settingsServicesFile, $yaml->dump($services))) { $io->commentBlock( sprintf( $this->trans('commands.site.mode.messages.services-file-overwritten'), @@ -358,7 +234,6 @@ class ModeCommand extends Command } sort($result); - return $result; } @@ -372,11 +247,11 @@ class ModeCommand extends Command if (!file_exists($configFile)) { $configFile = sprintf( '%s/config/dist/site.mode.yml', - $this->configurationManager->getApplicationDirectory().DRUPAL_CONSOLE_CORE + $this->configurationManager->getApplicationDirectory() . DRUPAL_CONSOLE_CORE ); } - $siteModeConfiguration = $this->yaml->parse(file_get_contents($configFile)); + $siteModeConfiguration = Yaml::parse(file_get_contents($configFile)); $configKeys = array_keys($siteModeConfiguration); $configurationSettings = []; diff --git a/vendor/drupal/console/src/Command/Site/StatusCommand.php b/vendor/drupal/console/src/Command/Site/StatusCommand.php index 776961b06..c07a758dd 100644 --- a/vendor/drupal/console/src/Command/Site/StatusCommand.php +++ b/vendor/drupal/console/src/Command/Site/StatusCommand.php @@ -116,6 +116,9 @@ class StatusCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { + // Make sure all modules are loaded. + $this->container->get('module_handler')->loadAll(); + $io = new DrupalStyle($input, $output); $systemData = $this->getSystemData(); diff --git a/vendor/drupal/console/src/Command/Test/DebugCommand.php b/vendor/drupal/console/src/Command/Test/DebugCommand.php index e87176ceb..f5a9b2f48 100644 --- a/vendor/drupal/console/src/Command/Test/DebugCommand.php +++ b/vendor/drupal/console/src/Command/Test/DebugCommand.php @@ -59,7 +59,7 @@ class DebugCommand extends Command ) ->addOption( 'test-class', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.test.debug.arguments.test-class') ); diff --git a/vendor/drupal/console/src/Command/Test/RunCommand.php b/vendor/drupal/console/src/Command/Test/RunCommand.php index edeb4c273..f31280105 100644 --- a/vendor/drupal/console/src/Command/Test/RunCommand.php +++ b/vendor/drupal/console/src/Command/Test/RunCommand.php @@ -91,7 +91,7 @@ class RunCommand extends Command ) ->addOption( 'url', - '', + null, InputOption::VALUE_REQUIRED, $this->trans('commands.test.run.arguments.url') ); diff --git a/vendor/drupal/console/src/Command/Theme/DownloadCommand.php b/vendor/drupal/console/src/Command/Theme/DownloadCommand.php index eec5beb37..c12bd52e4 100644 --- a/vendor/drupal/console/src/Command/Theme/DownloadCommand.php +++ b/vendor/drupal/console/src/Command/Theme/DownloadCommand.php @@ -71,7 +71,7 @@ class DownloadCommand extends Command ->addArgument('version', InputArgument::OPTIONAL, $this->trans('commands.theme.download.arguments.version')) ->addOption( 'composer', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.theme.download.options.composer') ); diff --git a/vendor/drupal/console/src/Command/Theme/InstallCommand.php b/vendor/drupal/console/src/Command/Theme/InstallCommand.php index 078307d5d..acb4f8817 100644 --- a/vendor/drupal/console/src/Command/Theme/InstallCommand.php +++ b/vendor/drupal/console/src/Command/Theme/InstallCommand.php @@ -64,7 +64,7 @@ class InstallCommand extends Command ->addArgument('theme', InputArgument::IS_ARRAY, $this->trans('commands.theme.install.options.module')) ->addOption( 'set-default', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.theme.install.options.set-default') ); @@ -132,7 +132,7 @@ class InstallCommand extends Command if ($default && count($theme) > 1) { $io->error($this->trans('commands.theme.install.messages.invalid-theme-default')); - return; + return 1; } $themes = $this->themeHandler->rebuildThemeData(); @@ -188,6 +188,8 @@ class InstallCommand extends Command ) ); drupal_set_message($e->getTranslatedMessage($this->getStringTranslation(), $theme), 'error'); + + return 1; } } elseif (empty($themesAvailable) && count($themesInstalled) > 0) { if (count($themesInstalled) > 1) { @@ -225,5 +227,7 @@ class InstallCommand extends Command // Run cache rebuild to see changes in Web UI $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']); + + return 0; } } diff --git a/vendor/drupal/console/src/Command/Theme/PathCommand.php b/vendor/drupal/console/src/Command/Theme/PathCommand.php index 3cb2fba20..68ad53bd7 100644 --- a/vendor/drupal/console/src/Command/Theme/PathCommand.php +++ b/vendor/drupal/console/src/Command/Theme/PathCommand.php @@ -50,7 +50,7 @@ class PathCommand extends Command ) ->addOption( 'absolute', - '', + null, InputOption::VALUE_NONE, $this->trans('commands.theme.path.options.absolute') ); diff --git a/vendor/drupal/console/src/Command/Theme/UninstallCommand.php b/vendor/drupal/console/src/Command/Theme/UninstallCommand.php index 7561aec24..b15930b54 100644 --- a/vendor/drupal/console/src/Command/Theme/UninstallCommand.php +++ b/vendor/drupal/console/src/Command/Theme/UninstallCommand.php @@ -146,7 +146,7 @@ class UninstallCommand extends Command ) ); - return; + return 1; } if ($themeKey === $config->get('admin')) { @@ -156,7 +156,7 @@ class UninstallCommand extends Command implode(',', $themesAvailable) ) ); - return; + return 1; } } @@ -185,6 +185,8 @@ class UninstallCommand extends Command ) ); drupal_set_message($e->getTranslatedMessage($this->getStringTranslation(), $theme), 'error'); + + return 1; } } elseif (empty($themesAvailable) && count($themesUninstalled) > 0) { if (count($themesUninstalled) > 1) { @@ -222,5 +224,7 @@ class UninstallCommand extends Command // Run cache rebuild to see changes in Web UI $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']); + + return 0; } } diff --git a/vendor/drupal/console/src/Command/Update/ExecuteCommand.php b/vendor/drupal/console/src/Command/Update/ExecuteCommand.php index 3387d4280..51d3ad4ac 100644 --- a/vendor/drupal/console/src/Command/Update/ExecuteCommand.php +++ b/vendor/drupal/console/src/Command/Update/ExecuteCommand.php @@ -229,7 +229,7 @@ class ExecuteCommand extends Command return false; } - $io->info( + $io->comment( sprintf( $this->trans('commands.update.execute.messages.executing-update'), $update_number, @@ -237,6 +237,12 @@ class ExecuteCommand extends Command ) ); + $updateExploded = explode(" - ", $update); + $updateExploded = count($updateExploded)>0?$updateExploded[1]:$updateExploded[0]; + + $io->comment(trim($updateExploded)); + $io->newLine(); + $this->moduleHandler->invoke($module_name, 'update_' . $update_number); drupal_set_installed_schema_version($module_name, $update_number); } diff --git a/vendor/drupal/console/src/Command/Views/DebugCommand.php b/vendor/drupal/console/src/Command/Views/DebugCommand.php index 087621a22..9136bb887 100644 --- a/vendor/drupal/console/src/Command/Views/DebugCommand.php +++ b/vendor/drupal/console/src/Command/Views/DebugCommand.php @@ -57,12 +57,12 @@ class DebugCommand extends Command ) ->addOption( 'tag', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.views.debug.arguments.view-tag') )->addOption( 'status', - '', + null, InputOption::VALUE_OPTIONAL, $this->trans('commands.views.debug.arguments.view-status') ); diff --git a/vendor/drupal/console/src/Command/Views/DisableCommand.php b/vendor/drupal/console/src/Command/Views/DisableCommand.php index c127f649c..146763ec9 100644 --- a/vendor/drupal/console/src/Command/Views/DisableCommand.php +++ b/vendor/drupal/console/src/Command/Views/DisableCommand.php @@ -98,7 +98,8 @@ class DisableCommand extends Command if (empty($view)) { $io->error(sprintf($this->trans('commands.views.debug.messages.not-found'), $viewId)); - return; + + return 1; } try { @@ -107,6 +108,10 @@ class DisableCommand extends Command $io->success(sprintf($this->trans('commands.views.disable.messages.disabled-successfully'), $view->get('label'))); } catch (\Exception $e) { $io->error($e->getMessage()); + + return 1; } + + return 0; } } diff --git a/vendor/drupal/console/src/Command/Views/EnableCommand.php b/vendor/drupal/console/src/Command/Views/EnableCommand.php index 3fe9ed651..898d17eea 100644 --- a/vendor/drupal/console/src/Command/Views/EnableCommand.php +++ b/vendor/drupal/console/src/Command/Views/EnableCommand.php @@ -103,7 +103,7 @@ class EnableCommand extends Command $viewId ) ); - return; + return 1; } try { @@ -116,6 +116,10 @@ class EnableCommand extends Command ); } catch (Exception $e) { $io->error($e->getMessage()); + + return 1; } + + return 0; } } diff --git a/vendor/drupal/console/src/Extension/Manager.php b/vendor/drupal/console/src/Extension/Manager.php index a1a79a1a0..b0798f965 100644 --- a/vendor/drupal/console/src/Extension/Manager.php +++ b/vendor/drupal/console/src/Extension/Manager.php @@ -3,6 +3,8 @@ namespace Drupal\Console\Extension; use Drupal\Console\Utils\Site; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\ClientException; /** * Class ExtensionManager @@ -15,6 +17,12 @@ class Manager * @var Site */ protected $site; + + /** + * @var Client + */ + protected $httpClient; + /** * @var string */ @@ -39,13 +47,16 @@ class Manager * ExtensionManager constructor. * * @param Site $site + * @param Client $httpClient * @param string $appRoot */ public function __construct( Site $site, + Client $httpClient, $appRoot ) { $this->site = $site; + $this->httpClient = $httpClient; $this->appRoot = $appRoot; $this->initialize(); } @@ -135,6 +146,8 @@ class Manager { $this->extension = $extension; $this->extensions[$extension] = $this->discoverExtensions($extension); + + return $this; } /** @@ -347,4 +360,45 @@ class Manager $extension = $this->getExtension($type, $name); return $this->createExtension($extension); } + + /** + * @param array $extensions + * @param string $type + * @return array + */ + public function checkExtensions(array $extensions, $type = 'module') + { + $checkextensions = [ + 'local_extensions' => [], + 'drupal_extensions' => [], + 'no_extensions' => [], + ]; + + $local_extensions = $this->discoverExtension($type) + ->showInstalled() + ->showUninstalled() + ->showCore() + ->showNoCore() + ->getList(true); + + foreach ($extensions as $extension) { + if (in_array($extension, $local_extensions)) { + $checkextensions['local_extensions'][] = $extension; + } else { + try { + $response = $this->httpClient->head('https://www.drupal.org/project/' . $extension); + $header_link = explode(';', $response->getHeader('link')); + if (empty($header_link[0])) { + $checkextensions['no_extensions'][] = $extension; + } else { + $checkextensions['drupal_extensions'][] = $extension; + } + } catch (ClientException $e) { + $checkextensions['no_extensions'][] = $extension; + } + } + } + + return $checkextensions; + } } diff --git a/vendor/drupal/console/src/Generator/CacheContextGenerator.php b/vendor/drupal/console/src/Generator/CacheContextGenerator.php index a4d85f813..da87ee974 100644 --- a/vendor/drupal/console/src/Generator/CacheContextGenerator.php +++ b/vendor/drupal/console/src/Generator/CacheContextGenerator.php @@ -44,7 +44,7 @@ class CacheContextGenerator extends Generator 'class' => $class, 'services' => $services, 'class_path' => sprintf('Drupal\%s\CacheContext\%s', $module, $class), - 'tags' => ['name' => 'cache_context'], + 'tags' => ['name' => 'cache.context'], 'file_exists' => file_exists($this->extensionManager->getModule($module)->getPath() .'/'.$module.'.services.yml'), ]; diff --git a/vendor/drupal/console/src/Generator/FormGenerator.php b/vendor/drupal/console/src/Generator/FormGenerator.php index a05cd1ae9..d19897480 100644 --- a/vendor/drupal/console/src/Generator/FormGenerator.php +++ b/vendor/drupal/console/src/Generator/FormGenerator.php @@ -41,6 +41,7 @@ class FormGenerator extends Generator * @param $module * @param $class_name * @param $services + * @param $config_file * @param $inputs * @param $form_id * @param $form_type @@ -50,7 +51,7 @@ class FormGenerator extends Generator * @param $menu_parent * @param $menu_link_desc */ - public function generate($module, $class_name, $form_id, $form_type, $services, $inputs, $path, $menu_link_gen, $menu_link_title, $menu_parent, $menu_link_desc) + public function generate($module, $class_name, $form_id, $form_type, $services, $config_file, $inputs, $path, $menu_link_gen, $menu_link_title, $menu_parent, $menu_link_desc) { $class_name_short = strtolower( $this->stringConverter->removeSuffix($class_name) @@ -59,6 +60,7 @@ class FormGenerator extends Generator $parameters = [ 'class_name' => $class_name, 'services' => $services, + 'config_file' => $config_file, 'inputs' => $inputs, 'module_name' => $module, 'form_id' => $form_id, @@ -90,13 +92,15 @@ class FormGenerator extends Generator $this->extensionManager->getModule($module)->getFormPath() .'/'.$class_name.'.php', $parameters ); - + // Render defaults YML file. - $this->renderFile( - 'module/config/install/field.default.yml.twig', - $this->extensionManager->getModule($module)->getPath() .'/config/install/'.$module.'.'.$class_name_short.'.yml', - $parameters - ); + if ($config_file == true) { + $this->renderFile( + 'module/config/install/field.default.yml.twig', + $this->extensionManager->getModule($module)->getPath() .'/config/install/'.$module.'.'.$class_name_short.'.yml', + $parameters + ); + } if ($menu_link_gen == true) { $this->renderFile( diff --git a/vendor/drupal/console/src/Generator/ModuleGenerator.php b/vendor/drupal/console/src/Generator/ModuleGenerator.php index be4b87c2a..f7c2ed0a7 100644 --- a/vendor/drupal/console/src/Generator/ModuleGenerator.php +++ b/vendor/drupal/console/src/Generator/ModuleGenerator.php @@ -117,7 +117,7 @@ class ModuleGenerator extends Generator if ($test) { $this->renderFile( 'module/src/Tests/load-test.php.twig', - $dir . '/src/Tests/' . 'LoadTest.php', + $dir . '/tests/src/Functional/' . 'LoadTest.php', $parameters ); } @@ -163,7 +163,7 @@ class ModuleGenerator extends Generator } $this->renderFile( 'module/twig-template-file.twig', - $dir . $machineName . '.html.twig', + $dir . str_replace("_", "-", $machineName) . '.html.twig', $parameters ); } diff --git a/vendor/drupal/console/src/Generator/ProfileGenerator.php b/vendor/drupal/console/src/Generator/ProfileGenerator.php index e3431b220..8d0857c1a 100644 --- a/vendor/drupal/console/src/Generator/ProfileGenerator.php +++ b/vendor/drupal/console/src/Generator/ProfileGenerator.php @@ -18,6 +18,7 @@ class ProfileGenerator extends Generator $description, $core, $dependencies, + $themes, $distribution ) { $dir = $profile_path . '/' . $machine_name; @@ -57,6 +58,7 @@ class ProfileGenerator extends Generator 'core' => $core, 'description' => $description, 'dependencies' => $dependencies, + 'themes' => $themes, 'distribution' => $distribution, ]; diff --git a/vendor/drupal/console/src/Generator/ThemeGenerator.php b/vendor/drupal/console/src/Generator/ThemeGenerator.php index e9f15173c..78342bf98 100644 --- a/vendor/drupal/console/src/Generator/ThemeGenerator.php +++ b/vendor/drupal/console/src/Generator/ThemeGenerator.php @@ -40,6 +40,7 @@ class ThemeGenerator extends Generator $package, $base_theme, $global_library, + $libraries, $regions, $breakpoints ) { @@ -81,6 +82,7 @@ class ThemeGenerator extends Generator 'package' => $package, 'base_theme' => $base_theme, 'global_library' => $global_library, + 'libraries' => $libraries, 'regions' => $regions, 'breakpoints' => $breakpoints, ]; @@ -97,6 +99,14 @@ class ThemeGenerator extends Generator $parameters ); + if ($libraries) { + $this->renderFile( + 'theme/libraries.yml.twig', + $dir . '/' . $machine_name . '.libraries.yml', + $parameters + ); + } + if ($breakpoints) { $this->renderFile( 'theme/breakpoints.yml.twig', diff --git a/vendor/drupal/console/src/Utils/DrupalApi.php b/vendor/drupal/console/src/Utils/DrupalApi.php index 9295db86a..c382e12eb 100644 --- a/vendor/drupal/console/src/Utils/DrupalApi.php +++ b/vendor/drupal/console/src/Utils/DrupalApi.php @@ -58,7 +58,7 @@ class DrupalApi /** * Auxiliary function to get all available drupal caches. * - * @return array The all available drupal caches + * @return \Drupal\Core\Cache\CacheBackendInterface[] The all available drupal caches */ public function getCaches() { diff --git a/vendor/drupal/console/src/Utils/Site.php b/vendor/drupal/console/src/Utils/Site.php index 72d1ab52b..46fbc86cf 100644 --- a/vendor/drupal/console/src/Utils/Site.php +++ b/vendor/drupal/console/src/Utils/Site.php @@ -38,8 +38,7 @@ class Site public function __construct( $appRoot, ConfigurationManager $configurationManager - ) - { + ) { $this->appRoot = $appRoot; $this->configurationManager = $configurationManager; } @@ -220,7 +219,7 @@ class Site if ($cacheDirectory) { if (strpos($cacheDirectory, '/') != 0) { $cacheDirectory = $this->configurationManager - ->getApplicationDirectory() . '/' . $cacheDirectory; + ->getApplicationDirectory() . '/' . $cacheDirectory; } $cacheDirectories[] = $cacheDirectory . '/' . $siteId . '/'; } @@ -255,4 +254,21 @@ class Site return false; } } + + public function cachedServicesFile() + { + return $this->getCacheDirectory().'/console.services.yml'; + } + + public function cachedServicesFileExists() + { + return file_exists($this->cachedServicesFile()); + } + + public function removeCachedServicesFile() + { + if ($this->cachedServicesFileExists()) { + unlink($this->cachedServicesFile()); + } + } } diff --git a/vendor/drupal/console/src/Utils/Validator.php b/vendor/drupal/console/src/Utils/Validator.php index 12b522786..b81c0ed65 100644 --- a/vendor/drupal/console/src/Utils/Validator.php +++ b/vendor/drupal/console/src/Utils/Validator.php @@ -8,6 +8,7 @@ namespace Drupal\Console\Utils; use Drupal\Console\Extension\Manager; +use Drupal\Console\Core\Style\DrupalStyle; class Validator { @@ -19,14 +20,23 @@ class Validator protected $appRoot; + /* + * TranslatorManager + */ + protected $translatorManager; + /** * Site constructor. * - * @param Manager $extensionManager + * @param Manager $extensionManager + * @param TranslatorManager $translatorManager */ - public function __construct(Manager $extensionManager) - { + public function __construct( + Manager $extensionManager, + TranslatorManager $translatorManager + ) { $this->extensionManager = $extensionManager; + $this->translatorManager = $translatorManager; } public function validateModuleName($module) @@ -114,29 +124,29 @@ class Validator return $module_path; } - public function validateModuleDependencies($dependencies) + public function validateMachineNameList($list) { - $dependencies_checked = [ + $list_checked = [ 'success' => [], 'fail' => [], ]; - if (empty($dependencies)) { + if (empty($list)) { return []; } - $dependencies = explode(',', $this->removeSpaces($dependencies)); - foreach ($dependencies as $key => $module) { + $list = explode(',', $this->removeSpaces($list)); + foreach ($list as $key => $module) { if (!empty($module)) { if (preg_match(self::REGEX_MACHINE_NAME, $module)) { - $dependencies_checked['success'][] = $module; + $list_checked['success'][] = $module; } else { - $dependencies_checked['fail'][] = $module; + $list_checked['fail'][] = $module; } } } - return $dependencies_checked; + return $list_checked; } /** @@ -259,4 +269,31 @@ class Validator return array_diff($moduleList, $modules); } + + /** + * @param string $extensions_list + * @param string $type + * @param DrupalStyle $io + * + * @return array + */ + public function validateExtensions($extensions_list, $type, DrupalStyle $io) + { + $extensions = $this->validateMachineNameList($extensions_list); + // Check if all extensions are available + if ($extensions) { + $checked_extensions = $this->extensionManager->checkExtensions($extensions['success'], $type); + if (!empty($checked_extensions['no_extensions'])) { + $io->warning( + sprintf( + $this->translatorManager->trans('validator.warnings.extension-unavailable'), + implode(', ', $checked_extensions['no_extensions']) + ) + ); + } + $extensions = $extensions['success']; + } + + return $extensions; + } } diff --git a/vendor/drupal/console/templates/module/Tests/Controller/controller.php.twig b/vendor/drupal/console/templates/module/Tests/Controller/controller.php.twig index a1748f9f5..d963c6652 100644 --- a/vendor/drupal/console/templates/module/Tests/Controller/controller.php.twig +++ b/vendor/drupal/console/templates/module/Tests/Controller/controller.php.twig @@ -23,11 +23,11 @@ class {{class_name}}Test extends WebTestBase {% endblock %} * {@inheritdoc} */ public static function getInfo() { - return array( + return [ 'name' => "{{module}} {{class_name}}'s controller functionality", 'description' => 'Test Unit for module {{module}} and controller {{class_name}}.', 'group' => 'Other', - ); + ]; } /** diff --git a/vendor/drupal/console/templates/module/module-twig-template-append.twig b/vendor/drupal/console/templates/module/module-twig-template-append.twig index 42b3d687b..bb516bde8 100644 --- a/vendor/drupal/console/templates/module/module-twig-template-append.twig +++ b/vendor/drupal/console/templates/module/module-twig-template-append.twig @@ -5,7 +5,6 @@ function {{machine_name}}_theme() { return [ '{{machine_name}}' => [ - 'template' => '{{machine_name}}', 'render element' => 'children', ], ]; diff --git a/vendor/drupal/console/templates/module/module.views.inc.twig b/vendor/drupal/console/templates/module/module.views.inc.twig index daf921f23..98e755c13 100644 --- a/vendor/drupal/console/templates/module/module.views.inc.twig +++ b/vendor/drupal/console/templates/module/module.views.inc.twig @@ -21,19 +21,19 @@ use Drupal\system\ActionConfigEntityInterface; function {{module}}_views_data() { $data['views']['table']['group'] = t('Custom Global'); - $data['views']['table']['join'] = array( + $data['views']['table']['join'] = [ // #global is a special flag which allows a table to appear all the time. - '#global' => array(), - ); + '#global' => [], + ]; - $data['views']['{{ class_machine_name }}'] = array( + $data['views']['{{ class_machine_name }}'] = [ 'title' => t('{{ title }}'), 'help' => t('{{ description }}'), - 'field' => array( + 'field' => [ 'id' => '{{ class_machine_name }}', - ), - ); + ], + ]; return $data; } diff --git a/vendor/drupal/console/templates/module/src/Command/command.php.twig b/vendor/drupal/console/templates/module/src/Command/command.php.twig index 305095753..7e6f264dd 100644 --- a/vendor/drupal/console/templates/module/src/Command/command.php.twig +++ b/vendor/drupal/console/templates/module/src/Command/command.php.twig @@ -37,7 +37,7 @@ class {{ class_name }} extends Command {% endblock %} {% if services is not empty %} /** - * {@inheritdoc} + * Constructs a new {{ class_name }} object. */ public function __construct({{ servicesAsParameters(services)|join(', ') }}) { {{ serviceClassInitialization(services) }} diff --git a/vendor/drupal/console/templates/module/src/Controller/controller.php.twig b/vendor/drupal/console/templates/module/src/Controller/controller.php.twig index cf52f16d1..57c1ad137 100644 --- a/vendor/drupal/console/templates/module/src/Controller/controller.php.twig +++ b/vendor/drupal/console/templates/module/src/Controller/controller.php.twig @@ -25,7 +25,7 @@ class {{ class_name }} extends ControllerBase {% endblock %} {% if services is not empty %} /** - * {@inheritdoc} + * Constructs a new {{ class_name }} object. */ public function __construct({{ servicesAsParameters(services)|join(', ') }}) { {{ serviceClassInitialization(services) }} diff --git a/vendor/drupal/console/templates/module/src/Controller/entity-controller.php.twig b/vendor/drupal/console/templates/module/src/Controller/entity-controller.php.twig index 1244001ab..d2261ff34 100644 --- a/vendor/drupal/console/templates/module/src/Controller/entity-controller.php.twig +++ b/vendor/drupal/console/templates/module/src/Controller/entity-controller.php.twig @@ -53,7 +53,7 @@ class {{ entity_class }}Controller extends ControllerBase implements ContainerIn */ public function revisionPageTitle(${{ entity_name }}_revision) { ${{ entity_name }} = $this->entityManager()->getStorage('{{ entity_name }}')->loadRevision(${{ entity_name }}_revision); - return $this->t('Revision of %title from %date', array('%title' => ${{ entity_name }}->label(), '%date' => format_date(${{ entity_name }}->getRevisionCreationTime()))); + return $this->t('Revision of %title from %date', ['%title' => ${{ entity_name }}->label(), '%date' => format_date(${{ entity_name }}->getRevisionCreationTime())]); } /** @@ -74,12 +74,12 @@ class {{ entity_class }}Controller extends ControllerBase implements ContainerIn ${{ entity_name }}_storage = $this->entityManager()->getStorage('{{ entity_name }}'); $build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => ${{ entity_name }}->label()]) : $this->t('Revisions for %title', ['%title' => ${{ entity_name }}->label()]); - $header = array($this->t('Revision'), $this->t('Operations')); + $header = [$this->t('Revision'), $this->t('Operations')]; $revert_permission = (($account->hasPermission("revert all {{ label|lower }} revisions") || $account->hasPermission('administer {{ label|lower }} entities'))); $delete_permission = (($account->hasPermission("delete all {{ label|lower }} revisions") || $account->hasPermission('administer {{ label|lower }} entities'))); - $rows = array(); + $rows = []; $vids = ${{ entity_name }}_storage->revisionIds(${{ entity_name }}); @@ -97,7 +97,7 @@ class {{ entity_class }}Controller extends ControllerBase implements ContainerIn ]; // Use revision link to link to revisions that are not active. - $date = \Drupal::service('date.formatter')->format($revision->revision_timestamp->value, 'short'); + $date = \Drupal::service('date.formatter')->format($revision->getRevisionCreationTime(), 'short'); if ($vid != ${{ entity_name }}->getRevisionId()) { $link = $this->l($date, new Url('entity.{{ entity_name }}.revision', ['{{ entity_name }}' => ${{ entity_name }}->id(), '{{ entity_name }}_revision' => $vid])); } @@ -113,7 +113,7 @@ class {{ entity_class }}Controller extends ControllerBase implements ContainerIn '#context' => [ 'date' => $link, 'username' => \Drupal::service('renderer')->renderPlain($username), - 'message' => ['#markup' => $revision->revision_log_message->value, '#allowed_tags' => Xss::getHtmlTagList()], + 'message' => ['#markup' => $revision->getRevisionLogMessage(), '#allowed_tags' => Xss::getHtmlTagList()], ], ], ]; @@ -166,11 +166,11 @@ class {{ entity_class }}Controller extends ControllerBase implements ContainerIn } } - $build['{{ entity_name }}_revisions_table'] = array( + $build['{{ entity_name }}_revisions_table'] = [ '#theme' => 'table', '#rows' => $rows, '#header' => $header, - ); + ]; return $build; } diff --git a/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-delete.php.twig b/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-delete.php.twig index 4d5a13f2e..02674ac11 100644 --- a/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-delete.php.twig +++ b/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-delete.php.twig @@ -82,14 +82,14 @@ class {{ entity_class }}RevisionDeleteForm extends ConfirmFormBase {% endblock % * {@inheritdoc} */ public function getQuestion() { - return t('Are you sure you want to delete the revision from %revision-date?', array('%revision-date' => format_date($this->revision->getRevisionCreationTime()))); + return t('Are you sure you want to delete the revision from %revision-date?', ['%revision-date' => format_date($this->revision->getRevisionCreationTime())]); } /** * {@inheritdoc} */ public function getCancelUrl() { - return new Url('entity.{{ entity_name }}.version_history', array('{{ entity_name }}' => $this->revision->id())); + return new Url('entity.{{ entity_name }}.version_history', ['{{ entity_name }}' => $this->revision->id()]); } /** @@ -115,16 +115,16 @@ class {{ entity_class }}RevisionDeleteForm extends ConfirmFormBase {% endblock % public function submitForm(array &$form, FormStateInterface $form_state) { $this->{{ entity_class }}Storage->deleteRevision($this->revision->getRevisionId()); - $this->logger('content')->notice('{{ label }}: deleted %title revision %revision.', array('%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId())); - drupal_set_message(t('Revision from %revision-date of {{ label }} %title has been deleted.', array('%revision-date' => format_date($this->revision->getRevisionCreationTime()), '%title' => $this->revision->label()))); + $this->logger('content')->notice('{{ label }}: deleted %title revision %revision.', ['%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]); + drupal_set_message(t('Revision from %revision-date of {{ label }} %title has been deleted.', ['%revision-date' => format_date($this->revision->getRevisionCreationTime()), '%title' => $this->revision->label()])); $form_state->setRedirect( 'entity.{{ entity_name }}.canonical', - array('{{ entity_name }}' => $this->revision->id()) + ['{{ entity_name }}' => $this->revision->id()] ); - if ($this->connection->query('SELECT COUNT(DISTINCT vid) FROM {{ '{'~entity_name~'_field_revision}' }} WHERE id = :id', array(':id' => $this->revision->id()))->fetchField() > 1) { + if ($this->connection->query('SELECT COUNT(DISTINCT vid) FROM {{ '{'~entity_name~'_field_revision}' }} WHERE id = :id', [':id' => $this->revision->id()])->fetchField() > 1) { $form_state->setRedirect( 'entity.{{ entity_name }}.version_history', - array('{{ entity_name }}' => $this->revision->id()) + ['{{ entity_name }}' => $this->revision->id()] ); } } diff --git a/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-revert-translation.php.twig b/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-revert-translation.php.twig index 6d2f46c2a..0c38ba5b3 100644 --- a/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-revert-translation.php.twig +++ b/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-revert-translation.php.twig @@ -87,11 +87,11 @@ class {{ entity_class }}RevisionRevertTranslationForm extends {{ entity_class }} $this->langcode = $langcode; $form = parent::buildForm($form, $form_state, ${{ entity_name }}_revision); - $form['revert_untranslated_fields'] = array( + $form['revert_untranslated_fields'] = [ '#type' => 'checkbox', '#title' => $this->t('Revert content shared among translations'), '#default_value' => FALSE, - ); + ]; return $form; } diff --git a/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-revert.php.twig b/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-revert.php.twig index 42e65979f..4077d9417 100644 --- a/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-revert.php.twig +++ b/vendor/drupal/console/templates/module/src/Entity/Form/entity-content-revision-revert.php.twig @@ -89,7 +89,7 @@ class {{ entity_class }}RevisionRevertForm extends ConfirmFormBase {% endblock % * {@inheritdoc} */ public function getCancelUrl() { - return new Url('entity.{{ entity_name }}.version_history', array('{{ entity_name }}' => $this->revision->id())); + return new Url('entity.{{ entity_name }}.version_history', ['{{ entity_name }}' => $this->revision->id()]); } /** @@ -132,7 +132,7 @@ class {{ entity_class }}RevisionRevertForm extends ConfirmFormBase {% endblock % drupal_set_message(t('{{ label }} %title has been reverted to the revision from %revision-date.', ['%title' => $this->revision->label(), '%revision-date' => $this->dateFormatter->format($original_revision_timestamp)])); $form_state->setRedirect( 'entity.{{ entity_name }}.version_history', - array('{{ entity_name }}' => $this->revision->id()) + ['{{ entity_name }}' => $this->revision->id()] ); } diff --git a/vendor/drupal/console/templates/module/src/Entity/Form/entity-content.php.twig b/vendor/drupal/console/templates/module/src/Entity/Form/entity-content.php.twig index e703e5f17..63982a485 100644 --- a/vendor/drupal/console/templates/module/src/Entity/Form/entity-content.php.twig +++ b/vendor/drupal/console/templates/module/src/Entity/Form/entity-content.php.twig @@ -30,12 +30,12 @@ class {{ entity_class }}Form extends ContentEntityForm {% endblock %} {% if revisionable %} if (!$this->entity->isNew()) { - $form['new_revision'] = array( + $form['new_revision'] = [ '#type' => 'checkbox', '#title' => $this->t('Create new revision'), '#default_value' => FALSE, '#weight' => 10, - ); + ]; } {% endif %} diff --git a/vendor/drupal/console/templates/module/src/Entity/entity-content-with-bundle.theme_hook_suggestions.php.twig b/vendor/drupal/console/templates/module/src/Entity/entity-content-with-bundle.theme_hook_suggestions.php.twig index c14788809..77ea4dfbb 100644 --- a/vendor/drupal/console/templates/module/src/Entity/entity-content-with-bundle.theme_hook_suggestions.php.twig +++ b/vendor/drupal/console/templates/module/src/Entity/entity-content-with-bundle.theme_hook_suggestions.php.twig @@ -4,7 +4,7 @@ * Implements hook_theme_suggestions_HOOK(). */ function {{ module }}_theme_suggestions_{{ entity_name }}(array $variables) { - $suggestions = array(); + $suggestions = []; $entity = $variables['elements']['#{{ entity_name }}']; $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_'); diff --git a/vendor/drupal/console/templates/module/src/Entity/entity-content.php.twig b/vendor/drupal/console/templates/module/src/Entity/entity-content.php.twig index 72bb9320b..018d2c0d6 100644 --- a/vendor/drupal/console/templates/module/src/Entity/entity-content.php.twig +++ b/vendor/drupal/console/templates/module/src/Entity/entity-content.php.twig @@ -123,9 +123,9 @@ class {{ entity_class }} extends {% if revisionable %}RevisionableContentEntityB */ public static function preCreate(EntityStorageInterface $storage_controller, array &$values) { parent::preCreate($storage_controller, $values); - $values += array( + $values += [ 'user_id' => \Drupal::currentUser()->id(), - ); + ]; } {% if revisionable %} @@ -152,15 +152,6 @@ class {{ entity_class }} extends {% if revisionable %}RevisionableContentEntityB } {% endif %} -{% if bundle_entity_type %} - /** - * {@inheritdoc} - */ - public function getType() { - return $this->bundle(); - } - -{% endif %} /** * {@inheritdoc} */ @@ -235,38 +226,6 @@ class {{ entity_class }} extends {% if revisionable %}RevisionableContentEntityB $this->set('status', $published ? TRUE : FALSE); return $this; } -{% if revisionable %} - - /** - * {@inheritdoc} - */ - public function getRevisionCreationTime() { - return $this->get('revision_timestamp')->value; - } - - /** - * {@inheritdoc} - */ - public function setRevisionCreationTime($timestamp) { - $this->set('revision_timestamp', $timestamp); - return $this; - } - - /** - * {@inheritdoc} - */ - public function getRevisionUser() { - return $this->get('revision_uid')->entity; - } - - /** - * {@inheritdoc} - */ - public function setRevisionUserId($uid) { - $this->set('revision_uid', $uid); - return $this; - } -{% endif %} /** * {@inheritdoc} @@ -281,21 +240,21 @@ class {{ entity_class }} extends {% if revisionable %}RevisionableContentEntityB ->setSetting('target_type', 'user') ->setSetting('handler', 'default') ->setTranslatable(TRUE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'author', 'weight' => 0, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'entity_reference_autocomplete', 'weight' => 5, - 'settings' => array( + 'settings' => [ 'match_operator' => 'CONTAINS', 'size' => '60', 'autocomplete_type' => 'tags', 'placeholder' => '', - ), - )) + ], + ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayConfigurable('view', TRUE); @@ -305,20 +264,20 @@ class {{ entity_class }} extends {% if revisionable %}RevisionableContentEntityB {% if revisionable %} ->setRevisionable(TRUE) {% endif %} - ->setSettings(array( + ->setSettings([ 'max_length' => 50, 'text_processing' => 0, - )) + ]) ->setDefaultValue('') - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'above', 'type' => 'string', 'weight' => -4, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'string_textfield', 'weight' => -4, - )) + ]) ->setDisplayConfigurable('form', TRUE) ->setDisplayConfigurable('view', TRUE); @@ -337,21 +296,6 @@ class {{ entity_class }} extends {% if revisionable %}RevisionableContentEntityB $fields['changed'] = BaseFieldDefinition::create('changed') ->setLabel(t('Changed')) ->setDescription(t('The time that the entity was last edited.')); -{% if revisionable %} - - $fields['revision_timestamp'] = BaseFieldDefinition::create('created') - ->setLabel(t('Revision timestamp')) - ->setDescription(t('The time that the current revision was created.')) - ->setQueryable(FALSE) - ->setRevisionable(TRUE); - - $fields['revision_uid'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('Revision user ID')) - ->setDescription(t('The user ID of the author of the current revision.')) - ->setSetting('target_type', 'user') - ->setQueryable(FALSE) - ->setRevisionable(TRUE); -{% endif %} {% if revisionable and is_translatable %} $fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean') diff --git a/vendor/drupal/console/templates/module/src/Entity/entity-content.theme.php.twig b/vendor/drupal/console/templates/module/src/Entity/entity-content.theme.php.twig index 4aab3bdc7..afa9d750c 100644 --- a/vendor/drupal/console/templates/module/src/Entity/entity-content.theme.php.twig +++ b/vendor/drupal/console/templates/module/src/Entity/entity-content.theme.php.twig @@ -1,7 +1,7 @@ {% block hook_theme %} - $theme['{{ entity_name }}'] = array( + $theme['{{ entity_name }}'] = [ 'render element' => 'elements', 'file' => '{{ entity_name }}.page.inc', 'template' => '{{ entity_name }}', - ); + ]; {% endblock %} diff --git a/vendor/drupal/console/templates/module/src/Entity/entity.php.twig b/vendor/drupal/console/templates/module/src/Entity/entity.php.twig index 07d85f294..03efd8791 100644 --- a/vendor/drupal/console/templates/module/src/Entity/entity.php.twig +++ b/vendor/drupal/console/templates/module/src/Entity/entity.php.twig @@ -24,6 +24,7 @@ use Drupal\Core\Config\Entity\ConfigEntityBase; * id = "{{ entity_name }}", * label = @Translation("{{ label }}"), * handlers = { + * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", * "list_builder" = "Drupal\{{ module }}\{{ entity_class }}ListBuilder", * "form" = { * "add" = "Drupal\{{ module }}\Form\{{ entity_class }}Form", diff --git a/vendor/drupal/console/templates/module/src/Entity/interface-entity-content.php.twig b/vendor/drupal/console/templates/module/src/Entity/interface-entity-content.php.twig index 9f7d3dad9..981b81bc2 100644 --- a/vendor/drupal/console/templates/module/src/Entity/interface-entity-content.php.twig +++ b/vendor/drupal/console/templates/module/src/Entity/interface-entity-content.php.twig @@ -12,8 +12,6 @@ namespace Drupal\{{module}}\Entity; {% if revisionable %} use Drupal\Core\Entity\RevisionLogInterface; use Drupal\Core\Entity\RevisionableInterface; -use Drupal\Component\Utility\Xss; -use Drupal\Core\Url; {% else %} use Drupal\Core\Entity\ContentEntityInterface; {% endif %} @@ -31,16 +29,6 @@ interface {{ entity_class }}Interface extends {% if revisionable %}RevisionableI {% block class_methods %} // Add get/set methods for your configuration properties here. -{% if bundle_entity_type %} - /** - * Gets the {{ label }} type. - * - * @return string - * The {{ label }} type. - */ - public function getType(); - -{% endif %} /** * Gets the {{ label }} name. * diff --git a/vendor/drupal/console/templates/module/src/Form/form-config.php.twig b/vendor/drupal/console/templates/module/src/Form/form-config.php.twig index 52ca88bfa..9dc7a7dcb 100644 --- a/vendor/drupal/console/templates/module/src/Form/form-config.php.twig +++ b/vendor/drupal/console/templates/module/src/Form/form-config.php.twig @@ -26,6 +26,9 @@ use Symfony\Component\DependencyInjection\ContainerInterface; class {{ class_name }} extends ConfigFormBase {% endblock %} {% block class_construct %} {% if services is not empty %} + /** + * Constructs a new {{ class_name }} object. + */ public function __construct( ConfigFactoryInterface $config_factory, {{ servicesAsParameters(services)|join(',\n ') }} diff --git a/vendor/drupal/console/templates/module/src/Form/form.php.twig b/vendor/drupal/console/templates/module/src/Form/form.php.twig index a495d6a9c..d45d63135 100644 --- a/vendor/drupal/console/templates/module/src/Form/form.php.twig +++ b/vendor/drupal/console/templates/module/src/Form/form.php.twig @@ -25,6 +25,9 @@ use Symfony\Component\DependencyInjection\ContainerInterface; class {{ class_name }} extends FormBase {% endblock %} {% block class_construct %} {% if services is not empty %} + /** + * Constructs a new {{ class_name }} object. + */ public function __construct( {{ servicesAsParameters(services)|join(',\n ') }} ) { @@ -80,18 +83,17 @@ class {{ class_name }} extends FormBase {% endblock %} {% endif %} ]; {% endfor %} - $form['submit'] = [ - '#type' => 'submit', - '#value' => $this->t('Submit'), + '#type' => 'submit', + '#value' => $this->t('Submit'), ]; return $form; } /** - * {@inheritdoc} - */ + * {@inheritdoc} + */ public function validateForm(array &$form, FormStateInterface $form_state) { parent::validateForm($form, $form_state); } @@ -102,7 +104,7 @@ class {{ class_name }} extends FormBase {% endblock %} public function submitForm(array &$form, FormStateInterface $form_state) { // Display result. foreach ($form_state->getValues() as $key => $value) { - drupal_set_message($key . ': ' . $value); + drupal_set_message($key . ': ' . $value); } } diff --git a/vendor/drupal/console/templates/module/src/Plugin/Block/block.php.twig b/vendor/drupal/console/templates/module/src/Plugin/Block/block.php.twig index e223b856f..c7d4cec4f 100644 --- a/vendor/drupal/console/templates/module/src/Plugin/Block/block.php.twig +++ b/vendor/drupal/console/templates/module/src/Plugin/Block/block.php.twig @@ -32,7 +32,7 @@ class {{class_name}} extends BlockBase {% if services is not empty %}implements {% block class_construct %} {% if services is not empty %} /** - * Construct. + * Constructs a new {{class_name}} object. * * @param array $configuration * A configuration array containing information about the plugin instance. diff --git a/vendor/drupal/console/templates/module/src/Plugin/Condition/condition.php.twig b/vendor/drupal/console/templates/module/src/Plugin/Condition/condition.php.twig index 569e56298..c782c90f5 100644 --- a/vendor/drupal/console/templates/module/src/Plugin/Condition/condition.php.twig +++ b/vendor/drupal/console/templates/module/src/Plugin/Condition/condition.php.twig @@ -42,7 +42,7 @@ public static function create(ContainerInterface $container, array $configuratio } /** - * Creates a new ExampleCondition instance. + * Creates a new {{ class_name }} object. * * @param array $configuration * The plugin configuration, i.e. an array with configuration values keyed diff --git a/vendor/drupal/console/templates/module/src/Plugin/Field/FieldFormatter/imageformatter.php.twig b/vendor/drupal/console/templates/module/src/Plugin/Field/FieldFormatter/imageformatter.php.twig index 83e6b7fcc..92059a4d4 100644 --- a/vendor/drupal/console/templates/module/src/Plugin/Field/FieldFormatter/imageformatter.php.twig +++ b/vendor/drupal/console/templates/module/src/Plugin/Field/FieldFormatter/imageformatter.php.twig @@ -58,7 +58,7 @@ class {{ class_name }} extends ImageFormatterBase implements ContainerFactoryPlu protected $imageStyleStorage; /** - * Constructs an ImageFormatter object. + * Constructs a new {{ class_name }} object. * * @param string $plugin_id * The plugin_id for the formatter. diff --git a/vendor/drupal/console/templates/module/src/Plugin/Mail/mail.php.twig b/vendor/drupal/console/templates/module/src/Plugin/Mail/mail.php.twig index d2e466e4c..878b3eea2 100644 --- a/vendor/drupal/console/templates/module/src/Plugin/Mail/mail.php.twig +++ b/vendor/drupal/console/templates/module/src/Plugin/Mail/mail.php.twig @@ -31,7 +31,7 @@ class {{class_name}} extends PhpMail {% if services is not empty %}implements Co {% block class_construct %} {% if services is not empty %} /** - * Construct. + * Constructs a new {{class_name}} object. * * @param array $configuration * A configuration array containing information about the plugin instance. diff --git a/vendor/drupal/console/templates/module/src/Plugin/Rest/Resource/rest.php.twig b/vendor/drupal/console/templates/module/src/Plugin/Rest/Resource/rest.php.twig index a5c3bbdce..9145f2e2a 100644 --- a/vendor/drupal/console/templates/module/src/Plugin/Rest/Resource/rest.php.twig +++ b/vendor/drupal/console/templates/module/src/Plugin/Rest/Resource/rest.php.twig @@ -43,7 +43,7 @@ class {{ class_name }} extends ResourceBase {% endblock %} {% block class_construct %} /** - * Constructs a Drupal\rest\Plugin\ResourceBase object. + * Constructs a new {{ class_name }} object. * * @param array $configuration * A configuration array containing information about the plugin instance. diff --git a/vendor/drupal/console/templates/module/src/Plugin/migrate/process/process.php.twig b/vendor/drupal/console/templates/module/src/Plugin/migrate/process/process.php.twig index fe18d3208..148d433f1 100644 --- a/vendor/drupal/console/templates/module/src/Plugin/migrate/process/process.php.twig +++ b/vendor/drupal/console/templates/module/src/Plugin/migrate/process/process.php.twig @@ -18,7 +18,7 @@ use Drupal\migrate\Row; /** * Provides a '{{class_name}}' migrate process plugin. * - * @MigrateProcess( + * @MigrateProcessPlugin( * id = "{{plugin_id}}" * ) */ diff --git a/vendor/drupal/console/templates/module/src/Plugin/skeleton.php.twig b/vendor/drupal/console/templates/module/src/Plugin/skeleton.php.twig index 4354a98f9..ccf2caf2f 100644 --- a/vendor/drupal/console/templates/module/src/Plugin/skeleton.php.twig +++ b/vendor/drupal/console/templates/module/src/Plugin/skeleton.php.twig @@ -39,7 +39,7 @@ class {{class_name}} implements {% if plugin_interface is not empty %} {{ plugin {% block class_construct %} {% if services is not empty %} /** - * Construct. + * Constructs a new {{class_name}} object. * * @param array $configuration * A configuration array containing information about the plugin instance. diff --git a/vendor/drupal/console/templates/module/src/Tests/load-test.php.twig b/vendor/drupal/console/templates/module/src/Tests/load-test.php.twig index df13935ca..69c2925a7 100644 --- a/vendor/drupal/console/templates/module/src/Tests/load-test.php.twig +++ b/vendor/drupal/console/templates/module/src/Tests/load-test.php.twig @@ -1,16 +1,16 @@ {% extends "base/class.php.twig" %} {% block file_path %} -\Drupal\{{ machine_name }}\Tests\LoadTest +\Drupal\Tests\{{ machine_name }}\Functional\LoadTest {% endblock %} {% block namespace_class %} -namespace Drupal\{{ machine_name }}\Tests; +namespace Drupal\Tests\{{ machine_name }}\Functional; {% endblock %} {% block use_class %} use Drupal\Core\Url; -use Drupal\simpletest\WebTestBase; +use Drupal\Tests\BrowserTestBase; {% endblock %} {% block class_declaration %} @@ -19,7 +19,7 @@ use Drupal\simpletest\WebTestBase; * * @group {{ machine_name }} */ -class LoadTest extends WebTestBase{% endblock %} +class LoadTest extends BrowserTestBase {% endblock %} {% block class_methods %} /** * Modules to enable. diff --git a/vendor/drupal/console/templates/module/src/TwigExtension/twig-extension.php.twig b/vendor/drupal/console/templates/module/src/TwigExtension/twig-extension.php.twig index 5b6f54758..438965049 100644 --- a/vendor/drupal/console/templates/module/src/TwigExtension/twig-extension.php.twig +++ b/vendor/drupal/console/templates/module/src/TwigExtension/twig-extension.php.twig @@ -36,7 +36,7 @@ class {{ class }} extends \Twig_Extension {% endblock %} {% if services|length > 1 %} /** - * Constructor. + * Constructs a new {{ class }} object. */ public function __construct({{ servicesAsParameters(services)|join(', ') }}) { parent::__construct($renderer); diff --git a/vendor/drupal/console/templates/module/src/cache-context.php.twig b/vendor/drupal/console/templates/module/src/cache-context.php.twig index 09c3e4b9f..5445fb3bf 100644 --- a/vendor/drupal/console/templates/module/src/cache-context.php.twig +++ b/vendor/drupal/console/templates/module/src/cache-context.php.twig @@ -9,6 +9,7 @@ namespace Drupal\{{module}}\CacheContext; {% endblock %} {% block use_class %} +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Cache\Context\CacheContextInterface; {% endblock %} @@ -23,8 +24,8 @@ class {{ class }} implements CacheContextInterface {% endblock %} {% block class_construct %} /** - * Constructor. - */ + * Constructs a new {{ class }} object. + */ public function __construct({{ servicesAsParameters(services)|join(', ') }}) { {{ serviceClassInitialization(services) }} } @@ -35,21 +36,21 @@ class {{ class }} implements CacheContextInterface {% endblock %} /** * {@inheritdoc} */ - static function getLabel() { - drupal_set_message('Lable of cache context'); + public static function getLabel() { + drupal_set_message('Lable of cache context'); } /** * {@inheritdoc} */ public function getContext() { - // Actual logic of context variation will lie here. + // Actual logic of context variation will lie here. } /** * {@inheritdoc} */ public function getCacheableMetadata() { - // The buble cache metadata. + return new CacheableMetadata(); } {% endblock %} diff --git a/vendor/drupal/console/templates/module/src/entity-storage.php.twig b/vendor/drupal/console/templates/module/src/entity-storage.php.twig index 006f417e4..01aec1cc4 100644 --- a/vendor/drupal/console/templates/module/src/entity-storage.php.twig +++ b/vendor/drupal/console/templates/module/src/entity-storage.php.twig @@ -33,7 +33,7 @@ class {{ entity_class }}Storage extends SqlContentEntityStorage implements {{ en public function revisionIds({{ entity_class }}Interface $entity) { return $this->database->query( 'SELECT vid FROM {{ '{'~entity_name~'_revision}' }} WHERE id=:id ORDER BY vid', - array(':id' => $entity->id()) + [':id' => $entity->id()] )->fetchCol(); } @@ -43,7 +43,7 @@ class {{ entity_class }}Storage extends SqlContentEntityStorage implements {{ en public function userRevisionIds(AccountInterface $account) { return $this->database->query( 'SELECT vid FROM {{ '{'~entity_name~'_field_revision}' }} WHERE uid = :uid ORDER BY vid', - array(':uid' => $account->id()) + [':uid' => $account->id()] )->fetchCol(); } @@ -51,7 +51,7 @@ class {{ entity_class }}Storage extends SqlContentEntityStorage implements {{ en * {@inheritdoc} */ public function countDefaultLanguageRevisions({{ entity_class }}Interface $entity) { - return $this->database->query('SELECT COUNT(*) FROM {{ '{'~entity_name~'_field_revision}' }} WHERE id = :id AND default_langcode = 1', array(':id' => $entity->id())) + return $this->database->query('SELECT COUNT(*) FROM {{ '{'~entity_name~'_field_revision}' }} WHERE id = :id AND default_langcode = 1', [':id' => $entity->id()]) ->fetchField(); } @@ -60,7 +60,7 @@ class {{ entity_class }}Storage extends SqlContentEntityStorage implements {{ en */ public function clearRevisionsLanguage(LanguageInterface $language) { return $this->database->update('{{ entity_name }}_revision') - ->fields(array('langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED)) + ->fields(['langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED]) ->condition('langcode', $language->getId()) ->execute(); } diff --git a/vendor/drupal/console/templates/module/src/event-subscriber.php.twig b/vendor/drupal/console/templates/module/src/event-subscriber.php.twig index a8fded0f3..d936b36cf 100644 --- a/vendor/drupal/console/templates/module/src/event-subscriber.php.twig +++ b/vendor/drupal/console/templates/module/src/event-subscriber.php.twig @@ -24,7 +24,7 @@ class {{ class }} implements EventSubscriberInterface {% endblock %} {% block class_construct %} /** - * Constructor. + * Constructs a new {{ class }} object. */ public function __construct({{ servicesAsParameters(services)|join(', ') }}) { {{ serviceClassInitialization(services) }} diff --git a/vendor/drupal/console/templates/module/src/listbuilder-entity-content.php.twig b/vendor/drupal/console/templates/module/src/listbuilder-entity-content.php.twig index 1615da806..46af6648c 100644 --- a/vendor/drupal/console/templates/module/src/listbuilder-entity-content.php.twig +++ b/vendor/drupal/console/templates/module/src/listbuilder-entity-content.php.twig @@ -11,8 +11,7 @@ namespace Drupal\{{module}}; {% block use_class %} use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityListBuilder; -use Drupal\Core\Routing\LinkGeneratorTrait; -use Drupal\Core\Url; +use Drupal\Core\Link; {% endblock %} {% block class_declaration %} @@ -22,9 +21,6 @@ use Drupal\Core\Url; * @ingroup {{ module }} */ class {{ entity_class }}ListBuilder extends EntityListBuilder {% endblock %} -{% block use_trait %} - use LinkGeneratorTrait; -{% endblock %} {% block class_methods %} /** @@ -42,13 +38,10 @@ class {{ entity_class }}ListBuilder extends EntityListBuilder {% endblock %} public function buildRow(EntityInterface $entity) { /* @var $entity \Drupal\{{module}}\Entity\{{ entity_class }} */ $row['id'] = $entity->id(); - $row['name'] = $this->l( + $row['name'] = Link::createFromRoute( $entity->label(), - new Url( - 'entity.{{ entity_name }}.edit_form', array( - '{{ entity_name }}' => $entity->id(), - ) - ) + 'entity.{{ entity_name }}.edit_form', + ['{{ entity_name }}' => $entity->id()] ); return $row + parent::buildRow($entity); } diff --git a/vendor/drupal/console/templates/module/src/plugin-type-annotation-manager.php.twig b/vendor/drupal/console/templates/module/src/plugin-type-annotation-manager.php.twig index f8645554b..2ed39b5df 100644 --- a/vendor/drupal/console/templates/module/src/plugin-type-annotation-manager.php.twig +++ b/vendor/drupal/console/templates/module/src/plugin-type-annotation-manager.php.twig @@ -22,7 +22,7 @@ class {{ class_name }}Manager extends DefaultPluginManager {% endblock %} {% block class_methods %} /** - * Constructor for {{ class_name }}Manager objects. + * Constructs a new {{ class_name }}Manager object. * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths diff --git a/vendor/drupal/console/templates/module/src/service.php.twig b/vendor/drupal/console/templates/module/src/service.php.twig index 2deb9d3eb..8116f27ce 100644 --- a/vendor/drupal/console/templates/module/src/service.php.twig +++ b/vendor/drupal/console/templates/module/src/service.php.twig @@ -16,7 +16,7 @@ namespace Drupal\{{module}};{% endblock %} class {{ class }}{% if(interface is defined and interface) %} implements {{ interface }}{% endif %} {% endblock %} {% block class_construct %} /** - * Constructor. + * Constructs a new {{ class }} object. */ public function __construct({{ servicesAsParameters(services)|join(', ') }}) { {{ serviceClassInitialization(services) }} diff --git a/vendor/drupal/console/templates/module/src/yaml-plugin-manager.php.twig b/vendor/drupal/console/templates/module/src/yaml-plugin-manager.php.twig index 81e6442b7..16d486bc5 100644 --- a/vendor/drupal/console/templates/module/src/yaml-plugin-manager.php.twig +++ b/vendor/drupal/console/templates/module/src/yaml-plugin-manager.php.twig @@ -28,14 +28,14 @@ class {{ plugin_class }}Manager extends DefaultPluginManager implements {{ plugi * * @var array */ - protected $defaults = array( + protected $defaults = [ // Add required and optional plugin properties. 'id' => '', 'label' => '', - ); + ]; /** - * Constructs a {{ plugin_class }}Manager object. + * Constructs a new {{ plugin_class }}Manager object. * * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. @@ -45,7 +45,7 @@ class {{ plugin_class }}Manager extends DefaultPluginManager implements {{ plugi public function __construct(ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend) { // Add more services as required. $this->moduleHandler = $module_handler; - $this->setCacheBackend($cache_backend, '{{ plugin_name }}', array('{{ plugin_name }}')); + $this->setCacheBackend($cache_backend, '{{ plugin_name }}', ['{{ plugin_name }}']); } /** diff --git a/vendor/drupal/console/templates/profile/info.yml.twig b/vendor/drupal/console/templates/profile/info.yml.twig index 31d0472e2..385baa630 100644 --- a/vendor/drupal/console/templates/profile/info.yml.twig +++ b/vendor/drupal/console/templates/profile/info.yml.twig @@ -14,3 +14,10 @@ dependencies: - {{ dependency }} {% endfor %} {% endif %} +{% if themes %} + +themes: +{% for theme in themes %} + - {{ theme }} +{% endfor %} +{% endif %} diff --git a/vendor/drupal/console/templates/theme/info.yml.twig b/vendor/drupal/console/templates/theme/info.yml.twig index e711e06cf..f68e9fb7e 100644 --- a/vendor/drupal/console/templates/theme/info.yml.twig +++ b/vendor/drupal/console/templates/theme/info.yml.twig @@ -5,7 +5,11 @@ package: {{ package }} core: {{ core }} libraries: - {{ machine_name }}/{{ global_library }} - +{% if libraries %} +{% for library in libraries %} + - {{ machine_name }}/{{ library.library_name }} +{% endfor %} +{% endif %} base theme: {{ base_theme }} {% if base_theme == 'classy' %} #Using Classy as a base theme https://www.drupal.org/theme-guide/8/classy diff --git a/vendor/drupal/console/templates/theme/libraries.yml.twig b/vendor/drupal/console/templates/theme/libraries.yml.twig new file mode 100644 index 000000000..8d2379ea6 --- /dev/null +++ b/vendor/drupal/console/templates/theme/libraries.yml.twig @@ -0,0 +1,16 @@ +{{ global_library }}: + version: 1.0 + css: + theme: + #css/your_style_sheet.css : {} + js: + #js/your_js.js : {} +{% for library in libraries %} +{{ library.library_name }}: + version: {{ library.library_version }} + css: + theme: + #js/your_js.js : {} + js: + #js/your_js.js : {} +{% endfor %} \ No newline at end of file diff --git a/vendor/drupal/console/services-drupal-install.yml b/vendor/drupal/console/uninstall.services.yml similarity index 89% rename from vendor/drupal/console/services-drupal-install.yml rename to vendor/drupal/console/uninstall.services.yml index 269e0189f..e85c0feb5 100644 --- a/vendor/drupal/console/services-drupal-install.yml +++ b/vendor/drupal/console/uninstall.services.yml @@ -4,7 +4,7 @@ services: arguments: ['@app.root', '@console.configuration_manager'] console.extension_manager: class: Drupal\Console\Extension\Manager - arguments: ['@console.site', '@app.root'] + arguments: ['@console.site', '@http_client', '@app.root'] console.server: class: Drupal\Console\Command\ServerCommand arguments: ['@app.root', '@console.configuration_manager'] @@ -25,3 +25,5 @@ services: arguments: ['@app.root'] tags: - { name: drupal.command } + http_client: + class: GuzzleHttp\Client diff --git a/vendor/drush/drush/.travis.yml b/vendor/drush/drush/.travis.yml index 7c51d6b97..8973c7ed1 100644 --- a/vendor/drush/drush/.travis.yml +++ b/vendor/drush/drush/.travis.yml @@ -36,13 +36,20 @@ env: - UNISH_DRUPAL_MAJOR_VERSION=7 PHPUNIT_ARGS=--group=pm - UNISH_DRUPAL_MAJOR_VERSION=7 PHPUNIT_ARGS=--group=quick-drupal - UNISH_DRUPAL_MAJOR_VERSION=7 PHPUNIT_ARGS=--exclude-group=base,make,commands,pm,quick-drupal -#D8 +#D8.3.x - UNISH_DRUPAL_MAJOR_VERSION=8 PHPUNIT_ARGS=--group=make - UNISH_DRUPAL_MAJOR_VERSION=8 PHPUNIT_ARGS=--group=base - UNISH_DRUPAL_MAJOR_VERSION=8 PHPUNIT_ARGS=--group=commands - UNISH_DRUPAL_MAJOR_VERSION=8 PHPUNIT_ARGS=--group=pm - UNISH_DRUPAL_MAJOR_VERSION=8 PHPUNIT_ARGS=--group=quick-drupal - UNISH_DRUPAL_MAJOR_VERSION=8 PHPUNIT_ARGS=--exclude-group=base,make,commands,pm,quick-drupal TEST_CHILDREN="drush-ops/config-extra" +#D8.4.x + - UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=make + - UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=base + - UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=commands + - UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=pm + - UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=quick-drupal + - UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--exclude-group=base,make,commands,pm,quick-drupal # - UNISH_DB_URL=sqlite://none/of/this/matters PHPUNIT_ARGS=--group=make # - UNISH_DB_URL=sqlite://none/of/this/matters PHPUNIT_ARGS=--group=base @@ -86,6 +93,18 @@ matrix: env: UNISH_DRUPAL_MAJOR_VERSION=8 PHPUNIT_ARGS=--group=quick-drupal - php: 5.4 env: UNISH_DRUPAL_MAJOR_VERSION=8 PHPUNIT_ARGS=--exclude-group=base,make,commands,pm,quick-drupal TEST_CHILDREN="drush-ops/config-extra" + - php: 5.4 + env: UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=make + - php: 5.4 + env: UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=base + - php: 5.4 + env: UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=commands + - php: 5.4 + env: UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=pm + - php: 5.4 + env: UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--group=quick-drupal + - php: 5.4 + env: UNISH_DRUPAL_MAJOR_VERSION=8 UNISH_DRUPAL_MINOR_VERSION=4.x PHPUNIT_ARGS=--exclude-group=base,make,commands,pm,quick-drupal before_install: - echo 'mbstring.http_input = pass' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini diff --git a/vendor/drush/drush/commands/core/cache.drush.inc b/vendor/drush/drush/commands/core/cache.drush.inc index 1df12cbca..990fc9f1a 100644 --- a/vendor/drush/drush/commands/core/cache.drush.inc +++ b/vendor/drush/drush/commands/core/cache.drush.inc @@ -277,7 +277,9 @@ function drush_cache_rebuild() { 'wincache_ucache_clear', 'xcache_clear_cache', ]; - array_map('call_user_func', array_filter($user_caches, 'is_callable')); + foreach (array_filter($user_caches, 'is_callable') as $cache) { + call_user_func($cache); + } $autoloader = drush_drupal_load_autoloader(DRUPAL_ROOT); require_once DRUSH_DRUPAL_CORE . '/includes/utility.inc'; diff --git a/vendor/drush/drush/commands/core/config.drush.inc b/vendor/drush/drush/commands/core/config.drush.inc index 8745597ba..26719547e 100644 --- a/vendor/drush/drush/commands/core/config.drush.inc +++ b/vendor/drush/drush/commands/core/config.drush.inc @@ -109,10 +109,8 @@ function config_drush_command() { 'example-value' => 'branchname', ), 'destination' => 'An arbitrary directory that should receive the exported files. An alternative to label argument.', - 'skip-modules' => 'A list of modules to ignore during export (e.g. to avoid listing dev-only modules in exported configuration).', ), 'examples' => array( - 'drush config-export --skip-modules=devel' => 'Export configuration; do not include the devel module in the exported configuration, regardless of whether or not it is enabled in the site.', 'drush config-export --destination' => 'Export configuration; Save files in a backup directory named config-export.', ), ); @@ -133,11 +131,10 @@ function config_drush_command() { 'partial' => array( 'description' => 'Allows for partial config imports from the source directory. Only updates and new configs will be processed with this flag (missing configs will not be deleted).', ), - 'skip-modules' => 'A list of modules to ignore during import (e.g. to avoid disabling dev-only modules that are not enabled in the imported configuration).', ), 'core' => array('8+'), 'examples' => array( - 'drush config-import --skip-modules=devel' => 'Import configuration; do not enable or disable the devel module, regardless of whether or not it appears in the imported list of enabled modules.', + 'drush config-import --partial' => 'Import configuration; do not remove missing configuration.', ), 'aliases' => array('cim'), ); @@ -458,7 +455,6 @@ function drush_config_export($destination = NULL) { function _drush_config_export($destination, $destination_dir, $branch) { $commit = drush_get_option('commit'); $comment = drush_get_option('message', 'Exported configuration.'); - $storage_filters = drush_config_get_storage_filters(); if (count(glob($destination_dir . '/*')) > 0) { // Retrieve a list of differences between the active and target configuration (if any). if ($destination == CONFIG_SYNC_DIRECTORY) { @@ -471,21 +467,6 @@ function _drush_config_export($destination, $destination_dir, $branch) { $active_storage = \Drupal::service('config.storage'); $comparison_source = $active_storage; - // If the output is being filtered, then write a temporary copy before doing - // any comparison. - if (!empty($storage_filters)) { - $tmpdir = drush_tempdir(); - drush_copy_dir($destination_dir, $tmpdir, FILE_EXISTS_OVERWRITE); - $comparison_source = new FileStorage($tmpdir); - $comparison_source_filtered = new StorageWrapper($comparison_source, $storage_filters); - foreach ($active_storage->listAll() as $name) { - // Copy active storage to our temporary active store. - if ($existing = $active_storage->read($name)) { - $comparison_source_filtered->write($name, $existing); - } - } - } - $config_comparer = new StorageComparer($comparison_source, $target_storage, \Drupal::service('config.manager')); if (!$config_comparer->createChangelist()->hasChanges()) { return drush_log(dt('The active configuration is identical to the configuration in the export directory (!target).', array('!target' => $destination_dir)), LogLevel::OK); @@ -521,10 +502,7 @@ function _drush_config_export($destination, $destination_dir, $branch) { else { $destination_storage = new FileStorage($destination_dir); } - // If there are any filters, then attach them to the destination storage - if (!empty($storage_filters)) { - $destination_storage = new StorageWrapper($destination_storage, $storage_filters); - } + foreach ($source_storage->listAll() as $name) { $destination_storage->write($name, $source_storage->read($name)); } @@ -599,28 +577,6 @@ function drush_config_import_validate() { } } -/** - * Return storage filters to alter config import and export. - */ -function drush_config_get_storage_filters() { - return drush_command_invoke_all('drush_storage_filters'); -} - -/** - * Implements hook_drush_storage_filters(). - */ -function config_drush_storage_filters() { - $result = array(); - $module_adjustments = drush_get_option('skip-modules'); - if (!empty($module_adjustments)) { - if (is_string($module_adjustments)) { - $module_adjustments = explode(',', $module_adjustments); - } - $result[] = new CoreExtensionFilter($module_adjustments); - } - return $result; -} - /** * Command callback. Import from specified config directory (defaults to sync). */ @@ -646,39 +602,29 @@ function drush_config_import($source = NULL) { $source_dir = config_get_config_directory($source); } + if ($source == CONFIG_SYNC_DIRECTORY) { + $source_storage = \Drupal::service('config.storage.sync'); + } + else { + $source_storage = new FileStorage($source_dir); + } + // Determine $source_storage in partial and non-partial cases. /** @var \Drupal\Core\Config\StorageInterface $active_storage */ $active_storage = \Drupal::service('config.storage'); if (drush_get_option('partial')) { - $source_storage = new StorageReplaceDataWrapper($active_storage); - $file_storage = new FileStorage($source_dir); - foreach ($file_storage->listAll() as $name) { - $data = $file_storage->read($name); - $source_storage->replaceData($name, $data); - } - } - else { - if ($source == CONFIG_SYNC_DIRECTORY) { - $source_storage = \Drupal::service('config.storage.sync'); - } - else { - $source_storage = new FileStorage($source_dir); + $replacement_storage = new StorageReplaceDataWrapper($active_storage); + foreach ($source_storage->listAll() as $name) { + $data = $source_storage->read($name); + $replacement_storage->replaceData($name, $data); } - } - - // If our configuration storage is being filtered, then attach all filters - // to the source storage object. We will use the filtered values uniformly - // for comparison, full imports, and partial imports. - $storage_filters = drush_config_get_storage_filters(); - if (!empty($storage_filters)) { - $source_storage = new StorageWrapper($source_storage, $storage_filters); + $source_storage = $replacement_storage; } /** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */ $config_manager = \Drupal::service('config.manager'); $storage_comparer = new StorageComparer($source_storage, $active_storage, $config_manager); - if (!$storage_comparer->createChangelist()->hasChanges()) { return drush_log(dt('There are no changes to import.'), LogLevel::OK); } @@ -742,7 +688,12 @@ function _drush_config_import(StorageComparer $storage_comparer) { } while ($context['finished'] < 1); } } - drush_log('The configuration was imported successfully.', LogLevel::SUCCESS); + if ($config_importer->getErrors()) { + throw new \Drupal\Core\Config\ConfigException('Errors occurred during import'); + } + else { + drush_log('The configuration was imported successfully.', LogLevel::SUCCESS); + } } catch (ConfigException $e) { // Return a negative result for UI purposes. We do not differentiate diff --git a/vendor/drush/drush/commands/core/docs.drush.inc b/vendor/drush/drush/commands/core/docs.drush.inc index f5784f7ae..432f12b6e 100644 --- a/vendor/drush/drush/commands/core/docs.drush.inc +++ b/vendor/drush/drush/commands/core/docs.drush.inc @@ -65,14 +65,6 @@ function docs_drush_command() { 'callback' => 'drush_print_file', 'callback arguments' => array($docs_dir . '/examples/example.drushrc.php'), ); - $items['docs-config-filter'] = array( - 'description' => 'Drupal Configuration Filtering with custom storage filters.', - 'hidden' => TRUE, - 'topic' => TRUE, - 'bootstrap' => DRUSH_BOOTSTRAP_NONE, - 'callback' => 'drush_print_file', - 'callback arguments' => array($docs_dir . '/docs/config-filter.md'), - ); $items['docs-config-exporting'] = array( 'description' => 'Drupal configuration export instructions, including customizing configuration by environment.', 'hidden' => TRUE, diff --git a/vendor/drush/drush/commands/core/drupal/pm_8.inc b/vendor/drush/drush/commands/core/drupal/pm_8.inc index f5a3beebe..d0d44b12c 100644 --- a/vendor/drush/drush/commands/core/drupal/pm_8.inc +++ b/vendor/drush/drush/commands/core/drupal/pm_8.inc @@ -43,16 +43,13 @@ function _drush_pm_uninstall($extensions) { drush_log(dt('!extension is already uninstalled.', array('!extension' => $extension)), LogLevel::OK); } elseif (drush_extension_get_type($extension_info[$extension]) == 'module') { - $dependents = array(); + // Add installed dependencies to the list of modules to uninstall. foreach (drush_module_dependents(array($extension), $extension_info) as $dependent) { - if (!in_array($dependent, $required) && ($extension_info[$dependent]->status)) { - $dependents[] = $dependent; + // Check if this dependency is not required, already enabled, and not already already in the list of modules to uninstall. + if (!in_array($dependent, $required) && ($extension_info[$dependent]->status) && !in_array($dependent, $extensions)) { + $extensions[] = $dependent; } } - if (count($dependents)) { - drush_log(dt('To uninstall !extension, the following extensions must be uninstalled first: !required', array('!extension' => $extension, '!required' => implode(', ', $dependents))), LogLevel::ERROR); - unset($extensions[$extension]); - } } } @@ -87,4 +84,3 @@ function _drush_pm_uninstall($extensions) { drush_log(dt('!extension was successfully uninstalled.', array('!extension' => $extension)), LogLevel::OK); } } - diff --git a/vendor/drush/drush/commands/core/drupal/site_install.inc b/vendor/drush/drush/commands/core/drupal/site_install.inc index 7c3d80b8f..f0fe0e427 100644 --- a/vendor/drush/drush/commands/core/drupal/site_install.inc +++ b/vendor/drush/drush/commands/core/drupal/site_install.inc @@ -57,10 +57,8 @@ function drush_core_site_install_version($profile, array $additional_form_option 'pass2' => $account_pass, ), ), - 'update_status_module' => array( - 1 => TRUE, - 2 => TRUE, - ), + 'enable_update_status_module' => TRUE, + 'enable_update_status_emails' => TRUE, 'clean_url' => drush_get_option('clean-url', TRUE), 'op' => dt('Save and continue'), ), diff --git a/vendor/drush/drush/commands/core/init.drush.inc b/vendor/drush/drush/commands/core/init.drush.inc index 7c82b87e1..183a41b5c 100644 --- a/vendor/drush/drush/commands/core/init.drush.inc +++ b/vendor/drush/drush/commands/core/init.drush.inc @@ -66,7 +66,7 @@ function drush_init_core_init() { if (!is_file($drush_bashrc)) { copy($example_bashrc, $drush_bashrc); $pattern = basename($drush_bashrc); - $bashrc_additions["%$pattern%"] = "# Include Drush bash customizations.\n". drush_bash_addition($drush_bashrc); + $bashrc_additions["%$pattern%"] = "\n# Include Drush bash customizations.". drush_bash_addition($drush_bashrc); drush_log(dt("Copied example Drush bash configuration file to !path", array('!path' => $drush_bashrc)), LogLevel::OK); } @@ -74,7 +74,7 @@ function drush_init_core_init() { if (!is_file($drush_complete)) { copy($example_complete, $drush_complete); $pattern = basename($drush_complete); - $bashrc_additions["%$pattern%"] = "# Include Drush completion.\n". drush_bash_addition($drush_complete); + $bashrc_additions["%$pattern%"] = "\n# Include Drush completion.\n". drush_bash_addition($drush_complete); drush_log(dt("Copied Drush completion file to !path", array('!path' => $drush_complete)), LogLevel::OK); } @@ -83,7 +83,7 @@ function drush_init_core_init() { if (!is_file($drush_prompt)) { copy($example_prompt, $drush_prompt); $pattern = basename($drush_prompt); - $bashrc_additions["%$pattern%"] = "# Include Drush prompt customizations.\n". drush_bash_addition($drush_prompt); + $bashrc_additions["%$pattern%"] = "\n# Include Drush prompt customizations.\n". drush_bash_addition($drush_prompt); drush_log(dt("Copied example Drush prompt file to !path", array('!path' => $drush_prompt)), LogLevel::OK); } @@ -98,7 +98,7 @@ function drush_init_core_init() { $drush_path = drush_find_path_to_drush($home); $drush_path = preg_replace("%^" . preg_quote($home) . "/%", '$HOME/', $drush_path); - $bashrc_additions["%$drush_path%"] = "# Path to Drush, added by 'drush init'.\nexport PATH=\"\$PATH:$drush_path\"\n\n"; + $bashrc_additions["%$drush_path%"] = "\n# Path to Drush, added by 'drush init'.\nexport PATH=\"\$PATH:$drush_path\"\n\n"; } // Modify the user's bashrc file, adding our customizations. @@ -164,6 +164,7 @@ function drush_find_path_to_drush($home) { function drush_bash_addition($file) { return << 'Install using SQLite (D7+ only).', 'drush site-install --account-name=joe --account-pass=mom' => 'Re-install with specified uid1 credentials.', 'drush site-install standard install_configure_form.site_default_country=FR my_profile_form.my_settings.key=value' => 'Pass additional arguments to the profile (D7 example shown here - for D6, omit the form id).', - "drush site-install standard install_configure_form.update_status_module='array(FALSE,FALSE)'" => 'Disable email notification during install and later. If your server has no smtp, this gets rid of an error during install.', + "drush site-install standard install_configure_form.update_status_module='array(FALSE,FALSE)'" => 'Disable email notification during install and later (D7). If your server has no mail transfer agent, this gets rid of an error during install.', + 'drush site-install standard install_configure_form.enable_update_status_module=NULL install_configure_form.enable_update_status_emails=NULL' => 'Disable email notification during install and later (D8). If your server has no mail transfer agent, this gets rid of an error during install.', ), 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT, 'aliases' => array('si'), diff --git a/vendor/drush/drush/commands/pm/pm.drush.inc b/vendor/drush/drush/commands/pm/pm.drush.inc index 8e6b6fb6a..4f955c427 100644 --- a/vendor/drush/drush/commands/pm/pm.drush.inc +++ b/vendor/drush/drush/commands/pm/pm.drush.inc @@ -289,7 +289,7 @@ function pm_drush_command() { // 'description' => 'Download and enable one or more modules', // ); $items['pm-uninstall'] = array( - 'description' => 'Uninstall one or more modules.', + 'description' => 'Uninstall one or more modules and their dependent modules.', 'arguments' => array( 'modules' => 'A list of modules.', ), diff --git a/vendor/drush/drush/commands/runserver/d7-rs-router.php b/vendor/drush/drush/commands/runserver/d7-rs-router.php new file mode 100644 index 000000000..c82e05bfd --- /dev/null +++ b/vendor/drush/drush/commands/runserver/d7-rs-router.php @@ -0,0 +1,70 @@ +uid; + $message = strtr('Watchdog: !message | severity: !severity | type: !type | uid: !uid | !ip | !request_uri | !referer | !link', array( + '!message' => strip_tags(!isset($log_entry['variables']) ? $log_entry['message'] : strtr($log_entry['message'], $log_entry['variables'])), + '!severity' => $log_entry['severity'], + '!type' => $log_entry['type'], + '!ip' => $log_entry['ip'], + '!request_uri' => $log_entry['request_uri'], + '!referer' => $log_entry['referer'], + '!uid' => $uid, + '!link' => strip_tags($log_entry['link']), + )); + error_log($message); + } +} + +// Get a $_SERVER key, or equivalent environment variable +// if it is not set in $_SERVER. +function runserver_env($key) { + if (isset($_SERVER[$key])) { + return $_SERVER[$key]; + } + else { + return getenv($key); + } +} + +$url = parse_url($_SERVER["REQUEST_URI"]); +if (file_exists('.' . $url['path'])) { + // Serve the requested resource as-is. + return FALSE; +} + +// Populate the "q" query key with the path, skip the leading slash. +$_GET['q'] = $_REQUEST['q'] = substr($url['path'], 1); + +// We set the base_url so that Drupal generates correct URLs for runserver +// (e.g. http://127.0.0.1:8888/...), but can still select and serve a specific +// site in a multisite configuration (e.g. http://mysite.com/...). +$base_url = runserver_env('RUNSERVER_BASE_URL'); + +// The built in webserver incorrectly sets $_SERVER['SCRIPT_NAME'] when URLs +// contain multiple dots (such as config entity IDs) in the path. Since this is +// a virtual resource, served by index.php set the script name explicitly. +// See https://github.com/drush-ops/drush/issues/2033 for more information. +$_SERVER['SCRIPT_NAME'] = '/index.php'; + +// Include the main index.php and let Drupal take over. +// n.b. Drush sets the cwd to the Drupal root during bootstrap. +include 'index.php'; diff --git a/vendor/drush/drush/commands/runserver/d8-rs-router.php b/vendor/drush/drush/commands/runserver/d8-rs-router.php index a0bfcb00b..d04d41d52 100644 --- a/vendor/drush/drush/commands/runserver/d8-rs-router.php +++ b/vendor/drush/drush/commands/runserver/d8-rs-router.php @@ -1,5 +1,39 @@ id(); + $message = strtr('Watchdog: !message | severity: !severity | type: !type | uid: !uid | !ip | !request_uri | !referer | !link', array( + '!message' => strip_tags(!isset($log_entry['variables']) ? $log_entry['message'] : strtr($log_entry['message'], $log_entry['variables'])), + '!severity' => $log_entry['severity'], + '!type' => $log_entry['type'], + '!ip' => $log_entry['ip'], + '!request_uri' => $log_entry['request_uri'], + '!referer' => $log_entry['referer'], + '!uid' => $uid, + '!link' => strip_tags($log_entry['link']), + )); + error_log($message); + } +} + // Get a $_SERVER key, or equivalent environment variable // if it is not set in $_SERVER. function runserver_env($key) { diff --git a/vendor/drush/drush/commands/runserver/runserver.drush.inc b/vendor/drush/drush/commands/runserver/runserver.drush.inc index 3c2c9e107..13103f2ac 100644 --- a/vendor/drush/drush/commands/runserver/runserver.drush.inc +++ b/vendor/drush/drush/commands/runserver/runserver.drush.inc @@ -131,9 +131,12 @@ function drush_core_runserver($uri = NULL) { drush_start_browser($browse, 2); } // Start the server using 'php -S'. - if (drush_drupal_major_version() >=8) { + if (drush_drupal_major_version() >= 8) { $extra = ' "' . __DIR__ . '/d8-rs-router.php"'; } + elseif (drush_drupal_major_version() == 7) { + $extra = ' "' . __DIR__ . '/d7-rs-router.php"'; + } else { $extra = ' --define auto_prepend_file="' . __DIR__ . '/runserver-prepend.php"'; } diff --git a/vendor/drush/drush/docs/config-exporting.md b/vendor/drush/drush/docs/config-exporting.md index 1ed16a913..a31428c85 100644 --- a/vendor/drush/drush/docs/config-exporting.md +++ b/vendor/drush/drush/docs/config-exporting.md @@ -29,33 +29,9 @@ a Drush feature. It should be the preferred method for changing configuration values on a per-environment basis; however, it does not work for some things, such as enabling and disabling modules. For configuration changes not handled by the configuration override system, -you can use Drush configuration filters. +you can use configuration filters of the Config Filter module. ## Ignoring Development Modules -If you have a certain list of modules that should only be enabled on -the development or staging server, then this may be done with the -built-in `--skip-modules` option in the config-export and config-import -commands. - -For example, if you want to enable the 'devel' module on development -systems, but not on production server, you could define the following -configuration settings in your drushrc.php file: -``` -# $command_specific['config-export']['skip-modules'] = array('devel'); -# $command_specific['config-import']['skip-modules'] = array('devel'); -``` -You may then use `drush pm-enable` to enable the devel module on the -development machine, and subsequent imports of the configuration data -will not cause it to be disabled again. Similarly, if you make changes -to configuration on the development environment and export them, then -the devel module will not be listed in the exports. - -## More Complex Adjustments - -Drush allows more complex changes to the configuration data to be made -via the configuration filter mechanism. In order to do this, you must -write some code inside a Drush extension. - -See [Drupal Configuration Filtering](config-filter.md) for more information -on how to do this. +Use the [Config Split](https://www.drupal.org/project/config_split) module to +split off development configuration in a dedicated config directory. \ No newline at end of file diff --git a/vendor/drush/drush/docs/config-filter.md b/vendor/drush/drush/docs/config-filter.md deleted file mode 100644 index 8cea79717..000000000 --- a/vendor/drush/drush/docs/config-filter.md +++ /dev/null @@ -1,66 +0,0 @@ -# Filtering Drupal Configuration - -When exporting and importing configuration from and to a Drupal 8 site, -Drush provides a mechanism called the Configuration Filter system which -allows configuration values to be altered during import and export, allowing -you to vary your configuration by environment. The --skip-modules option -in the config-import and config-export commands is implemented with a -configuration filter. For more complex uses, you will need to write some -custom code. - -## Other Alternatives - -The Drupal Configuration system provides the capability to [add configuration -overrides from modules](https://www.drupal.org/node/1928898). Configuration -overrides should be provided from a module override when possible. Implementing -an override via a Drush extension is convenient in situations where you would -like to be able to pass values in to the configuration filter via a Drush -commandline option. - -## Filtering Drupal Configuration with Drush - -Instructions on writing a Drush extension to filter Drupal configuration follows. - -### Getting started - -The first thing that you will need to do is set up a Drush extension -to hold your storage filter hook. See the example -[example sandwich commandfile](../examples/sandwich-drush.inc) for -details; note, however, that it is not necessary for your commandfile -to implement hook_drush_command(), or any other hook besides the storage -filter hook. - -You will need a composer.json file as well, in order to define where -your StorageFilter class is defined. Make sure that Drush and your -custom commandfile are required from the composer.json file of any -Drupal site that you plan on using your filter with. - -### Implementing the Storage Filter Hook - -When Drush imports or exports configuration, it gives all Drush -extensions a chance to hook this process by way of the hook -hook_drush_storage_filters. The implementation of this hook, -in the file MYFILTER.drush.inc, would look like this: -``` -function MYFILTER_drush_storage_filters() { - $result = array(); - $my_option = drush_get_option('my-option'); - if (!empty($my_option)) { - $result[] = new MyConfigurationFilter($my_option); - } - return $result; -} -``` -With this hook in place, MyConfigurationFilter will become part of -the import / export process. - -### Implementing a Storage Filter - -It is necessary to implement a class that implements -[StorageFilter](https://github.com/drush-ops/drush/blob/master/lib/Drush/Config/StorageFilter.php). -Your class only needs to implement the two methods defined there, -filterRead() and filterWrite(), to make whichever alterations to configuration -you need during the export and import operations, respectively. For -an example class that implements StorageFilter, see the -[CoreExtensionFilter](https://github.com/drush-ops/drush/blob/master/lib/Drush/Config/CoreExtensionFilter.php) -class. diff --git a/vendor/drush/drush/docs/make.md b/vendor/drush/drush/docs/make.md index 4915ff9cd..94aebdf3c 100644 --- a/vendor/drush/drush/docs/make.md +++ b/vendor/drush/drush/docs/make.md @@ -102,8 +102,8 @@ Do not use both types of declarations for a single project in your makefile. - `patch` - One or more patches to apply to this project. An array of URLs from which - each patch should be retrieved. + One or more patches to apply to this project. An array of patches, + each specified as a URL or local path relative to the makefile. projects: calendar: @@ -116,6 +116,7 @@ Do not use both types of declarations for a single project in your makefile. patch: - "http://drupal.org/files/issues/adminrole_exceptions.patch" - "http://drupal.org/files/issues/adminrole-213212-01.patch" + - "adminrole-customizations.patch" - `subdir` diff --git a/vendor/drush/drush/drush.api.php b/vendor/drush/drush/drush.api.php index 21a9aa868..6b99d9ddb 100644 --- a/vendor/drush/drush/drush.api.php +++ b/vendor/drush/drush/drush.api.php @@ -420,22 +420,6 @@ function hook_drush_invoke_alter($modules, $hook) { } } -/* - * Storage filters alter the .yml files on disk after a config-export or before - * a config-import. See `drush topic docs-config-filter` and config_drush_storage_filters(). - */ -function hook_drush_storage_filters() { - $result = array(); - $module_adjustments = drush_get_option('skip-modules'); - if (!empty($module_adjustments)) { - if (is_string($module_adjustments)) { - $module_adjustments = explode(',', $module_adjustments); - } - $result[] = new CoreExtensionFilter($module_adjustments); - } - return $result; -} - /** * @} End of "addtogroup hooks". */ diff --git a/vendor/drush/drush/drush.info b/vendor/drush/drush/drush.info index c77896307..cb563b31a 100644 --- a/vendor/drush/drush/drush.info +++ b/vendor/drush/drush/drush.info @@ -1 +1 @@ -drush_version=8.1.10 +drush_version=8.1.12 diff --git a/vendor/drush/drush/lib/Drush/Boot/DrupalBoot8.php b/vendor/drush/drush/lib/Drush/Boot/DrupalBoot8.php index f427571b3..468e963aa 100644 --- a/vendor/drush/drush/lib/Drush/Boot/DrupalBoot8.php +++ b/vendor/drush/drush/lib/Drush/Boot/DrupalBoot8.php @@ -4,11 +4,9 @@ namespace Drush\Boot; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Psr\Log\LoggerInterface; use Drupal\Core\DrupalKernel; use Drush\Drupal\DrupalKernel as DrushDrupalKernel; -use Drush\Drupal\DrushServiceModfier; -use Symfony\Component\DependencyInjection\Reference; +use Drush\Drupal\DrushServiceModifier; use Drush\Log\LogLevel; @@ -128,7 +126,7 @@ class DrupalBoot8 extends DrupalBoot { $this->kernel = DrushDrupalKernel::createFromRequest($this->request, $classloader, 'prod'); } // @see Drush\Drupal\DrupalKernel::addServiceModifier() - $this->kernel->addServiceModifier(new DrushServiceModfier()); + $this->kernel->addServiceModifier(new DrushServiceModifier()); // Unset drupal error handler and restore Drush's one. restore_error_handler(); @@ -145,7 +143,6 @@ class DrupalBoot8 extends DrupalBoot { if (!drush_get_context('DRUSH_QUIET', FALSE)) { ob_start(); } - $this->kernel->invalidateContainer(); $this->kernel->boot(); $this->kernel->prepareLegacyRequest($this->request); if (!drush_get_context('DRUSH_QUIET', FALSE)) { diff --git a/vendor/drush/drush/lib/Drush/Command/DrushInputAdapter.php b/vendor/drush/drush/lib/Drush/Command/DrushInputAdapter.php index 29126f19a..801b58c32 100644 --- a/vendor/drush/drush/lib/Drush/Command/DrushInputAdapter.php +++ b/vendor/drush/drush/lib/Drush/Command/DrushInputAdapter.php @@ -24,7 +24,8 @@ use Symfony\Component\Console\Input\InputDefinition; * 2) We do not want Symfony to attempt to validate our options or arguments * for us. */ -class DrushInputAdapter implements InputInterface { +class DrushInputAdapter implements InputInterface +{ protected $arguments; protected $options; protected $interactive; @@ -52,13 +53,13 @@ class DrushInputAdapter implements InputInterface { */ public function getFirstArgument() { - return reset($arguments); + return reset($this->arguments); } /** * {@inheritdoc} */ - public function hasParameterOption($values) + public function hasParameterOption($values, $onlyParams = false) { $values = (array) $values; @@ -74,7 +75,7 @@ class DrushInputAdapter implements InputInterface { /** * {@inheritdoc} */ - public function getParameterOption($values, $default = false) + public function getParameterOption($values, $default = false, $onlyParams = false) { $values = (array) $values; diff --git a/vendor/drush/drush/lib/Drush/Config/CoreExtensionFilter.php b/vendor/drush/drush/lib/Drush/Config/CoreExtensionFilter.php deleted file mode 100644 index 43c9b2b2e..000000000 --- a/vendor/drush/drush/lib/Drush/Config/CoreExtensionFilter.php +++ /dev/null @@ -1,81 +0,0 @@ -adjustments = $adjustments; - } - - public function filterRead($name, $data) { - if ($name != 'core.extension') { - return $data; - } - $active_storage = \Drupal::service('config.storage'); - return $this->filterOutIgnored($data, $active_storage->read($name)); - } - - public function filterWrite($name, array $data, StorageInterface $storage) { - if ($name != 'core.extension') { - return $data; - } - $originalData = $storage->read($name); - return $this->filterOutIgnored($data, $storage->read($name)); - } - - protected function filterOutIgnored($data, $originalData) { - foreach($this->adjustments as $module) { - if (is_array($originalData) && array_key_exists($module, $originalData['module'])) { - $data['module'][$module] = $originalData['module'][$module]; - } - else { - unset($data['module'][$module]); - } - } - return $data; - - } -} diff --git a/vendor/drush/drush/lib/Drush/Config/StorageFilter.php b/vendor/drush/drush/lib/Drush/Config/StorageFilter.php deleted file mode 100644 index 790748d6e..000000000 --- a/vendor/drush/drush/lib/Drush/Config/StorageFilter.php +++ /dev/null @@ -1,44 +0,0 @@ -storage = $storage; - $this->filters = is_array($filterOrFilters) ? $filterOrFilters : array($filterOrFilters); - } - - /** - * {@inheritdoc} - */ - public function exists($name) { - return $this->storage->exists($name); - } - - /** - * {@inheritdoc} - */ - public function read($name) { - $data = $this->storage->read($name); - - foreach ($this->filters as $filter) { - $data = $filter->filterRead($name, $data); - } - - return $data; - } - - /** - * {@inheritdoc} - */ - public function readMultiple(array $names) { - $dataList = $this->storage->readMultiple($names); - $result = array(); - - foreach ($dataList as $name => $data) { - foreach ($this->filters as $filter) { - $data = $filter->filterRead($name, $data); - } - $result[$name] = $data; - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function write($name, array $data) { - foreach ($this->filters as $filter) { - $data = $filter->filterWrite($name, $data, $this->storage); - } - - return $this->storage->write($name, $data); - } - - /** - * {@inheritdoc} - */ - public function delete($name) { - return $this->storage->delete($name); - } - - /** - * {@inheritdoc} - */ - public function rename($name, $new_name) { - return $this->storage->rename($name, $new_name); - } - - /** - * {@inheritdoc} - */ - public function encode($data) { - return $this->storage->encode($data); - } - - /** - * {@inheritdoc} - */ - public function decode($raw) { - return $this->storage->decode($raw); - } - - /** - * {@inheritdoc} - */ - public function listAll($prefix = '') { - return $this->storage->listAll($prefix); - } - - /** - * {@inheritdoc} - */ - public function deleteAll($prefix = '') { - return $this->storage->deleteAll($prefix); - } - - /** - * {@inheritdoc} - */ - public function createCollection($collection) { - return $this->storage->createCollection($collection); - } - - /** - * {@inheritdoc} - */ - public function getAllCollectionNames() { - return $this->storage->getAllCollectionNames(); - } - - /** - * {@inheritdoc} - */ - public function getCollectionName() { - return $this->storage->getCollectionName(); - } - -} diff --git a/vendor/drush/drush/lib/Drush/Drupal/DrupalKernel.php b/vendor/drush/drush/lib/Drush/Drupal/DrupalKernel.php index 73456ed46..39fa15c0f 100644 --- a/vendor/drush/drush/lib/Drush/Drupal/DrupalKernel.php +++ b/vendor/drush/drush/lib/Drush/Drupal/DrupalKernel.php @@ -43,4 +43,21 @@ class DrupalKernel extends DrupalDrupalKernel { } return $container; } + /** + * Initializes the service container. + * + * @return \Symfony\Component\DependencyInjection\ContainerInterface + */ + protected function initializeContainer() { + if (empty($this->moduleList) && !$this->containerNeedsRebuild) { + $container_definition = $this->getCachedContainerDefinition(); + foreach ($this->serviceModifiers as $serviceModifier) { + if (!$serviceModifier->check($container_definition)) { + $this->invalidateContainer(); + break; + } + } + } + return parent::initializeContainer(); + } } diff --git a/vendor/drush/drush/lib/Drush/Drupal/DrushServiceModfier.php b/vendor/drush/drush/lib/Drush/Drupal/DrushServiceModifier.php similarity index 65% rename from vendor/drush/drush/lib/Drush/Drupal/DrushServiceModfier.php rename to vendor/drush/drush/lib/Drush/Drupal/DrushServiceModifier.php index 7d6dec4aa..14a8a292e 100644 --- a/vendor/drush/drush/lib/Drush/Drupal/DrushServiceModfier.php +++ b/vendor/drush/drush/lib/Drush/Drupal/DrushServiceModifier.php @@ -6,7 +6,7 @@ use Drush\Log\LogLevel; use Drupal\Core\DependencyInjection\ServiceModifierInterface; use Drupal\Core\DependencyInjection\ContainerBuilder; -class DrushServiceModfier implements ServiceModifierInterface +class DrushServiceModifier implements ServiceModifierInterface { /** * @inheritdoc @@ -19,4 +19,15 @@ class DrushServiceModfier implements ServiceModifierInterface $container->register('drush.service.consolidationcommands', 'Drush\Command\ServiceCommandlist'); $container->addCompilerPass(new FindCommandsCompilerPass('drush.service.consolidationcommands', 'consolidation.commandhandler')); } + /** + * Checks existing service definitions for the presence of modification. + * + * @param $container_definition + * Cached container definition + * @return bool + */ + public function check($container_definition) { + return isset($container_definition['services']['drush.service.consolecommands']) && + isset($container_definition['services']['drush.service.consolidationcommands']); + } } diff --git a/vendor/drush/drush/mkdocs.yml b/vendor/drush/drush/mkdocs.yml index 98f17b1b8..470a41ae8 100644 --- a/vendor/drush/drush/mkdocs.yml +++ b/vendor/drush/drush/mkdocs.yml @@ -21,7 +21,6 @@ pages: - Command Authoring: commands.md - Bootstrap: bootstrap.md - Context system: context.md - - Filtering Drupal configuration: config-filter.md theme: readthedocs site_author: "" repo_url: https://github.com/drush-ops/drush diff --git a/vendor/drush/drush/tests/Unish/UnishTestCase.php b/vendor/drush/drush/tests/Unish/UnishTestCase.php index 37fe9806c..e9ae4ab8d 100644 --- a/vendor/drush/drush/tests/Unish/UnishTestCase.php +++ b/vendor/drush/drush/tests/Unish/UnishTestCase.php @@ -263,7 +263,14 @@ abstract class UnishTestCase extends \PHPUnit_Framework_TestCase { return parse_url(UNISH_DB_URL, PHP_URL_SCHEME); } - function setUpDrupal($num_sites = 1, $install = FALSE, $version_string = UNISH_DRUPAL_MAJOR_VERSION, $profile = NULL) { + function defaultInstallationVerion() { + return UNISH_DRUPAL_MAJOR_VERSION . UNISH_DRUPAL_MINOR_VERSION; + } + + function setUpDrupal($num_sites = 1, $install = FALSE, $version_string = NULL, $profile = NULL) { + if (!$version_string) { + $version_string = UNISH_DRUPAL_MAJOR_VERSION; + } $sites_subdirs_all = array('dev', 'stage', 'prod', 'retired', 'elderly', 'dead', 'dust'); $sites_subdirs = array_slice($sites_subdirs_all, 0, $num_sites); $root = $this->webroot(); @@ -315,7 +322,10 @@ abstract class UnishTestCase extends \PHPUnit_Framework_TestCase { return self::$sites; } - function fetchInstallDrupal($env = 'dev', $install = FALSE, $version_string = UNISH_DRUPAL_MAJOR_VERSION, $profile = NULL, $separate_roots = FALSE) { + function fetchInstallDrupal($env = 'dev', $install = FALSE, $version_string = NULL, $profile = NULL, $separate_roots = FALSE) { + if (!$version_string) { + $version_string = UNISH_DRUPAL_MAJOR_VERSION; + } $root = $this->webroot(); $uri = $separate_roots ? "default" : "$env"; $options = array(); diff --git a/vendor/drush/drush/tests/archiveDumpTest.php b/vendor/drush/drush/tests/archiveDumpTest.php index cfeb48e9a..5085142a9 100644 --- a/vendor/drush/drush/tests/archiveDumpTest.php +++ b/vendor/drush/drush/tests/archiveDumpTest.php @@ -22,7 +22,7 @@ class archiveDumpCase extends CommandUnishTestCase { */ private function archiveDump($no_core) { $profile = UNISH_DRUPAL_MAJOR_VERSION >= 7 ? 'testing' : 'default'; - $this->fetchInstallDrupal(self::uri, TRUE, UNISH_DRUPAL_MAJOR_VERSION, $profile); + $this->fetchInstallDrupal(self::uri, TRUE, NULL, $profile); $root = $this->webroot(); $dump_dest = UNISH_SANDBOX . DIRECTORY_SEPARATOR . 'dump.tar.gz'; $options = array( diff --git a/vendor/drush/drush/tests/bootstrap.inc b/vendor/drush/drush/tests/bootstrap.inc index be5b978e9..ab7f8cc19 100644 --- a/vendor/drush/drush/tests/bootstrap.inc +++ b/vendor/drush/drush/tests/bootstrap.inc @@ -31,6 +31,16 @@ function unish_init() { $unish_drupal_major = $GLOBALS['UNISH_DRUPAL_MAJOR_VERSION']; } define('UNISH_DRUPAL_MAJOR_VERSION', $unish_drupal_major); + $unish_drupal_minor = ''; + if ($unish_drupal_major == 8) { + if (getenv('UNISH_DRUPAL_MINOR_VERSION')) { + $unish_drupal_minor = '.' . getenv('UNISH_DRUPAL_MINOR_VERSION'); + } + elseif (isset($GLOBALS['UNISH_DRUPAL_MINOR_VERSION'])) { + $unish_drupal_minor = '.' . $GLOBALS['UNISH_DRUPAL_MINOR_VERSION']; + } + } + define('UNISH_DRUPAL_MINOR_VERSION', $unish_drupal_minor); // We read from env then globals then default to mysql. $unish_db_url = 'mysql://root:@127.0.0.1'; diff --git a/vendor/drush/drush/tests/configTest.php b/vendor/drush/drush/tests/configTest.php index 318980236..77d9d075c 100644 --- a/vendor/drush/drush/tests/configTest.php +++ b/vendor/drush/drush/tests/configTest.php @@ -74,35 +74,6 @@ class ConfigCase extends CommandUnishTestCase { $this->drush('config-get', array('system.site', 'page'), $options + array('format' => 'json')); $page = $this->getOutputFromJSON('system.site:page'); $this->assertContains('unish partial', $page->front, '--partial was successfully imported.'); - - $this->drush('pm-enable', array('tracker'), $options); - $ignored_modules = array('skip-modules' => 'tracker'); - - // Run config-export again - note that 'tracker' is enabled, but we - // are going to ignore it on write, so no changes should be written - // to core.extension when it is exported. - $this->drush('config-export', array(), $options + $ignored_modules); - $this->assertFileExists($core_extension_yml); - $contents = file_get_contents($core_extension_yml); - $this->assertNotContains('tracker', $contents); - - // Run config-import again, but ignore 'tracker' when importing. - // It is not presently in the exported configuration, because we enabled - // it after export. If we imported again without adding 'tracker' with - // 'skip-modules' option, then it would be disabled. - $this->drush('config-import', array(), $options + $ignored_modules); - $this->drush('config-get', array('core.extension', 'module'), $options + array('format' => 'yaml')); - $modules = $this->getOutput(); - $this->assertContains('tracker', $modules, 'Tracker module appears in extension list after import, as it should.'); - - // Run config-export one final time. 'tracker' is still enabled, even - // though it was ignored in the previous import/export operations. - // When we remove the skip-modules option, then 'tracker' will - // be exported. - $this->drush('config-export', array(), $options); - $this->assertFileExists($core_extension_yml); - $contents = file_get_contents($core_extension_yml); - $this->assertContains('tracker', $contents); } function options() { diff --git a/vendor/drush/drush/tests/makeTest.php b/vendor/drush/drush/tests/makeTest.php index 7741e77ae..cccc70fa6 100644 --- a/vendor/drush/drush/tests/makeTest.php +++ b/vendor/drush/drush/tests/makeTest.php @@ -380,6 +380,7 @@ class makeMakefileCase extends CommandUnishTestCase { } } + /* TODO: http://download.gna.org/wkhtmltopdf/obsolete/linux/wkhtmltopdf-0.11.0_rc1-static-amd64.tar.bz2 cannot be downloaded any longer function testMakeBZ2SingleFile() { // Silently skip bz2 test if bz2 is not installed. exec('which bzip2', $output, $whichBzip2ErrorCode); @@ -390,6 +391,7 @@ class makeMakefileCase extends CommandUnishTestCase { $this->markTestSkipped('bzip2 command not available.'); } } + */ function testMakeContribDestination() { $this->runMakefileTest('contrib-destination'); diff --git a/vendor/drush/drush/tests/pmUpdateCodeTest.php b/vendor/drush/drush/tests/pmUpdateCodeTest.php index 5fc9ad20c..e4b966887 100644 --- a/vendor/drush/drush/tests/pmUpdateCodeTest.php +++ b/vendor/drush/drush/tests/pmUpdateCodeTest.php @@ -25,9 +25,11 @@ class pmUpdateCode extends CommandUnishTestCase { $list = $this->getOutputAsList(); // Line 0 is "Release" // Line 1 is "...-dev" - // Line 2 is current best release - // Line 3 is the previous release - return trim($list[3]); + // Line 2 is "...-dev" + // Line 3 is "...-dev" + // Line 4 is current best release + // Line 5 is the previous release + return trim($list[5]); } /** diff --git a/vendor/ezyang/htmlpurifier/NEWS b/vendor/ezyang/htmlpurifier/NEWS index 82ebedf3e..fd5d56cf0 100644 --- a/vendor/ezyang/htmlpurifier/NEWS +++ b/vendor/ezyang/htmlpurifier/NEWS @@ -9,6 +9,14 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier . Internal change ========================== +4.9.3, released 2017-06-02 +- Workaround PHP 7.1 infinite loop when opcode cache is enabled. + Thanks @Xiphin (#134, #135) +- Don't use autoloader when testing for DOMDocument. Hypothetically, + this could cause your install to start using DirectLex if you had + previously been monkeypatching in a custom, autoloaded implementation + of DOMDocument. Don't do that. Thanks @Izumi-kun (#130) + 4.9.2, released 2017-03-12 - Fixes PHP 5.3 compatibility - Fix breakage when decoding decimal entities. Thanks @rybakit (#129) diff --git a/vendor/ezyang/htmlpurifier/VERSION b/vendor/ezyang/htmlpurifier/VERSION index b550c72a1..e94f14fa9 100644 --- a/vendor/ezyang/htmlpurifier/VERSION +++ b/vendor/ezyang/htmlpurifier/VERSION @@ -1 +1 @@ -4.9.2 \ No newline at end of file +4.9.3 \ No newline at end of file diff --git a/vendor/ezyang/htmlpurifier/WHATSNEW b/vendor/ezyang/htmlpurifier/WHATSNEW index b435e664b..810086f27 100644 --- a/vendor/ezyang/htmlpurifier/WHATSNEW +++ b/vendor/ezyang/htmlpurifier/WHATSNEW @@ -7,6 +7,7 @@ entity decoding (we won't accidentally encode entities that occur in URLs) and rel="noopener" on links with target attributes, to prevent them from overwriting the original frame. -4.9.0 was skipped due to a packaging problem; 4.9.2 fixes two -major regressions in PHP 5.3 support and entity decoding; no -other functional changes were applied. +4.9.3 works around an infinite loop bug in PHP 7.1 with the opcode +cache (and has one other, minor bugfix, avoiding using autoloading +when testing for DOMDocument presence). If these bugs do not +affect you, you do not need to upgrade. diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.includes.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.includes.php index 7779fe34d..e8bce5c85 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.includes.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.includes.php @@ -7,7 +7,7 @@ * primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS * FILE, changes will be overwritten the next time the script is run. * - * @version 4.9.2 + * @version 4.9.3 * * @warning * You must *not* include any other HTML Purifier files before this file, diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.php index 9c539e225..b4605ebc6 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier.php @@ -19,7 +19,7 @@ */ /* - HTML Purifier 4.9.2 - Standards Compliant HTML Filtering + HTML Purifier 4.9.3 - Standards Compliant HTML Filtering Copyright (C) 2006-2008 Edward Z. Yang This library is free software; you can redistribute it and/or @@ -58,12 +58,12 @@ class HTMLPurifier * Version of HTML Purifier. * @type string */ - public $version = '4.9.2'; + public $version = '4.9.3'; /** * Constant with version of HTML Purifier. */ - const VERSION = '4.9.2'; + const VERSION = '4.9.3'; /** * Global configuration object. diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ChildDef/List.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ChildDef/List.php index 5a53a4b49..4fc70e0ef 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ChildDef/List.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ChildDef/List.php @@ -50,7 +50,7 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef // a little sanity check to make sure it's not ALL whitespace $all_whitespace = true; - $current_li = false; + $current_li = null; foreach ($children as $node) { if (!empty($node->is_whitespace)) { @@ -71,7 +71,7 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef // to handle non-list elements; non-list elements should // not be appended to an existing li; only li created // for non-list. This distinction is not currently made. - if ($current_li === false) { + if ($current_li === null) { $current_li = new HTMLPurifier_Node_Element('li'); $result[] = $current_li; } diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Config.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Config.php index 69e6d2765..3648364b3 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Config.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Config.php @@ -21,7 +21,7 @@ class HTMLPurifier_Config * HTML Purifier's version * @type string */ - public $version = '4.9.2'; + public $version = '4.9.3'; /** * Whether or not to automatically finalize @@ -333,7 +333,7 @@ class HTMLPurifier_Config } // Raw type might be negative when using the fully optimized form - // of stdclass, which indicates allow_null == true + // of stdClass, which indicates allow_null == true $rtype = is_int($def) ? $def : $def->type; if ($rtype < 0) { $type = -$rtype; diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ConfigSchema.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ConfigSchema.php index bfbb0f92f..655c0e97a 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ConfigSchema.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/ConfigSchema.php @@ -24,11 +24,11 @@ class HTMLPurifier_ConfigSchema * * array( * 'Namespace' => array( - * 'Directive' => new stdclass(), + * 'Directive' => new stdClass(), * ) * ) * - * The stdclass may have the following properties: + * The stdClass may have the following properties: * * - If isAlias isn't set: * - type: Integer type of directive, see HTMLPurifier_VarParser for definitions @@ -39,8 +39,8 @@ class HTMLPurifier_ConfigSchema * - namespace: Namespace this directive aliases to * - name: Directive name this directive aliases to * - * In certain degenerate cases, stdclass will actually be an integer. In - * that case, the value is equivalent to an stdclass with the type + * In certain degenerate cases, stdClass will actually be an integer. In + * that case, the value is equivalent to an stdClass with the type * property set to the integer. If the integer is negative, type is * equal to the absolute value of integer, and allow_null is true. * @@ -105,7 +105,7 @@ class HTMLPurifier_ConfigSchema */ public function add($key, $default, $type, $allow_null) { - $obj = new stdclass(); + $obj = new stdClass(); $obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type]; if ($allow_null) { $obj->allow_null = true; @@ -152,14 +152,14 @@ class HTMLPurifier_ConfigSchema */ public function addAlias($key, $new_key) { - $obj = new stdclass; + $obj = new stdClass; $obj->key = $new_key; $obj->isAlias = true; $this->info[$key] = $obj; } /** - * Replaces any stdclass that only has the type property with type integer. + * Replaces any stdClass that only has the type property with type integer. */ public function postProcess() { diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Generator.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Generator.php index 6fb568714..eb56e2dfa 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Generator.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Generator.php @@ -146,7 +146,7 @@ class HTMLPurifier_Generator $attr = $this->generateAttributes($token->attr, $token->name); if ($this->_flashCompat) { if ($token->name == "object") { - $flash = new stdclass(); + $flash = new stdClass(); $flash->attr = $token->attr; $flash->param = array(); $this->_flashStack[] = $flash; diff --git a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer.php b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer.php index 99b3c7df0..e9da3ed5e 100644 --- a/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer.php +++ b/vendor/ezyang/htmlpurifier/library/HTMLPurifier/Lexer.php @@ -96,7 +96,7 @@ class HTMLPurifier_Lexer break; } - if (class_exists('DOMDocument') && + if (class_exists('DOMDocument', false) && method_exists('DOMDocument', 'loadHTML') && !extension_loaded('domxml') ) { diff --git a/vendor/gabordemooij/redbean/.gitignore b/vendor/gabordemooij/redbean/.gitignore new file mode 100644 index 000000000..4294ebe3a --- /dev/null +++ b/vendor/gabordemooij/redbean/.gitignore @@ -0,0 +1,26 @@ +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so +*.pyc + +# Logs and databases # +###################### +*.log + +# OS generated files # +###################### +.DS_Store* +ehthumbs.db +Icon? +Thumbs.db +/.project +/.settings/org.eclipse.php.core.prefs +/.settings/org.eclipse.php.debug.core.Debug_Process_Preferences.prefs +/rb.phar +/rb.php +build/ diff --git a/vendor/gabordemooij/redbean/.travis.yml b/vendor/gabordemooij/redbean/.travis.yml new file mode 100644 index 000000000..8cb349d3f --- /dev/null +++ b/vendor/gabordemooij/redbean/.travis.yml @@ -0,0 +1,20 @@ +language: php +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - hhvm + +before_script: + - touch /tmp/oodb.db + - mysql -e 'create database oodb;' + - psql template1 -c 'CREATE EXTENSION "uuid-ossp";' -U postgres + - psql -c 'create database oodb;' -U postgres + - php replica2.php onlyphp + - cp rb.php testing/cli/testcontainer/rb.php + - cd testing/cli + + +script: php runtests.php diff --git a/vendor/gabordemooij/redbean/README.markdown b/vendor/gabordemooij/redbean/README.markdown new file mode 100755 index 000000000..d82c223cd --- /dev/null +++ b/vendor/gabordemooij/redbean/README.markdown @@ -0,0 +1,55 @@ +RedBeanPHP 4 +============ + +![Build Status](https://travis-ci.org/gabordemooij/redbean.svg?branch=master) + +RedBeanPHP is an easy to use ORM tool for PHP. + +* Automatically creates tables and columns as you go +* No configuration, just fire and forget +* No complicated package tools, no autoloaders, just ONE file + +Installation via Composer +------------------------- + +Just open your composer.json file and add the package name ```(e.g. "gabordemooij/redbean": "dev-master")``` in your require list. + +```json +{ + "require": { + "gabordemooij/redbean": "dev-master" + } +} +``` + +**NOTE**: +You will find many examples on the redbean website make use of RedBean's `R` class. Because of namespaced autoloading in composer, this class will be available as `\RedbeanPHP\R` instead of `R`. If you desire to use the much shorter `R` class, you can utilize PHP's `class_alias()` function to take care of the job for you as so: + +```php +class_alias('\RedBeanPHP\R','\R'); +``` + +If you are not using composer then [try it.](http://redbeanphp.com/install) + + +Quick Example +------------- + +How we store a book object with RedBeanPHP: +```php +$book = R::dispense("book"); +$book->author = "Santa Claus"; +$book->title = "Secrets of Christmas"; +$id = R::store( $book ); +``` + +Yep, it's that simple. + + +More information +---------------- + +For more information about RedBeanPHP please consult +the RedBeanPHP website: + +http://www.redbeanphp.com/ diff --git a/vendor/gabordemooij/redbean/RedBeanPHP/OODBBean.php b/vendor/gabordemooij/redbean/RedBeanPHP/OODBBean.php index f77f4f2b0..ac3719061 100755 --- a/vendor/gabordemooij/redbean/RedBeanPHP/OODBBean.php +++ b/vendor/gabordemooij/redbean/RedBeanPHP/OODBBean.php @@ -548,7 +548,7 @@ class OODBBean implements\IteratorAggregate,\ArrayAccess,\Countable,Jsonable { $myID = $this->properties['id']; - $this->import( $otherBean->export() ); + $this->import( $otherBean->export( FALSE, FALSE, TRUE ) ); $this->id = $myID; @@ -1068,6 +1068,8 @@ class OODBBean implements\IteratorAggregate,\ArrayAccess,\Countable,Jsonable $hasSQL = ($this->withSql !== '' || $this->via !== NULL); $exists = isset( $this->properties[$property] ); $fieldLink = $property . '_id'; + $isFieldLink = (($pos = strrpos($property, '_id')) !== FALSE) && array_key_exists( ($fieldName = substr($property, 0, $pos)), $this->properties ); + if ( ($isOwn || $isShared) && (!$exists || $hasSQL || $differentAlias) ) { @@ -1104,6 +1106,12 @@ class OODBBean implements\IteratorAggregate,\ArrayAccess,\Countable,Jsonable throw new RedException( 'Cannot cast to bean.' ); } } + + if ( $isFieldLink ){ + unset( $this->properties[ $fieldName ]); + $this->properties[ $property ] = NULL; + } + if ( $value === FALSE ) { $value = '0'; diff --git a/vendor/gabordemooij/redbean/deepfreeze.php b/vendor/gabordemooij/redbean/deepfreeze.php new file mode 100644 index 000000000..36b2ad4cb --- /dev/null +++ b/vendor/gabordemooij/redbean/deepfreeze.php @@ -0,0 +1,49 @@ + 0) { + echo 'Applied patch for PHP < 5.3.3'; + echo PHP_EOL; + exit; +} else { + echo 'Somthing went wrong.'; + echo PHP_EOL; + exit; +} diff --git a/vendor/gabordemooij/redbean/replica2-win.php b/vendor/gabordemooij/redbean/replica2-win.php new file mode 100644 index 000000000..01f1928c0 --- /dev/null +++ b/vendor/gabordemooij/redbean/replica2-win.php @@ -0,0 +1,34 @@ +buildFromDirectory('./build'); +echo "Done.\n"; + +echo "Adding stub... "; +$phar->setStub($phar->createDefaultStub("loader.php")); +echo "Done.\n"; + +echo "Your PHAR file has been generated.\n"; diff --git a/vendor/gabordemooij/redbean/replica2.php b/vendor/gabordemooij/redbean/replica2.php new file mode 100644 index 000000000..bedd51fb9 --- /dev/null +++ b/vendor/gabordemooij/redbean/replica2.php @@ -0,0 +1,94 @@ +#!/usr/bin/env php + 0) { + echo 'Done!' ,PHP_EOL; +} else { + echo 'Hm, something seems to have gone wrong... ',PHP_EOL; +} diff --git a/vendor/gabordemooij/redbean/run_all_tests.sh b/vendor/gabordemooij/redbean/run_all_tests.sh new file mode 100755 index 000000000..242c8cf46 --- /dev/null +++ b/vendor/gabordemooij/redbean/run_all_tests.sh @@ -0,0 +1,6 @@ +#!/bin/sh +php replica2.php +cp rb.php testing/cli/testcontainer/rb.php +cd testing +cd cli +php runtests.php diff --git a/vendor/gabordemooij/redbean/run_single_test.sh b/vendor/gabordemooij/redbean/run_single_test.sh new file mode 100755 index 000000000..92015d4be --- /dev/null +++ b/vendor/gabordemooij/redbean/run_single_test.sh @@ -0,0 +1,11 @@ +#!/bin/sh +if [ -z "$1" ] +then + echo "Please enter the name of a test suite, example: Blackhole/Version" + exit +fi +php replica2.php +cp rb.php testing/cli/testcontainer/rb.php +cd testing +cd cli +php runtests.php $1 diff --git a/vendor/gabordemooij/redbean/test-dist.ini b/vendor/gabordemooij/redbean/test-dist.ini new file mode 100755 index 000000000..8de9b9bb2 --- /dev/null +++ b/vendor/gabordemooij/redbean/test-dist.ini @@ -0,0 +1,17 @@ +; Test suite database config +; Rename this file to test.ini if you are done + +[mysql] +host = "localhost" +schema = "oodb" +user = "root" +pass = "password" + +[pgsql] +host = "localhost" +schema = "oodb" +user = "postgres" +pass = "password" + +[sqlite] +file = "/tmp/database.db" diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT.php b/vendor/gabordemooij/redbean/testing/RedUNIT.php new file mode 100644 index 000000000..9f3f9a33b --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT.php @@ -0,0 +1,153 @@ +getMethods( \ReflectionMethod::IS_PUBLIC ) as $method ) { + // Skip methods inherited from parent class + if ( $method->class != $class->getName() ) continue; + if ( in_array( $method->name, $skip ) ) continue; + $classname = str_replace( $class->getParentClass()->getName().'_', '', $method->class ); + printtext( "\n\t" . $classname."->".$method->name." [".$method->class."->".$method->name."]" . " \n\t" ); + $call = $method->name; + $this->$call(); + try { + R::nuke(); + } catch( \PDOException $e ) { + // Some tests use a broken database on purpose, so an exception is ok + } + } + } + + /** + * Clean-up method, to be invoked after running the test. + * This is an empty implementation, it does nothing. However this method + * should be overridden by tests that require clean-up. + * + * @return void + */ + public function cleanUp() + { + } + + /** + * Sets the current driver. + * This method is called by a test controller, runner or manager + * to activate the mode associated with the specified driver + * identifier. This mechanism allows a test to run slightly different + * in the context of another driver, for instance SQLite might not need + * some tests, or MySQL might need some additional tests etc... + * + * @param string $driver the driver identifier + * + * @return void + */ + public function setCurrentDriver( $driver ) + { + $this->currentlyActiveDriverID = $driver; + } + + /** + * Sets the round number. + * Each test can have a varying number of flavors. + * A test flavor is 'that same test' but for a different driver. + * Each 'run on a specific driver' is called a round. + * Some tests might want to know what the current round is. + * This method can be used to set the current round number. + * + * @param integer $roundNumber round, the current round number + * + * @return void + */ + public function setRound( $roundNumber ) + { + $this->round = (int) $roundNumber; + } + + /** + * Returns the current round number. + * The current round number indicates how many times + * this test has been applied (to various drivers). + * + * @return integer + */ + public function getRound() + { + return $this->round; + } + + /** + * Detects whether the current round is the first one. + * If the current round is indeed the first round, this method + * will return boolean TRUE, otherwise it will return FALSE. Note that + * the rounds are 0-based, so - if the current round equals 0, this + * method will return TRUE. + * + * @return boolean + */ + public function isFirstRound() + { + return ( $this->round === 0 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base.php new file mode 100644 index 000000000..5750b009b --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base.php @@ -0,0 +1,55 @@ +name = 'teacher'; + $student->name = 'student'; + $project->teacher = $teacher; + $project->student = $student; + R::store( $project ); + $project = $project->fresh(); + asrt( ( $project->teacher instanceof OODBBean), TRUE ); + asrt( ( $project->student instanceof OODBBean), TRUE ); + asrt( $project->teacher->name, 'teacher' ); + asrt( $project->student->name, 'student' ); + $project2 = R::dispense( 'project' ); + $teacher2 = R::dispense( 'person' ); + $teacher2->name = 'teacher2'; + $project2->teacher = $teacher2; + R::store( $project2 ); + $project2 = $project2->fresh(); + asrt( ( $project2->teacher instanceof OODBBean), TRUE ); + asrt( $project2->teacher->name, 'teacher2' ); + asrt( is_null( $project2->student ), TRUE ); + $project = $project->fresh(); + asrt( ( $project->fetchAs('person')->teacher instanceof OODBBean), TRUE ); + asrt( ( $project->fetchAs('person')->student instanceof OODBBean), TRUE ); + asrt( $project->fetchAs('person')->teacher->name, 'teacher' ); + asrt( $project->fetchAs('person')->student->name, 'student' ); + $project = $project->fresh(); + $export = R::exportAll( array( $project ), TRUE ); + asrt( isset( $export[0]['teacher']['name'] ), TRUE ); + asrt( isset( $export[0]['student']['name'] ), TRUE ); + asrt( $export[0]['teacher']['name'], 'teacher' ); + asrt( $export[0]['student']['name'], 'student' ); + //Also test the default implementation... + $nullWriter = new \NullWriter( R::getDatabaseAdapter() ); + asrt( is_null( $nullWriter->inferFetchType( 'test', 'test' ) ), TRUE ); + //Realteacher should take precedence over fetchAs-teacher, name conventions first! + //also: ensure we do not use autoresolv for anything except when truly necessary! (performance) + $realTeacher = R::dispense( 'teacher' ); + $realTeacher->name = 'real'; + R::store( $realTeacher ); + //ID must be same + asrt( $realTeacher->id, $teacher->id ); + $project = $project->fresh(); + asrt( $project->teacher->name, 'real' ); + } + + /** + * Test for aliasing issue for LTS version. + * + * @return void + */ + public function testIssueAliasingForLTSVersion() { + $person = R::dispense('person'); + $pro = R::dispense('project'); + $c = R::dispense('course'); + $person->name = 'x'; + $person->alias('teacher')->ownProject[] = $pro; + $person->alias('student')->ownCourse[] = $c; + R::store($person); + asrt($c->fresh()->fetchAs('person')->student->name, 'x'); + asrt($pro->fresh()->fetchAs('person')->teacher->name, 'x'); + $person = $person->fresh(); + $person->alias('teacher')->ownProject = array(); + $person->alias('student')->ownCourse = array(); + R::store($person); + asrt($c->fresh()->fetchAs('person')->student, NULL); + asrt($pro->fresh()->fetchAs('person')->teacher, NULL); + } + + /** + * Describing how clearing state of bean works. + * Every method returning somthing (except getID) + * clears prefix-method-state (anything set by withCond,with,alias,fetchAs). + * + * @return void + */ + public function clearStateAdditionalTests() + { + list( $project1, $project2 ) = R::dispense( 'project', 2 ); + list( $irene, $ilse ) = R::dispense('person', 2); + $project1->developer = $ilse; + $project1->designer = $irene; + $ilse->name = 'Ilse'; + $irene->name = 'Irene'; + $project2->developer = $ilse; + R::storeAll( array( $project1, $project2 ) ); + $ilse = R::load( 'person', $ilse->id ); + asrt( count( $ilse->alias( 'developer' )->ownProject ), 2); + //cached - same list + asrt( count( $ilse->ownProject ), 2); + asrt( count( $ilse->alias( 'designer' )->ownProject ), 0); + //cached - same list + asrt( count( $ilse->ownProject ), 0); + //now test state + asrt( count( $ilse->setAttr( 'a', 'b' )->alias( 'developer' )->ownProject ), 2); + //now test state + $ilse = $ilse->fresh(); + //attr clears state... + asrt( count( $ilse->alias( 'developer' )->setAttr( 'a', 'b' )->ownProject ), 0); + //but getID() does not! + $ilse = $ilse->fresh(); + $ilse->alias('developer'); + $ilse->getID(); + asrt( count( $ilse->ownProject ), 2 ); + } + + /** + * Can switch fetchAs(). + * Also checks shadow by storing. + * + * @return void + */ + public function canSwitchParentBean() + { + list( $project1, $project2 ) = R::dispense( 'project', 2 ); + list( $irene, $ilse ) = R::dispense('person', 2); + $project1->developer = $ilse; + $project1->designer = $irene; + $ilse->name = 'Ilse'; + $irene->name = 'Irene'; + $project2->developer = $ilse; + R::storeAll( array( $project1, $project2 ) ); + $project1 = R::load( 'project', $project1->id ); + asrt( $project1->fetchAs('person')->developer->name, 'Ilse' ); + asrt( $project1->fetchAs('person')->designer->name, 'Irene' ); + R::store( $project1 ); + $project1 = R::load( 'project', $project1->id ); + asrt( $project1->fetchAs('person')->designer->name, 'Irene' ); + asrt( $project1->fetchAs('person')->developer->name, 'Ilse' ); + R::store( $project1 ); + asrt( $project1->fetchAs('person')->developer->name, 'Ilse' ); + asrt( $project1->fetchAs('person')->designer->name, 'Irene' ); + asrt( $project1->fetchAs('person')->developer->name, 'Ilse' ); + } + + /** + * Switching aliases (->alias) should not change other list during + * storage. + * + * @return void + */ + public function testShadow() + { + list( $project1, $project2 ) = R::dispense( 'project', 2 ); + list( $irene, $ilse ) = R::dispense('person', 2); + $project1->developer = $ilse; + $project1->designer = $irene; + $project2->developer = $ilse; + R::storeAll( array( $project1, $project2 ) ); + $ilse = R::load( 'person', $ilse->id ); + $irene = R::load( 'person', $irene->id ); + asrt( count( $ilse->alias('developer')->ownProject ), 2 ); + asrt( count( $ilse->alias('designer')->ownProject ), 0 ); + R::store( $ilse ); + $ilse = R::load( 'person', $ilse->id ); + $irene = R::load( 'person', $irene->id ); + asrt( count( $ilse->alias('designer')->ownProject ), 0 ); + asrt( count( $ilse->alias('developer')->ownProject ), 2 ); + R::storeAll( array( $ilse, $irene) ); + $ilse = R::load( 'person', $ilse->id ); + $irene = R::load( 'person', $irene->id ); + asrt( count( $ilse->alias('designer')->ownProject ), 0 ); + asrt( count( $ilse->alias('developer')->ownProject ), 2 ); + asrt( count( $irene->alias('designer')->ownProject), 1 ); + asrt( count( $irene->alias('developer')->ownProject), 0 ); + R::storeAll( array( $ilse, $irene) ); + $ilse = R::load( 'person', $ilse->id ); + $irene = R::load( 'person', $irene->id ); + asrt( count( $ilse->alias('designer')->ownProject ), 0 ); + asrt( count( $ilse->alias('developer')->ownProject ), 2 ); + asrt( count( $irene->alias('designer')->ownProject), 1 ); + asrt( count( $irene->alias('developer')->ownProject), 0 ); + } + + /** + * Issue 291. State not cleared. + * + * @return void + */ + public function testFetchTypeConfusionIssue291() + { + list( $teacher, $student ) = R::dispense( 'person', 2 ) ; + $teacher->name = 'jimmy' ; + $student->name = 'jacko' ; + R::store( $teacher ) ; + R::store( $student ) ; + $client = R::dispense( 'client' ) ; + $client->firm = 'bean AG' ; + R::store( $client ) ; + $project = R::dispense( 'project' ) ; + $project->teacher = $teacher ; + $project->student = $student ; + $project->client = $client ; + R::store( $project ) ; + unset( $project->student ) ; + R::store( $project ) ; + $project = R::load( 'project', 1 ) ; + $teacher = $project->fetchAs( 'person' )->teacher ; + $student = $project->fetchAs( 'person' )->student ; + $client = $project->client ; // this will select from "person" instead of "client" + asrt( $client->firm, 'bean AG' ); + } + + /** + * Test switching alias (also issue #291). + * + * @return void + */ + public function testAliasSwitch() + { + $student = R::dispense( 'person' ); + $project = R::dispense( 'project' ); + $project->student = $student; + R::store( $project ); + $person = R::load( 'person', $student->id ); + asrt( count( $person->alias( 'student' )->ownProject ), 1); + asrt( count( $person->alias( 'teacher' )->ownProject ), 0); + } + + /** + * Associating two beans, then loading the associated bean + * + * @return void + */ + public function testAssociated() + { + $person = R::dispense( 'person' ); + $person->name = 'John'; + R::store( $person ); + $course = R::dispense( 'course' ); + $course->name = 'Math'; + + R::store( $course ); + $course->teacher = $person; + $id = R::store( $course ); + $course = R::load( 'course', $id ); + $teacher = $course->fetchAs( 'person' )->teacher; + asrt( $teacher->name, 'John' ); + + //Trying to load a property that has an invalid name + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->wrongProperty = array( $page ); + try { + $book->wrongProperty[] = $page; + R::store( $book ); + fail(); + } catch ( RedException $e ) { + pass(); + } catch ( \Exception $e ) { + fail(); + } + } + + /** + * Test for quick detect change. + * + * @return void + */ + public function basic() + { + $book = R::dispense( 'book' ); + + asrt( isset( $book->prop ), FALSE ); //not a very good test + asrt( in_array( 'prop', array_keys( $book->export() ) ), FALSE ); //better... + + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + + $book->paper = $page; + + $id = R::store( $book ); + $book = R::load( 'book', $id ); + + asrt( FALSE, ( isset( $book->paper ) ) ); + asrt( FALSE, ( isset( $book->page ) ) ); + + /** + * The following tests try to store various things that aren't + * beans (which is expected) with the own* and shared* properties + * which only accept beans as assignments, so they're expected to fail + */ + foreach ( array( 'a string', 1928, TRUE, NULL, array()) as $value ) { + try { + $book->ownPage[] = $value; + R::store( $book ); + $book->sharedPage[] = $value; + R::store( $book ); + fail(); + } catch ( RedException $e ) { + pass(); + } catch ( \Exception $e ) { + fail(); + } + } + } + + /** + * Finding $person beans that have been aliased into various roles + * + * @return void + */ + public function testAliasedFinder() + { + $message = R::dispense( 'message' ); + $message->subject = 'Roommate agreement'; + list( $sender, $recipient ) = R::dispense( 'person', 2 ); + $sender->name = 'Sheldon'; + $recipient->name = 'Leonard'; + $message->sender = $sender; + $message->recipient = $recipient; + $id = R::store( $message ); + $message = R::load( 'message', $id ); + asrt( $message->fetchAs( 'person' )->sender->name, 'Sheldon' ); + asrt( $message->fetchAs( 'person' )->recipient->name, 'Leonard' ); + $otherRecipient = R::dispense( 'person' ); + $otherRecipient->name = 'Penny'; + $message->recipient = $otherRecipient; + R::store( $message ); + $message = R::load( 'message', $id ); + asrt( $message->fetchAs( 'person' )->sender->name, 'Sheldon' ); + asrt( $message->fetchAs( 'person' )->recipient->name, 'Penny' ); + } + + /** + * Test Basic Fetch AS functionality. + */ + public function testBasicFetchAs() + { + $project = R::dispense( 'project' ); + $project->name = 'Mutant Project'; + list( $teacher, $student ) = R::dispense( 'person', 2 ); + $teacher->name = 'Charles Xavier'; + $project->student = $student; + $project->student->name = 'Wolverine'; + $project->teacher = $teacher; + $id = R::store( $project ); + $project = R::load( 'project', $id ); + asrt( $project->fetchAs( 'person' )->teacher->name, 'Charles Xavier' ); + asrt( $project->fetchAs( 'person' )->student->name, 'Wolverine' ); + } + + /** + * Test Basic list variations. + * + * @return void + */ + public function testBasicListVariations() + { + $farm = R::dispense( 'building' ); + $village = R::dispense( 'village' ); + $farm->name = 'farm'; + $village->name = 'Dusty Mountains'; + $farm->village = $village; + $id = R::store( $farm ); + $farm = R::load( 'building', $id ); + asrt( $farm->name, 'farm' ); + asrt( $farm->village->name, 'Dusty Mountains' ); + $village = R::dispense( 'village' ); + list( $mill, $tavern ) = R::dispense( 'building', 2 ); + $mill->name = 'Mill'; + $tavern->name = 'Tavern'; + $village->ownBuilding = array( $mill, $tavern ); + $id = R::store( $village ); + $village = R::load( 'village', $id ); + asrt( count( $village->ownBuilding ), 2 ); + $village2 = R::dispense( 'village' ); + $army = R::dispense( 'army' ); + $village->sharedArmy[] = $army; + $village2->sharedArmy[] = $army; + $id1 = R::store( $village ); + $id2 = R::store( $village2 ); + $village1 = R::load( 'village', $id1 ); + $village2 = R::load( 'village', $id2 ); + asrt( count( $village1->sharedArmy ), 1 ); + asrt( count( $village2->sharedArmy ), 1 ); + asrt( count( $village1->ownArmy ), 0 ); + asrt( count( $village2->ownArmy ), 0 ); + } + + /** + * Tests whether aliasing plays nice with beautification. + * Ensure that aliased column aren't beautified + * + * @return void + */ + public function testAliasWithBeautify() + { + $points = R::dispense( 'point', 2 ); + $line = R::dispense( 'line' ); + $line->pointA = $points[0]; + $line->pointB = $points[1]; + R::store( $line ); + $line2 = R::dispense( 'line' ); + $line2->pointA = $line->fetchAs('point')->pointA; + $line2->pointB = R::dispense( 'point' ); + R::store( $line2 ); + + //now we have two points per line (1-to-x) + //I want to know which lines cross A: + $a = R::load( 'point', $line->pointA->id ); //reload A + $lines = $a->alias( 'pointA' )->ownLine; + asrt( count( $lines ), 2 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Arrays.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Arrays.php new file mode 100644 index 000000000..56303b19b --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Arrays.php @@ -0,0 +1,273 @@ +name = 'bean'; + $bean->taste = 'salty'; + $properties = array(); + foreach($bean as $key => $value) { + $properties[ $key ] = $value; + } + asrt( count( $bean ), 3 ); + asrt( count( $properties ), 3 ); + asrt( isset( $properties['id'] ), TRUE ); + asrt( isset( $properties['name'] ), TRUE ); + asrt( isset( $properties['taste'] ), TRUE ); + $bean = R::dispense('bean'); + $bean['name'] = 'bean'; + $bean['taste'] = 'salty'; + $properties = array(); + foreach($bean as $key => $value) { + $properties[ $key ] = $value; + } + asrt( count( $bean ), 3 ); + asrt( count( $properties ), 3 ); + asrt( isset( $properties['id'] ), TRUE ); + asrt( isset( $properties['name'] ), TRUE ); + asrt( isset( $properties['taste'] ), TRUE ); + } + + /** + * Tests array access with lists. + * Tests whether list properties behave as arrays correctly. + * + * @return void + */ + public function testArrayAccessAndLists() + { + $book = R::dispense('book'); + $book['title'] = 'My Book'; + //Can we add a bean in list with array access? + $book['ownPage'][] = R::dispense('page'); + $book['ownPage'][] = R::dispense('page'); + asrt( count( $book ), 3 ); + $properties = array(); + foreach($book as $key => $value) { + $properties[ $key ] = $value; + } + asrt( count( $properties ), 3 ); + //Dont reveal aliased x-own and -List in foreach-loop + asrt( isset( $properties['id'] ), TRUE ); + asrt( isset( $properties['title'] ), TRUE ); + asrt( isset( $properties['ownPage'] ), TRUE ); + asrt( isset( $properties['ownPageList'] ), FALSE ); + asrt( isset( $properties['xownPage'] ), FALSE ); + asrt( isset( $properties['xownPageList'] ), FALSE ); + //But keep them countable + asrt( count( $book['ownPage'] ), 2 ); + asrt( count( $book['ownPageList'] ), 2 ); + asrt( count( $book['xownPage'] ), 2 ); + asrt( count( $book['xownPageList'] ), 2 ); + //And reveal state of items with isset() + asrt( isset( $book['id'] ), TRUE ); + asrt( isset( $book['title'] ), TRUE ); + asrt( isset( $book['ownPage'] ), TRUE ); + asrt( isset( $book['ownPageList'] ), TRUE ); + asrt( isset( $book['xownPage'] ), TRUE ); + asrt( isset( $book['xownPageList'] ), TRUE ); + //Can we add using the List alias? + $book['ownPageList'][] = R::dispense('page'); + asrt( count( $book['ownPage'] ), 3 ); + asrt( count( $book['ownPageList'] ), 3 ); + asrt( count( $book['xownPage'] ), 3 ); + asrt( count( $book['xownPageList'] ), 3 ); + //Can we add using the x-mode alias? + $book['ownPageList'][] = R::dispense('page'); + asrt( count( $book['ownPage'] ), 4 ); + asrt( count( $book['ownPageList'] ), 4 ); + asrt( count( $book['xownPage'] ), 4 ); + asrt( count( $book['xownPageList'] ), 4 ); + //Can we unset using array access? + unset( $book['ownPage'] ); + asrt( isset( $book['ownPage'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + $book['ownPage'] = array( R::dispense('page') ); + unset( $book['xownPage'] ); + asrt( isset( $book['ownPage'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + $book['ownPage'] = array( R::dispense('page') ); + unset( $book['ownPageList'] ); + asrt( isset( $book['ownPage'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + $book['ownPage'] = array( R::dispense('page') ); + unset( $book['xownPageList'] ); + asrt( isset( $book['ownPage'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + //does it work with shared lists as well? + $book['sharedCategory'] = array( R::dispense('category') ); + asrt( count( $book ), 3 ); + $properties = array(); + foreach($book as $key => $value) { + $properties[ $key ] = $value; + } + asrt( isset( $properties['sharedCategory'] ), TRUE ); + asrt( isset( $properties['sharedCategoryList'] ), FALSE ); + asrt( isset( $book['sharedCategory'] ), TRUE ); + asrt( isset( $book['sharedCategoryList'] ), TRUE ); + asrt( count( $book['sharedCategory'] ), 1 ); + asrt( count( $book['sharedCategoryList'] ), 1 ); + $book['sharedCategory'][] = R::dispense( 'category' ); + asrt( count( $book['sharedCategory'] ), 2 ); + asrt( count( $book['sharedCategoryList'] ), 2 ); + $book['sharedCategoryList'][] = R::dispense( 'category' ); + asrt( count( $book['sharedCategory'] ), 3 ); + asrt( count( $book['sharedCategoryList'] ), 3 ); + } + + /** + * Tests array access with parent beans. + * + * @return void + */ + public function testArrayAccessWithBeans() + { + $book = R::dispense( 'bean' ); + $book['author'] = R::dispense( 'author' ); + asrt( isset( $book['author'] ), TRUE ); + asrt( count( $book ), 2 ); + $book['author']['name'] = 'me'; + asrt( $book['author']['name'], 'me' ); + $book['author']['address'] = R::dispense( 'address' ); + $book['author']['ownTagList'][] = R::dispense( 'tag' ); + asrt( isset( $book['author']['address'] ), TRUE ); + asrt( isset( $book['author']['ownTag'] ), TRUE ); + asrt( count( $book['author']['ownTag'] ), 1 ); + asrt( isset( $book['author']['xownTag'] ), TRUE ); + asrt( count( $book['author']['xownTag'] ), 1 ); + asrt( isset( $book['author']['ownTagList'] ), TRUE ); + asrt( count( $book['author']['ownTagList'] ), 1 ); + asrt( isset( $book['author']['xownTagList'] ), TRUE ); + asrt( count( $book['author']['xownTagList'] ), 1 ); + unset( $book['author'] ); + asrt( isset( $book['author'] ), FALSE ); + asrt( count( $book ), 1 ); + } + + /** + * Tests array access with CRUD operations. + * + * @return void + */ + public function testArrayAccessWithCRUD() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book['ownPageList'] = R::dispense( 'page', 3 ); + R::store( $book ); + $book = $book->fresh(); + //note that isset first returns false, so you can check if a list is loaded + asrt( isset( $book['ownPage'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + //count triggers load... + asrt( count( $book['ownPage'] ), 3 ); + asrt( isset( $book['ownPage'] ), TRUE ); + asrt( isset( $book['ownPageList'] ), TRUE ); + asrt( isset( $book['xownPage'] ), TRUE ); + asrt( isset( $book['xownPageList'] ), TRUE ); + $book = $book->fresh(); + asrt( count( $book['xownPage'] ), 3 ); + $book = $book->fresh(); + asrt( count( $book['ownPageList'] ), 3 ); + $book = $book->fresh(); + asrt( count( $book['xownPageList'] ), 3 ); + $book['ownPage'][] = R::dispense( 'page' ); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book['ownPage'] ), 4 ); + $book = $book->fresh(); + asrt( count( $book['xownPage'] ), 4 ); + $book = $book->fresh(); + asrt( count( $book['ownPageList'] ), 4 ); + $book = $book->fresh(); + asrt( count( $book['xownPageList'] ), 4 ); + //does dependency still work? + $book['xownPageList'] = array(); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book['ownPage'] ), 0 ); + $book = $book->fresh(); + asrt( count( $book['xownPage'] ), 0 ); + $book = $book->fresh(); + asrt( count( $book['ownPageList'] ), 0 ); + $book = $book->fresh(); + asrt( count( $book['xownPageList'] ), 0 ); + //does shared list work as well? + $book['sharedTag'] = R::dispense( 'tag', 2 ); + R::store( $book ); + $book = $book->fresh(); + //note that isset first returns false, so you can check if a list is loaded + asrt( isset( $book['sharedTagList'] ), FALSE ); + asrt( isset( $book['sharedTag'] ), FALSE ); + //count triggers load... + asrt( count( $book['sharedTagList'] ), 2 ); + asrt( count( $book['sharedTag'] ), 2 ); + asrt( isset( $book['sharedTagList'] ), TRUE ); + asrt( isset( $book['sharedTag'] ), TRUE ); + $book['sharedTag'][] = R::dispense( 'tag' ); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book['sharedTagList'] ), 3 ); + asrt( count( $book['sharedTag'] ), 3 ); + $book['sharedTagList'][] = R::dispense( 'tag' ); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book['sharedTagList'] ), 4 ); + asrt( count( $book['sharedTag'] ), 4 ); + //does it also work with cross-shared + $book['sharedBookList'][] = R::dispense( 'book' ); + R::store( $book ); + $book = $book->fresh(); + asrt( isset( $book['sharedBookList'] ), FALSE ); + asrt( count( $book['sharedBookList'] ), 1 ); + $first = reset( $book['sharedBookList'] ); + $id = $first['id']; + asrt( count( $book['sharedBookList'][$id]['sharedBookList'] ), 1 ); + $properties = array(); + foreach($book as $key => $value) { + $properties[ $key ] = $value; + } + asrt( count( $properties ), 2 ); + $keys = array_keys( $properties ); + sort( $keys ); + asrt( implode( ',', $keys ), 'id,sharedBook' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Association.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Association.php new file mode 100644 index 000000000..568074740 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Association.php @@ -0,0 +1,293 @@ +currentlyActiveDriverID !== 'mysql' ) { + return; + } + testpack( 'Throw exception in case of issue with assoc constraint' ); + $bunny = R::dispense( 'bunny' ); + $carrot = R::dispense( 'carrot' ); + $faultyWriter = new \FaultyWriter( R::getToolBox()->getDatabaseAdapter() ); + $faultyOODB = new OODB( $faultyWriter ); + $faultyOODB->setBeanHelper( R::getRedBean()->getBeanHelper() ); + $faultyToolbox = new ToolBox( $faultyOODB, R::getToolBox()->getDatabaseAdapter(), $faultyWriter ); + $faultyAssociationManager = new AssociationManager( $faultyToolbox ); + $faultyWriter->setSQLState( '23000' ); + $faultyAssociationManager->associate( $bunny, $carrot ); + pass(); + $faultyWriter->setSQLState( '42S22' ); + R::nuke(); + try { + $faultyAssociationManager->associate( $bunny, $carrot ); + fail(); + } catch ( SQL $exception ) { + pass(); + } + } + + /** + * Test fast-track deletion, i.e. bypassing FUSE. + * For link beans. + * + * @return void + */ + public function testFastTrackDeletion() + { + testpack( 'Test fast-track deletion' ); + $ghost = R::dispense( 'ghost' ); + $house = R::dispense( 'house' ); + $house->sharedGhost[] = $ghost; + \Model_Ghost_House::$deleted = FALSE; + R::getRedBean()->getAssociationManager()->unassociate( $house, $ghost ); + // No fast-track, assoc bean got trashed + asrt( \Model_Ghost_House::$deleted, TRUE ); + \Model_Ghost_House::$deleted = FALSE; + R::getRedBean()->getAssociationManager()->unassociate( $house, $ghost, TRUE ); + // Fast-track, assoc bean got deleted right away + asrt( \Model_Ghost_House::$deleted, FALSE ); + } + + /** + * Test self-referential associations. + * + * @return void + */ + public function testCrossAssociation() + { + $ghost = R::dispense( 'ghost' ); + $ghost2 = R::dispense( 'ghost' ); + R::getRedBean()->getAssociationManager()->associate( $ghost, $ghost2 ); + \Model_Ghost_Ghost::$deleted = FALSE; + R::getRedBean()->getAssociationManager()->unassociate( $ghost, $ghost2 ); + // No fast-track, assoc bean got trashed + asrt( \Model_Ghost_Ghost::$deleted, TRUE ); + \Model_Ghost_Ghost::$deleted = FALSE; + R::getRedBean()->getAssociationManager()->unassociate( $ghost, $ghost2, TRUE ); + // Fast-track, assoc bean got deleted right away + asrt( \Model_Ghost_Ghost::$deleted, FALSE ); + } + + /** + * Test limited support for polymorph associations. + * RedBeanPHP does not really feature polymorph relations since + * they are not really compatible with traditional relational databases. + * However a light-weight, basic implementation has been added for + * those circumstances where you can't live without... + * i.e... possible legacy systems and so on. + * + * @return void + */ + public function testPoly() + { + testpack( 'Testing poly' ); + $shoe = R::dispense( 'shoe' ); + $lace = R::dispense( 'lace' ); + $lace->color = 'white'; + $id = R::store( $lace ); + $shoe->itemType = 'lace'; + $shoe->item = $lace; + $id = R::store( $shoe ); + $shoe = R::load( 'shoe', $id ); + $x = $shoe->poly( 'itemType' )->item; + asrt( $x->color, 'white' ); + } + + /** + * Test limited support for 1-to-1 associations. + * The rule is, one-to-ones are supposes to be in the same table, + * this is just for some legacy tables not designed to work + * with RedBeanPHP at all. + * + * @return void + */ + public function testOneToOne() + { + testpack( 'Testing one-to-ones' ); + $author = R::dispense( 'author' )->setAttr( 'name', 'a' );; + $bio = R::dispense( 'bio' )->setAttr( 'name', 'a' ); + R::storeAll( array( $author, $bio ) ); + $id1 = $author->id; + $author = R::dispense( 'author' )->setAttr( 'name', 'b' );; + $bio = R::dispense( 'bio' )->setAttr( 'name', 'b' ); + R::storeAll( array( $author, $bio ) ); + $x = $author->one( 'bio' ); + $y = $bio->one('author'); + asrt( $x->name, $bio->name ); + asrt( $y->name, $author->name ); + asrt( $x->id, $bio->id ); + asrt( $y->id, $author->id ); + $id2 = $author->id; + list( $a, $b ) = R::loadMulti( 'author,bio', $id1 ); + asrt( $a->name, $b->name ); + asrt( $a->name, 'a' ); + list( $a, $b ) = R::loadMulti( 'author,bio', $id2 ); + asrt( $a->name, $b->name ); + asrt( $a->name, 'b' ); + list( $a, $b ) = R::loadMulti( array( 'author', 'bio' ), $id1 ); + asrt( $a->name, $b->name ); + asrt( $a->name, 'a' ); + list( $a, $b ) = R::loadMulti( array( 'author', 'bio' ), $id2 ); + asrt( $a->name, $b->name ); + asrt( $a->name, 'b' ); + asrt( is_array( R::loadMulti( NULL, 1 ) ), TRUE ); + asrt( ( count( R::loadMulti( NULL, 1 ) ) === 0 ), TRUE ); + } + + /** + * Test single column bases unique constraints. + * + * @return void + */ + public function testSingleColUniqueConstraint() + { + testpack( 'Testing unique constraint on single column' ); + $book = R::dispense( 'book' ); + $book->title = 'bla'; + $book->extra = 2; + $id = R::store( $book ); + R::getWriter()->addUniqueIndex( 'book', array( 'title' ) ); + $book = R::dispense( 'book' ); + $book->title = 'bla'; + $expected = NULL; + try { + R::store( $book ); + + fail(); + } catch ( SQL $e ) { + $expected = $e; + } + asrt( ( $expected instanceof SQL ), TRUE ); + asrt( R::count( 'book' ), 1 ); + $book = R::load( 'book', $id ); + // Causes failure, table will be rebuild + $book->extra = 'CHANGE'; + $id2 = R::store( $book ); + $book2 = R::load( 'book', $id2 ); + $book = R::dispense( 'book' ); + $book->title = 'bla'; + try { + R::store( $book ); + + fail(); + } catch ( SQL $e ) { + $expected = $e; + } + asrt( ( $expected instanceof SQL ), TRUE ); + asrt( R::count( 'book' ), 1 ); + } + + /** + * Test multiple assiociation. + * + * @return void + */ + public function testMultiAssociationDissociation() + { + $wines = R::dispense( 'wine', 3 ); + $cheese = R::dispense( 'cheese', 3 ); + $olives = R::dispense( 'olive', 3 ); + R::getRedBean()->getAssociationManager()->associate( $wines, array_merge( $cheese, $olives ) ); + asrt( R::count( 'cheese' ), 3 ); + asrt( R::count( 'olive' ), 3 ); + asrt( R::count( 'wine' ), 3 ); + asrt( count( $wines[0]->sharedCheese ), 3 ); + asrt( count( $wines[0]->sharedOlive ), 3 ); + asrt( count( $wines[1]->sharedCheese ), 3 ); + asrt( count( $wines[1]->sharedOlive ), 3 ); + asrt( count( $wines[2]->sharedCheese ), 3 ); + asrt( count( $wines[2]->sharedOlive ), 3 ); + R::getRedBean()->getAssociationManager()->unassociate( $wines, $olives ); + asrt( count( $wines[0]->sharedCheese ), 3 ); + asrt( count( $wines[0]->sharedOlive ), 0 ); + asrt( count( $wines[1]->sharedCheese ), 3 ); + asrt( count( $wines[1]->sharedOlive ), 0 ); + asrt( count( $wines[2]->sharedCheese ), 3 ); + asrt( count( $wines[2]->sharedOlive ), 0 ); + R::getRedBean()->getAssociationManager()->unassociate( array( $wines[1] ), $cheese ); + asrt( count( $wines[0]->sharedCheese ), 3 ); + asrt( count( $wines[0]->sharedOlive ), 0 ); + asrt( count( $wines[1]->sharedCheese ), 0 ); + asrt( count( $wines[1]->sharedOlive ), 0 ); + asrt( count( $wines[2]->sharedCheese ), 3 ); + asrt( count( $wines[2]->sharedOlive ), 0 ); + R::getRedBean()->getAssociationManager()->unassociate( array( $wines[2] ), $cheese ); + asrt( count( $wines[0]->sharedCheese ), 3 ); + asrt( count( $wines[0]->sharedOlive ), 0 ); + asrt( count( $wines[1]->sharedCheese ), 0 ); + asrt( count( $wines[1]->sharedOlive ), 0 ); + asrt( count( $wines[2]->sharedCheese ), 0 ); + asrt( count( $wines[2]->sharedOlive ), 0 ); + } + + /** + * Tests error handling related to association. + * On database systems providing informative SQL STATE error codes + * RedBeanPHP should not mind non-existing tables or columns in + * fluid mode. + * + * @return void + */ + public function testErrorHandling() + { + R::nuke(); + list( $book, $page ) = R::dispenseAll( 'book,page' ); + $book->sharedPage[] = $page; + R::store( $page ); + $redbean = R::getRedBean(); + $am = $redbean->getAssociationManager(); + //SQLite and CUBRID do not comply with ANSI SQLState codes. + $catchAll = ( $this->currentlyActiveDriverID == 'sqlite' || $this->currentlyActiveDriverID === 'CUBRID' ); + try { + $am->related( $book, 'page', 'invalid SQL' ); + if ($catchAll) pass(); else fail(); + } catch ( SQL $e ) { + if ($catchAll) fail(); else pass(); + } + try { + $am->related( $book, 'cover'); + pass(); + } catch ( SQL $e ) { + fail(); + } + try { + $am->related( R::dispense('cover'), 'book' ); + pass(); + } catch ( SQL $e ) { + fail(); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Batch.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Batch.php new file mode 100644 index 000000000..0df0e45d4 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Batch.php @@ -0,0 +1,143 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + + $page = $redbean->dispense( "page" ); + + $page->name = "page no. 1"; + $page->rating = 1; + + $id1 = $redbean->store( $page ); + + $page = $redbean->dispense( "page" ); + + $page->name = "page no. 2"; + + $id2 = $redbean->store( $page ); + + $batch = $redbean->batch( "page", array( $id1, $id2 ) ); + + asrt( count( $batch ), 2 ); + asrt( $batch[$id1]->getMeta( "type" ), "page" ); + asrt( $batch[$id2]->getMeta( "type" ), "page" ); + asrt( (int) $batch[$id1]->id, $id1 ); + asrt( (int) $batch[$id2]->id, $id2 ); + + $book = $redbean->dispense( "book" ); + + $book->name = "book 1"; + + $redbean->store( $book ); + + $book = $redbean->dispense( "book" ); + + $book->name = "book 2"; + + $redbean->store( $book ); + + $book = $redbean->dispense( "book" ); + + $book->name = "book 3"; + + $redbean->store( $book ); + + $books = $redbean->batch( "book", $adapter->getCol( "SELECT id FROM book" ) ); + + asrt( count( $books ), 3 ); + + $a = $redbean->batch( 'book', 9919 ); + + asrt( is_array( $a ), TRUE ); + asrt( count( $a ), 0 ); + $a = $redbean->batch( 'triangle', 1 ); + + asrt( is_array( $a ), TRUE ); + asrt( count( $a ), 0 ); + + R::freeze( TRUE ); + + $a = $redbean->batch( 'book', 9919 ); + + asrt( is_array( $a ), TRUE ); + asrt( count( $a ), 0 ); + try { + $a = $redbean->batch( 'triangle', 1 ); + fail(); + } catch(SQL $e) { + pass(); + } + R::freeze( FALSE ); + asrt( R::wipe( 'spaghettimonster' ), FALSE ); + } + + /** + * Test missing bean scenarios. + * + * @return void + */ + public function testMissingBeans() + { + testpack( 'deal with missing beans' ); + + $id = R::store( R::dispense( 'beer' ) ); + $bottles = R::batch( 'beer', array( $id, $id + 1, $id + 2 ) ); + + asrt( count( $bottles ), 3 ); + asrt( (int) $bottles[$id]->id, (int) $id ); + asrt( (int) $bottles[$id + 1]->id, 0 ); + asrt( (int) $bottles[$id + 2]->id, 0 ); + } + + /** + * Test batch alias loadAll. + * + * @return void + */ + public function testBatchAliasLoadAll() + { + $ids = R::storeAll( R::dispense( 'page', 2 ) ); + $pages = R::loadAll( 'page', $ids ); + asrt( is_array( $pages ), true ); + asrt( count( $pages ), 2 ); + asrt( ( $pages[$ids[0]] instanceof OODBBean ), true ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Bean.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Bean.php new file mode 100644 index 000000000..4ee3017b0 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Bean.php @@ -0,0 +1,1112 @@ + 'book', + 'title' => 'Bean Recipes', + 'author' => 'Meastro de la Bean' + ) ); + $pages = R::dispenseAll( 'page*2' ); + $book->ownPageList = reset( $pages ); + R::store( $book ); + $data = R::getRow('SELECT book.*, + COUNT(page.id) AS meta_count, + 1234 AS meta_extra + FROM book + LEFT JOIN page ON page.book_id = book.id + GROUP BY book.id + '); + $bean = R::convertToBean( 'book', $data, 'meta_' ); + asrt( isset( $bean->title ), TRUE ); + asrt( isset( $bean->author ), TRUE ); + asrt( isset( $bean->meta_count ), FALSE ); + asrt( isset( $bean->meta_extra ), FALSE ); + $data = $bean->getMeta( 'data.bundle' ); + asrt( intval( $data['meta_count'] ), 2); + asrt( intval( $data['meta_extra'] ), 1234); + //now with multiple beans + $book = R::dispense( array( + '_type' => 'book', + 'title' => 'Bean Adventures', + 'author' => 'Mr Adventure' + ) ); + $pages = R::dispenseAll( 'page*3' ); + $book->ownPageList = reset( $pages ); + R::store( $book ); + $data = R::getAll('SELECT book.*, + COUNT(page.id) AS meta_pages + FROM book + LEFT JOIN page ON page.book_id = book.id + GROUP BY book.id + '); + $books = R::convertToBeans( 'book', $data, 'meta_' ); + $found = 0; + foreach( $books as $book ) { + if ( $book->title == 'Bean Recipes' ) { + $found++; + asrt( isset( $book->title ), TRUE ); + asrt( isset( $book->author ), TRUE ); + asrt( isset( $book->meta_count ), FALSE ); + asrt( isset( $book->meta_extra ), FALSE ); + $data = $book->getMeta( 'data.bundle' ); + asrt( intval( $data['meta_pages'] ), 2); + } + if ( $book->title == 'Bean Adventures' ) { + $found++; + asrt( isset( $book->title ), TRUE ); + asrt( isset( $book->author ), TRUE ); + asrt( isset( $book->meta_pages ), FALSE ); + asrt( isset( $book->meta_extra ), FALSE ); + $data = $book->getMeta( 'data.bundle' ); + asrt( intval( $data['meta_pages'] ), 3); + } + } + asrt( $found, 2 ); + } + + /** + * Test beautification conflicts... + * Issue #418 + * + * @return void + */ + public function testBeau() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book->ownerId = 2; + $book->ownerCritic = 'a'; + $book->sharedbyReader = 'b'; + $id = R::store( $book ); + $columns = R::inspect( 'book' ); + asrt( isset( $columns['owner_id'] ), TRUE ); + asrt( isset( $columns['owner_critic'] ), TRUE ); + asrt( isset( $columns['sharedby_reader'] ), TRUE ); + asrt( isset( $columns['ownerId'] ), FALSE ); + asrt( isset( $columns['ownerCritic'] ), FALSE ); + asrt( isset( $columns['sharedbyReader'] ), FALSE ); + R::nuke(); + $book = R::dispense( 'book' ); + $book->xownerId = 2; + $book->xownerCritic = 'a'; + $book->sharedbyReader = 'b'; + $id = R::store( $book ); + $columns = R::inspect( 'book' ); + asrt( isset( $columns['xowner_id'] ), TRUE ); + asrt( isset( $columns['xowner_critic'] ), TRUE ); + asrt( isset( $columns['sharedby_reader'] ), TRUE ); + asrt( isset( $columns['xownerId'] ), FALSE ); + asrt( isset( $columns['xownerCritic'] ), FALSE ); + asrt( isset( $columns['sharedbyReader'] ), FALSE ); + } + + /** + * Other tests... + */ + public function testMisc() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book->ownPage[] = R::dispense( 'page' ); + R::store( $book ); + R::nuke(); + R::store( $book ); + asrt( R::count( 'book' ), 0 ); + $book->ownPage; + R::store( $book ); + asrt( R::count( 'book' ), 0 ); + $book->title = 'x'; + R::store( $book ); + asrt( R::count( 'book' ), 0 ); + } + + /** + * Only fire update query if the bean really contains different + * values. But make sure beans several 'parents' away still get + * saved. + * + * @return void + */ + public function testBeanTainting() + { + $logger = R::getDatabaseAdapter()->getDatabase()->getLogger(); + list( $i, $k, $c, $s ) = R::dispenseAll( 'invoice,customer,city,state' ); + $i->customer = $k; + $i->status = 0; + $k->city = $c; + $c->state = $s; + $s->name = 'x'; + R::store( $i ); + $i = $i->fresh(); + asrt( $i->customer->city->state->name, 'x' ); + $i->status = 1; + R::freeze( true ); + $logger = R::debug( 1, 1 ); + //do we properly skip unmodified but tainted parent beans? + R::store( $i ); + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 1 ); + //does cascade update still work? + $i = $i->fresh(); + $i->customer->city->state->name = 'y'; + R::store( $i ); + $i = $i->fresh(); + asrt( $i->customer->city->state->name, 'y' ); + $i = $i->fresh(); + $differentCity = R::dispense( 'city' ); + R::store( $differentCity ); + $i->customer->city = $differentCity; + R::store( $i ); + $i = $i->fresh(); + asrt( ( $i->customer->city->id != $c->id ), TRUE ); + asrt( is_null( $i->customer->city->state ), TRUE ); + $i->customer->city = NULL; + R::store( $i ); + $i = $i->fresh(); + asrt( is_null( $i->customer->city ), TRUE ); + $i->customer = $k; + $i->status = 0; + $k->city = $c; + $c->state = $s; + $s->name = 'x'; + R::store( $i ); + R::freeze( FALSE ); + $i = $i->fresh(); + //can we still change remote parent? + $i->customer->city->name = 'q'; + $logger->clear(); + R::store($i); + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + //print_r($logger->getLogs()); + asrt( count( $numberOfUpdateQueries ), 1 ); + $i = $i->fresh(); + asrt( $i->customer->city->name, 'q' ); + //do we properly skip unmodified but tainted parent beans? + $i->status = 3; + $logger->clear(); + R::store( $i ); + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 1 ); + } + + /** + * Test whether the number of update queries + * executed is limited to the ones that are absolutely + * necessary to sync the database. + * + * @return void + */ + public function testUpdateQueries() + { + $book = R::dispense( 'book' ); + $book->title = 'Eye of Wight'; + $book->xownPageList = R::dispense( 'page', 10 ); + $book->sharedCategoryList = R::dispense( 'category', 2 ); + $n = 1; + foreach( $book->xownPageList as $page ) { + $page->number = $n++; + } + $book->sharedCategory[0]->name = 'adventure'; + $book->sharedCategory[1]->name = 'puzzle'; + $book->author = R::dispense( 'author' ); + $book->author->name = 'John'; + $book->map = R::dispense( 'map' ); + $book->map->name = 'Wight'; + $book->map->xownLocationList = R::dispense( 'location', 3 ); + asrt( $book->getMeta('tainted'), TRUE ); + asrt( $book->getMeta('changed'), TRUE ); + R::store( $book ); + asrt( $book->getMeta('tainted'), FALSE ); + asrt( $book->getMeta('changed'), FALSE ); + $logger = R::debug( 1, 1 ); + $book = $book->fresh(); + asrt( $book->getMeta('tainted'), FALSE ); + asrt( $book->getMeta('changed'), FALSE ); + $book->author; + asrt( $book->getMeta('tainted'), TRUE ); + asrt( $book->getMeta('changed'), FALSE ); + $logger->clear(); + R::store( $book ); + //read only, no updates + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 0 ); + $book->title = 'Spirit of the Stones'; + R::store( $book ); + //changed title, 1 update + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 1 ); + $logger->clear(); + //store again, no changes, no updates + R::store( $book ); + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 0 ); + $logger->clear(); + $book = $book->fresh(); + $book->xownPageList; + asrt( $book->getMeta('tainted'), TRUE ); + asrt( $book->getMeta('changed'), FALSE ); + R::store( $book ); + //access only, no update + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 0 ); + $logger->clear(); + $book = $book->fresh(); + $book->sharedCategoryList; + asrt( $book->getMeta('tainted'), TRUE ); + asrt( $book->getMeta('changed'), FALSE ); + R::store( $book ); + //access only, no update + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 0 ); + $logger->clear(); + $book = $book->fresh(); + unset($book->xownPageList[5]); + asrt( $book->getMeta('tainted'), TRUE ); + asrt( $book->getMeta('changed'), FALSE ); + R::store( $book ); + //remove only, no update, just 1 delete + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 0 ); + $numberOfUpdateQueries = $logger->grep( 'DELETE' ); + asrt( count( $numberOfUpdateQueries ), 1 ); + $book = $book->fresh(); + asrt( count( $book->xownPageList ), 9 ); + $logger->clear(); + $book = $book->fresh(); + $book->xownPageList[] = R::dispense('page'); + asrt( $book->getMeta('tainted'), TRUE ); + asrt( $book->getMeta('changed'), FALSE ); + R::store( $book ); + //no update, 1 insert, just adding + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 0 ); + $numberOfUpdateQueries = $logger->grep( 'INSERT' ); + asrt( count( $numberOfUpdateQueries ), 1 ); + $book = $book->fresh(); + asrt( count( $book->xownPageList ), 10 ); + $logger->clear(); + $book = $book->fresh(); + $book->map->xownLocationList[1]->name = 'Horshoe Bay'; + asrt( $book->getMeta('tainted'), TRUE ); + asrt( $book->getMeta('changed'), FALSE ); + asrt( $book->map->getMeta('tainted'), TRUE ); + asrt( $book->map->getMeta('changed'), FALSE ); + asrt( $book->map->xownLocationList[1]->getMeta('tainted'), TRUE ); + asrt( $book->map->xownLocationList[1]->getMeta('changed'), TRUE ); + R::store( $book ); + //1 update for child of parent, no other updates + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 1 ); + $book = $book->fresh(); + asrt( $book->map->xownLocationList[1]->name, 'Horshoe Bay' ); + $logger->clear(); + R::store( $book ); + //just access, no updates + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 0 ); + $logger->clear(); + $book = $book->fresh(); + $book->ownPageList[2]->number = 99; + R::store( $book ); + //1 update, do not update rest of pages or book itself + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 1 ); + $book = $book->fresh(); + $book->author->name = 'Worsley'; + $logger->clear(); + R::store( $book ); + //1 update for parent + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 1 ); + $author = R::dispense('author'); + $author->name = 'J.W.'; + R::store( $author ); + $book = $book->fresh(); + $book->author = $author; + $author->name = 'JW'; + $logger->clear(); + R::store( $book ); + //2 updates, one for author, one for link field: author_id needs update. + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 2 ); + $author->country = R::dispense( 'country' )->setAttr( 'name', 'England' ); + R::store( $author ); + $book = $book->fresh(); + $book->author->country->name = 'Wight'; + $logger->clear(); + R::store( $book ); + //1 update, country only, dont update for intermediate parents: book -> author -> ... + $numberOfUpdateQueries = $logger->grep( 'UPDATE' ); + asrt( count( $numberOfUpdateQueries ), 1 ); + } + + /** + * Tests effects of importFrom and setProperty. + * + * @return void + */ + public function testImportFromAndSetProp() + { + $bean = R::dispense( 'bean' ); + asrt( $bean->getMeta( 'tainted' ), TRUE ); + asrt( $bean->getMeta( 'changed' ), TRUE ); + $bean->setMeta( 'tainted', FALSE ); + $bean->setMeta( 'changed', FALSE ); + asrt( $bean->getMeta( 'tainted' ), FALSE ); + asrt( $bean->getMeta( 'changed' ), FALSE ); + $bean->importFrom( R::dispense( 'bean' ) ); + asrt( $bean->getMeta( 'tainted' ), TRUE ); + asrt( $bean->getMeta( 'changed' ), TRUE ); + $bean->setMeta( 'tainted', FALSE ); + $bean->setMeta( 'changed', FALSE ); + asrt( $bean->getMeta( 'tainted' ), FALSE ); + asrt( $bean->getMeta( 'changed' ), FALSE ); + $bean->setProperty( 'id', 0, TRUE, TRUE ); + asrt( $bean->getMeta( 'tainted' ), TRUE ); + asrt( $bean->getMeta( 'changed' ), TRUE ); + $bean->setMeta( 'tainted', FALSE ); + $bean->setMeta( 'changed', FALSE ); + asrt( $bean->getMeta( 'tainted' ), FALSE ); + asrt( $bean->getMeta( 'changed' ), FALSE ); + $bean->setProperty( 'id', 0, TRUE, FALSE ); + asrt( $bean->getMeta( 'tainted' ), FALSE ); + asrt( $bean->getMeta( 'changed' ), FALSE ); + $bean->name = 'x'; + asrt( $bean->getMeta( 'tainted' ), TRUE ); + asrt( $bean->getMeta( 'changed' ), TRUE ); + } + + /** + * Setup + * + * @return void + */ + private function _createBook() + { + R::nuke(); + $book = R::dispense( 'book' ); + $pages = R::dispense( 'page', 2 ); + $ads = R::dispense('ad', 3 ); + $tags = R::dispense( 'tag', 2 ); + $author = R::dispense( 'author' ); + $coauthor = R::dispense( 'author' ); + $book->alias( 'magazine' )->ownAd = $ads; + $book->ownPage = $pages; + $book->sharedTag = $tags; + $book->via( 'connection' )->sharedUser = array( R::dispense( 'user' ) ); + $book->author = $author; + $book->coauthor = $coauthor; + R::store( $book ); + return $book->fresh(); + } + + /* + * Can we add a bean to a list? + * + * @return void + */ + public function testWhetherWeCanAddToLists() + { + $book = $this->_createBook(); + $book->ownPage[] = R::dispense( 'page' ); + R::store( $book ); + asrt( R::count('page'), 3 ); + $book = $this->_createBook(); + $book->ownPageList[] = R::dispense('page'); + R::store( $book ); + asrt( R::count('page'), 3 ); + $book = $this->_createBook(); + $book->xownPage[] = R::dispense('page'); + R::store( $book ); + asrt( R::count('page'), 3 ); + $book = $this->_createBook(); + $book->xownPageList[] = R::dispense('page'); + R::store( $book ); + asrt( R::count('page'), 3 ); + + $ads = R::dispense('ad', 3 ); + $book = $this->_createBook(); + $book->alias('magazine')->ownAd = $ads; + $book->ownPage[] = R::dispense('page'); + R::store( $book ); + asrt( R::count('ad'), 6 ); + asrt( R::count('page'), 3 ); + $ads = R::dispense('ad', 3 ); + $book = $this->_createBook(); + $book->alias('magazine')->ownAdList = $ads; + $book->ownPageList[] = R::dispense('page'); + R::store( $book ); + asrt( R::count('ad'), 6 ); + asrt( R::count('page'), 3 ); + $ads = R::dispense('ad', 3 ); + $book = $this->_createBook(); + $book->alias('magazine')->xownAd = $ads; + $book->xownPage[] = R::dispense('page'); + R::store( $book ); + asrt( R::count('ad'), 3 ); + asrt( R::count('page'), 3 ); + $ads = R::dispense('ad', 3 ); + $book = $this->_createBook(); + $book->alias('magazine')->xownAdList = $ads; + $book->xownPageList[] = R::dispense('page'); + R::store( $book ); + asrt( R::count('ad'), 3 ); + asrt( R::count('page'), 3 ); + + $book = $this->_createBook(); + $book->sharedTag[] = R::dispense('tag'); + R::store( $book ); + asrt( R::count('tag'), 3 ); + $book = $this->_createBook(); + $book->sharedTagList[] = R::dispense('tag'); + R::store( $book ); + asrt( R::count('tag'), 3 ); + } + + /** + * Can we delete a bean in a list by its ID? + * Only the UNSET() variant should work. + * + * @return void + */ + public function testDeleteByIDs() + { + $book = $this->_createBook(); + $firstPage = reset( $book->ownPageList ); + $book->ownPage[ $firstPage->id ] = NULL; + try { R::store( $book ); fail(); }catch(\Exception $e) { pass(); } + $book = $this->_createBook(); + asrt( count( $book->ownPage ), 2 ); + $firstPage = reset( $book->ownPageList ); + unset( $book->ownPage[ $firstPage->id ] ); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book->ownPage ), 1 ); + $firstPage = reset( $book->ownPageList ); + $book->ownPage[ $firstPage->id ] = FALSE; + try { R::store( $book ); fail(); }catch(\Exception $e) { pass(); } + $book = $book->fresh(); + asrt( count( $book->ownPage ), 0 ); + + $book = $this->_createBook(); + $firstAd = reset( $book->alias('magazine')->ownAd ); + $book->alias('magazine')->ownAd[ $firstAd->id ] = NULL; + try { R::store( $book ); fail(); }catch(\Exception $e) { pass(); } + $book = $this->_createBook(); + asrt( count( $book->alias('magazine')->ownAd ), 3 ); + $firstAd = reset( $book->alias('magazine')->ownAdList ); + unset( $book->alias('magazine')->ownAdList[ $firstAd->id ] ); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book->alias('magazine')->ownAd ), 2 ); + $firstAd = reset( $book->alias('magazine')->ownAd ); + $book->alias('magazine')->ownAd[ $firstAd->id ] = FALSE; + try { R::store( $book ); fail(); }catch(\Exception $e) { pass(); } + $book = $book->fresh(); + asrt( count( $book->alias('magazine')->ownAd ), 1 ); + + } + + /** + * You CAN delete an own-list by assiging an empty array. + * + * @return void + */ + public function testDeleteOwnListWithEmptyArray() + { + $book = $this->_createBook(); + asrt( isset($book->ownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->ownPage ), 2 ); //when loaded has 2 + $book->ownPage = array(); //remove all + R::store( $book ); + asrt( isset($book->ownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->ownPage ), 0 ); + } + + /** + * You cannot delete an own-list by assigning NULL. + * + * @return void + */ + public function testCANTDeleteOwnListWithNULL() + { + $book = $this->_createBook(); + asrt( isset($book->ownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->ownPage ), 2 ); //when loaded has 2 + $book->ownPage = NULL; //remove all + R::store( $book ); + asrt( isset($book->ownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->ownPage ), 2 ); + } + + /** + * You cannot delete an own-list by assigning FALSE. + * + * @return void + */ + public function testCANTDeleteOwnListWithFalse() + { + $book = $this->_createBook(); + asrt( isset($book->ownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->ownPage ), 2 ); //when loaded has 2 + $book->ownPage = FALSE; //remove all + R::store( $book ); + asrt( isset($book->ownPage), TRUE ); //not loaded yet, lazy loading + asrt( $book->ownPage, '0' ); + } + + /** + * You cannot delete an own-list by unsetting it. + */ + public function testCANTDeleteOwnListWithUnset() + { + $book = $this->_createBook(); + asrt( isset($book->ownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->ownPage ), 2 ); //when loaded has 2 + unset( $book->ownPage ); //does NOT remove all + R::store( $book ); + asrt( isset($book->ownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->ownPage ), 2 ); + } + + /** + * You CAN delete an aliased own-list by assiging an empty array. + * + * @return void + */ + public function testDeleteAliasedOwnListWithEmptyArray() + { + $book = $this->_createBook(); + asrt( isset($book->alias('magazine')->ownAd), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->alias('magazine')->ownAd ), 3 ); //when loaded has 2 + $book->alias('magazine')->ownAd = array(); //remove all + $book->ownPage[] = R::dispense('page'); + R::store( $book ); + asrt( isset($book->alias('magazine')->ownAd), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->alias('magazine')->ownAd ), 0 ); + asrt( count( $book->alias('magazine')->ownPage ), 0 ); //also test possible confusion + asrt( count( $book->all()->ownPageList ), 3 ); + } + + /** + * You cannot delete an aliased own-list by assigning NULL. + * + * @return void + */ + public function testCANTDeleteAliasedOwnListWithNULL() + { + $book = $this->_createBook(); + asrt( isset($book->alias('magazine')->ownAd), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->alias('magazine')->ownAd ), 3 ); //when loaded has 2 + $book->alias('magazine')->ownAd = NULL; //remove all + R::store( $book ); + asrt( isset($book->alias('magazine')->ownAd), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->alias('magazine')->ownAd ), 3 ); + } + + /** + * You cannot delete an aliased own-list by assigning FALSE. + * + * @return void + */ + public function testCANTDeleteAliasedOwnListWithFalse() + { + $book = $this->_createBook(); + asrt( isset($book->alias('magazine')->ownAd), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->alias('magazine')->ownAd ), 3 ); //when loaded has 2 + $book->alias('magazine')->ownAd = FALSE; //remove all + R::store( $book ); + asrt( isset($book->alias('magazine')->ownAd), TRUE ); //not loaded yet, lazy loading + asrt( $book->alias('magazine')->ownAd, '0' ); + } + + /** + * You cannot delete an aliased own-list by unsetting it. + * + * @return void + */ + public function testCANTDeleteAliasedOwnListWithUnset() + { + $book = $this->_createBook(); + asrt( isset($book->alias('magazine')->ownAd), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->alias('magazine')->ownAd ), 3 ); //when loaded has 2 + unset( $book->alias('magazine')->ownAd ); //does NOT remove all + R::store( $book ); + asrt( isset($book->alias('magazine')->ownAd), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->alias('magazine')->ownAd ), 3 ); + } + + /** + * You CAN delete an x-own-list by assiging an empty array. + * + * @return void + */ + public function testDeleteXOwnListWithEmptyArray() + { + $book = $this->_createBook(); + asrt( isset($book->xownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->xownPage ), 2 ); //when loaded has 2 + $book->xownPage = array(); //remove all + R::store( $book ); + asrt( isset($book->xownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->xownPage ), 0 ); + } + + /** + * You cannot delete an x-own-list by assigning NULL. + * + * @return void + */ + public function testCANTDeleteXOwnListWithNULL() + { + $book = $this->_createBook(); + asrt( isset($book->xownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->xownPage ), 2 ); //when loaded has 2 + $book->xownPage = NULL; //remove all + R::store( $book ); + asrt( isset($book->xownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->xownPage ), 2 ); + } + + /** + * You cannot delete an x-own-list by assigning FALSE. + * + * @return void + */ + public function testCANTDeleteXOwnListWithFalse() + { + $book = $this->_createBook(); + asrt( isset($book->xownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->xownPage ), 2 ); //when loaded has 2 + $book->xownPage = FALSE; //remove all + R::store( $book ); + asrt( isset($book->xownPage), TRUE ); //not loaded yet, lazy loading + asrt( $book->xownPage, '0' ); + } + + /** + * You cannot delete an x-own-list by unsetting it. + * + * @return void + */ + public function testCANTDeleteXOwnListWithUnset() + { + $book = $this->_createBook(); + asrt( isset($book->xownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->xownPage ), 2 ); //when loaded has 2 + unset( $book->xownPage ); //does NOT remove all + R::store( $book ); + asrt( isset($book->xownPage), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->xownPage ), 2 ); + } + + /** + * You CAN delete a shared-list by assiging an empty array. + * + * @return void + */ + public function testDeleteSharedListWithEmptyArray() + { + $book = $this->_createBook(); + asrt( isset($book->sharedTag), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->sharedTag ), 2 ); //when loaded has 2 + $book->sharedTag = array(); //remove all + R::store( $book ); + asrt( isset($book->sharedTag), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->sharedTag ), 0 ); + } + + /** + * You cannot delete a shared list by assigning NULL. + * + * @return void + */ + public function testCANTDeleteSharedListWithNULL() + { + $book = $this->_createBook(); + asrt( isset($book->sharedTag), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->sharedTag ), 2 ); //when loaded has 2 + $book->sharedTag = NULL; //remove all + R::store( $book ); + asrt( isset($book->sharedTag), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->sharedTag ), 2 ); + } + + /** + * You cannot delete a shared-list by assigning FALSE. + * + * @return void + */ + public function testCANTDeleteSharedListWithFalse() + { + $book = $this->_createBook(); + asrt( isset($book->sharedTag), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->sharedTag ), 2 ); //when loaded has 2 + $book->sharedTag = FALSE; //remove all + R::store( $book ); + asrt( isset($book->sharedTag), TRUE ); //not loaded yet, lazy loading + asrt( $book->sharedTag, '0' ); + } + + /** + * You cannot delete a shared-list by unsetting it. + * + * @return void + */ + public function testCANTDeleteSharedWithUnset() + { + $book = $this->_createBook(); + asrt( isset($book->sharedTag), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->sharedTag ), 2 ); //when loaded has 2 + unset( $book->sharedTag ); //does NOT remove all + R::store( $book ); + asrt( isset($book->sharedTag), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->sharedTag ), 2 ); + } + + /** + * You CAN delete a shared-list by assiging an empty array. + * + * @return void + */ + public function testDeleteViaSharedListWithEmptyArray() + { + $book = $this->_createBook(); + asrt( isset($book->via('connection')->sharedUser), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->via('connection')->sharedUser ), 1 ); //when loaded has 2 + $book->via('connection')->sharedUser = array(); //remove all + R::store( $book ); + asrt( isset($book->via('connection')->sharedUser), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->via('connection')->sharedUser ), 0 ); + } + + /** + * You cannot delete a shared-list by assigning NULL. + * + * @return void + */ + public function testCANTDeleteViaSharedListWithNULL() + { + $book = $this->_createBook(); + asrt( isset($book->via('connection')->sharedUser), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->via('connection')->sharedUser ), 1 ); //when loaded has 2 + $book->via('connection')->sharedUser = NULL; //remove all + R::store( $book ); + asrt( isset($book->via('connection')->sharedUser), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->via('connection')->sharedUser ), 1 ); + } + + /** + * You cannot delete a shared list by assigning FALSE. + * + * @return void + */ + public function testCANTDeleteViaSharedListWithFalse() + { + $book = $this->_createBook(); + asrt( isset($book->via('connection')->sharedUser), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->via('connection')->sharedUser ), 1 ); //when loaded has 1 + $book->via('connection')->sharedUser = FALSE; //remove all + R::store( $book ); + asrt( isset($book->via('connection')->sharedUser), TRUE ); //not loaded yet, lazy loading + asrt( count( $book->via('connection')->sharedUser ), 1 ); //when loaded has 1 + + } + + /** + * You cannot delete a shared-list by unsetting it. + * + * @return void + */ + public function testCANTDeleteViaSharedWithUnset() + { + $book = $this->_createBook(); + asrt( isset($book->via('connection')->sharedUser), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->via('connection')->sharedUser ), 1 ); //when loaded has 2 + unset( $book->via('connection')->sharedUser ); //does NOT remove all + R::store( $book ); + asrt( isset($book->via('connection')->sharedUser), FALSE ); //not loaded yet, lazy loading + asrt( count( $book->via('connection')->sharedUser ), 1 ); + } + + /** + * You cannot delete a parent bean by unsetting it. + * + * @return void + */ + public function testYouCANTDeleteParentBeanWithUnset() + { + $book = $this->_createBook(); + asrt( isset($book->author), FALSE ); + asrt( (boolean) ($book->author), TRUE ); + unset( $book->author ); + R::store( $book ); + $book = $book->fresh(); + asrt( isset($book->author), FALSE ); + asrt( (boolean) ($book->author), TRUE ); + } + + /** + * You cannot delete a parent bean by setting it to NULL. + * + * @return void + */ + public function testYouCANDeleteParentBeanWithNULL() + { + $book = $this->_createBook(); + asrt( isset($book->author), FALSE ); + asrt( (boolean) ($book->author), TRUE ); + $book->author = NULL; + R::store( $book ); + $book = $book->fresh(); + asrt( isset($book->author), FALSE ); + asrt( (boolean) ($book->author), FALSE ); + } + + /** + * You CAN delete a parent bean by setting it to FALSE. + * + * @return void + */ + public function testYouCANDeleteParentBeanWithFALSE() + { + $book = $this->_createBook(); + asrt( isset($book->author), FALSE ); + asrt( (boolean) ($book->author), TRUE ); + $book->author = FALSE; + R::store( $book ); + $book = $book->fresh(); + asrt( isset($book->author), FALSE ); + asrt( (boolean) ($book->author), FALSE ); + } + + /** + * You cannot delete an aliased parent bean by unsetting it. + * + * @return void + */ + public function testYouCANTDeleteAliasedParentBeanWithUnset() + { + $book = $this->_createBook(); + asrt( isset($book->fetchAs('author')->coauthor), FALSE ); + asrt( (boolean) ($book->fetchAs('author')->coauthor), TRUE ); + unset( $book->fetchAs('author')->coauthor ); + R::store( $book ); + $book = $book->fresh(); + asrt( isset($book->fetchAs('author')->coauthor), FALSE ); + asrt( (boolean) ($book->fetchAs('author')->coauthor), TRUE ); + } + + /** + * You CAN delete an aliased parent bean by setting it to NULL. + * + * @return void + */ + public function testYouCANDeleteAliasedParentBeanWithNULL() + { + $book = $this->_createBook(); + asrt( isset($book->fetchAs('author')->coauthor), FALSE ); + asrt( (boolean) ($book->fetchAs('author')->coauthor), TRUE ); + $book->fetchAs('author')->coauthor = NULL; + R::store( $book ); + $book = $book->fresh(); + asrt( isset($book->fetchAs('author')->coauthor), FALSE ); + asrt( (boolean) ($book->fetchAs('author')->coauthor), FALSE ); + } + + /** + * You cannot delete an aliased parent bean by setting it to FALSE. + * + * @return void + */ + public function testYouCANDeleteAliasedParentBeanWithFALSE() + { + $book = $this->_createBook(); + asrt( isset($book->fetchAs('author')->coauthor), FALSE ); + asrt( (boolean) ($book->fetchAs('author')->coauthor), TRUE ); + $book->fetchAs('author')->coauthor = FALSE; + R::store( $book ); + $book = $book->fresh(); + asrt( isset($book->fetchAs('author')->coauthor), FALSE ); + asrt( (boolean) ($book->fetchAs('author')->coauthor), FALSE ); + } + + /** + * Tests the effects of unsetting on the shadow of a list. + * + * @return void + */ + public function testUnsettingAListAndShadow() + { + $book = $this->_createBook(); + //should work with ownPage and ownPageList as well... + unset( $book->ownPageList ); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book->ownPage ), 2 ); + unset( $book->ownPage ); + //shadow should be reloaded as well... + $book->with(' LIMIT 1 ')->ownPage; + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book->ownPage ), 2 ); + asrt( count( $book->getMeta('sys.shadow.ownPage') ), 2 ); + unset( $book->ownPage ); + asrt( $book->getMeta('sys.shadow.ownPage'), NULL ); + //no load must clear shadow as well... + $book->noLoad()->ownPage[] = R::dispense( 'page' ); + asrt( count( $book->getMeta('sys.shadow.ownPage') ), 0 ); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book->ownPage ), 3 ); + $lists = array( 'ownPage', 'ownPageList', 'xownPage', 'xownPageList', 'sharedPage', 'sharedPageList' ); + foreach( $lists as $list ) { + $book = R::dispense( 'book' ); + $book->$list; + $shadowKey = $list; + if ( strpos( $list, 'x' ) === 0) $shadowKey = substr( $shadowKey, 1 ); + $shadowKey = preg_replace( '/List$/', '', $shadowKey ); + asrt( is_array( $book->getMeta('sys.shadow.'.$shadowKey) ), TRUE ); + unset( $book->$list ); + asrt( $book->getMeta('sys.shadow.'.$shadowKey), NULL ); + $book->$list; //reloading brings back shadow + asrt( is_array( $book->getMeta('sys.shadow.'.$shadowKey) ), TRUE ); + $book->$list = array(); //keeps shadow (very important to compare deletions!) + asrt( is_array( $book->getMeta('sys.shadow.'.$shadowKey) ), TRUE ); + R::store( $book ); //clears shadow + $book->alias('magazine')->$list; //reloading with alias also brings back shadow + unset( $book->$list ); + asrt( $book->getMeta('sys.shadow.'.$shadowKey), NULL ); + $book = $book->fresh(); //clears shadow, reload + asrt( $book->getMeta('sys.shadow.'.$shadowKey), NULL ); + $book->noLoad()->$list; //reloading with noload also brings back shadow + asrt( is_array( $book->getMeta('sys.shadow.'.$shadowKey) ), TRUE ); + asrt( count( $book->getMeta('sys.shadow.'.$shadowKey) ), 0 ); + $book = $book->fresh(); //clears shadow, reload + asrt( $book->getMeta('sys.shadow.'.$shadowKey), NULL ); + $book->all()->$list; //reloading with all also brings back shadow + asrt( is_array( $book->getMeta('sys.shadow.'.$shadowKey) ), TRUE ); + $book = $book->fresh(); //clears shadow, reload + asrt( $book->getMeta('sys.shadow.'.$shadowKey), NULL ); + $book->with(' LIMIT 1 ')->$list; //reloading with with- all also brings back shadow + asrt( is_array( $book->getMeta('sys.shadow.'.$shadowKey) ), TRUE ); + $book = $book->fresh(); //clears shadow, reload + asrt( $book->getMeta('sys.shadow.'.$shadowKey), NULL ); + $book->$list = array(); //keeps shadow (very important to compare deletions!) + asrt( is_array( $book->getMeta('sys.shadow.'.$shadowKey) ), TRUE ); + $book = $book->fresh(); //clears shadow, reload + asrt( $book->getMeta('sys.shadow.'.$shadowKey), NULL ); + $book->$list = array(); //keeps shadow (very important to compare deletions!) + asrt( is_array( $book->getMeta('sys.shadow.'.$shadowKey) ), TRUE ); + R::trash( $book ); + asrt( $book->getMeta('sys.shadow.'.$shadowKey), NULL ); + } + + //no shadow for parent bean + $book = $book->fresh(); + $book->author = R::dispense( 'author' ); + asrt( $book->getMeta('sys.shadow.author'), NULL ); + R::store( $book ); + $book = $book->fresh(); + unset( $book->author ); //we can unset and it does not remove + R::store( $book ); + $book = $book->fresh(); + asrt( is_object( $book->author ),TRUE ); + //but we can also remove + $book->author = NULL; + R::store( $book ); + $book = $book->fresh(); + asrt( $book->author, NULL ); + + } + + /** + * Test whether the tainted flag gets set correctly. + * + * @return void + */ + public function testAccessingTainting() + { + $book = $this->_createBook(); + asrt( $book->isTainted(), FALSE ); + $book->ownPage; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->author; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->fetchAs('author')->coauthor; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->alias('magazine')->xownAdList; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->title = 'Hello'; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->sharedTag; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->via('connection')->sharedUser; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->coauthor; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->ownFakeList; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->sharedFakeList; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->alias('fake')->ownFakeList; + asrt( $book->isTainted(), TRUE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->title; + asrt( $book->isTainted(), FALSE ); + $book = $book->fresh(); + asrt( $book->isTainted(), FALSE ); + $book->title = 1; + $book->setMeta( 'tainted', FALSE ); + asrt( $book->isTainted(), FALSE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Boxing.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Boxing.php new file mode 100644 index 000000000..1c281c7d2 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Boxing.php @@ -0,0 +1,70 @@ +box(); + R::trash( $bean ); + pass(); + $bean = R::dispense( 'boxedbean' ); + $bean->sharedBoxbean = R::dispense( 'boxedbean' )->box(); + R::store( $bean ); + pass(); + $bean = R::dispense( 'boxedbean' ); + $bean->ownBoxedbean = R::dispense( 'boxedbean' )->box(); + R::store( $bean ); + pass(); + $bean = R::dispense( 'boxedbean' ); + $bean->other = R::dispense( 'boxedbean' )->box(); + R::store( $bean ); + pass(); + $bean = R::dispense( 'boxedbean' ); + $bean->title = 'MyBean'; + $box = $bean->box(); + asrt( ( $box instanceof \Model_Boxedbean ), TRUE ); + R::store( $box ); + } + + /** + * Test fix for issue #512 - thanks for reporting Bernhard H. + * OODBBean::__toString() implementation only works with C_ERR_IGNORE + * + * @return void + */ + public function testToStringIssue512() + { + R::setErrorHandlingFUSE( \RedBeanPHP\OODBBean::C_ERR_FATAL ); + $boxedBean = R::dispense( 'boxedbean' ); + $str = (string) $boxedBean; + asrt( $str, '{"id":0}' ); //no fatal error + R::setErrorHandlingFUSE( FALSE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Chill.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Chill.php new file mode 100644 index 000000000..e85094703 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Chill.php @@ -0,0 +1,154 @@ +col1 = '1'; + $bean->col2 = '2'; + + R::store( $bean ); + + asrt( count( R::getWriter()->getColumns( 'bean' ) ), 3 ); + + $bean->col3 = '3'; + + R::store( $bean ); + + asrt( count( R::getWriter()->getColumns( 'bean' ) ), 4 ); + + R::freeze( array( 'umbrella' ) ); + + $bean->col4 = '4'; + + R::store( $bean ); + + asrt( count( R::getWriter()->getColumns( 'bean' ) ), 5 ); + + R::freeze( array( 'bean' ) ); + + $bean->col5 = '5'; + + try { + R::store( $bean ); + fail(); + } catch (\Exception $e ) { + pass(); + } + + asrt( count( R::getWriter()->getColumns( 'bean' ) ), 5 ); + + R::freeze( array() ); + + $bean->col5 = '5'; + + R::store( $bean ); + + asrt( count( R::getWriter()->getColumns( 'bean' ) ), 6 ); + } + + /** + * Test whether we cannot add unique constraints on chilled tables, + * otherwise you cannot avoid this from happening when adding beans to the + * shared list :) -- this is almost a theoretical issue however we want it + * to work according to specifications! + * + * @return void + */ + public function testDontAddUniqueConstraintForChilledBeanTypes() + { + R::nuke(); + $person = R::dispense( 'person' ); + $role = R::dispense( 'role' ); + $person->sharedRole[] = $role; + R::store( $person ); + $person->sharedRole[] = R::dispense( 'role' ); + R::store( $person ); + $bean = R::getRedBean()->dispense('person_role'); + $bean->personId = $person->id; + $bean->roleId = $role->id; + try { + R::store( $bean ); + fail(); + } catch(\Exception $e) { + pass(); + } + asrt(R::count('person_role'), 2); + + R::nuke(); + $link = R::getRedBean()->dispense('person_role'); + $person = R::dispense( 'person' ); + $role = R::dispense( 'role' ); + $link->person = $person; + $link->role = $role; + R::store( $link ); + R::freeze(array('person_role')); + $person->sharedRole[] = R::dispense( 'role' ); + R::store( $person ); + $bean = R::getRedBean()->dispense('person_role'); + $bean->personId = $person->id; + $bean->roleId = $role->id; + try { + R::store( $bean ); + pass(); + } catch(\Exception $e) { + fail(); + } + asrt(R::count('person_role'), 3); + R::freeze( array() ); //set freeze to FALSE and clear CHILL LIST! + } + + /** + * Test whether we can set and reset the chill list and check the contents + * of the chill list. + * + * @return void + */ + public function testChillTest() + { + R::freeze( array( 'beer' ) ); + $oodb = R::getRedBean(); + asrt( $oodb->isChilled( 'beer' ), TRUE ); + asrt( $oodb->isChilled( 'wine' ), FALSE ); + R::freeze( FALSE ); + $oodb = R::getRedBean(); + asrt( $oodb->isChilled( 'beer' ), TRUE ); + asrt( $oodb->isChilled( 'wine' ), FALSE ); + R::freeze( TRUE ); + $oodb = R::getRedBean(); + asrt( $oodb->isChilled( 'beer' ), TRUE ); + asrt( $oodb->isChilled( 'wine' ), FALSE ); + R::freeze( array() ); + $oodb = R::getRedBean(); + asrt( $oodb->isChilled( 'beer' ), FALSE ); + asrt( $oodb->isChilled( 'wine' ), FALSE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Close.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Close.php new file mode 100644 index 000000000..ae9f8ff56 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Close.php @@ -0,0 +1,38 @@ +getDatabase()->isConnected(), TRUE ); + R::close(); + asrt( R::getDatabaseAdapter()->getDatabase()->isConnected(), FALSE ); + } +} + diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Copy.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Copy.php new file mode 100644 index 000000000..5deebc5c2 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Copy.php @@ -0,0 +1,224 @@ +ownDocument[] = $document; + R::store( $document ); + $duplicate = R::dup( $document ); + pass(); //if RB cant handle this is will crash (nesting level error from PHP). + $id2 = R::store( $duplicate ); + $duplicate = R::load( 'document', $id ); + asrt( (int) $document->document_id, $id ); + asrt( (int) $duplicate->document_id, $id2 ); + // Export variant + $duplicate = R::exportAll( $document ); + asrt( (int) $duplicate[0]['document_id'], $id ); + } + + /** + * Test real world scenario: Versioning + */ + public function testVersioning() + { + $document = R::dispense( 'document' ); + $page = R::dispense( 'page' ); + $document->title = 'test'; + $page->content = 'lorem ipsum'; + $user = R::dispense( 'user' ); + $user->name = 'Leo'; + $document->sharedUser[] = $user; + $document->ownPage[] = $page; + $document->starship_id = 3; + $document->planet = R::dispense( 'planet' ); + R::store( $document ); + $duplicate = R::dup( $document ); + R::store( $duplicate ); + $duplicate = R::dup( $document ); + R::store( $duplicate ); + asrt( R::count( 'planet' ), 1 ); + asrt( R::count( 'user' ), 1 ); + asrt( R::count( 'document' ), 3 ); + asrt( R::count( 'page' ), 3 ); + asrt( R::count( 'spaceship' ), 0 ); + } + + /** + * Same as above but now with intermediate save, counts must be same + */ + public function testVersioningIntermediateSaves() + { + $document = R::dispense( 'document' ); + $page = R::dispense( 'page' ); + $document->title = 'test'; + $page->content = 'lorem ipsum'; + $user = R::dispense( 'user' ); + $user->name = 'Leo'; + $document->sharedUser[] = $user; + $document->ownPage[] = $page; + $document->starship_id = 3; + $document->planet = R::dispense( 'planet' ); + R::store( $document ); + $duplicate = R::dup( $document ); + R::store( $document ); + R::store( $duplicate ); + R::store( $document ); + $duplicate = R::dup( $document ); + R::store( $document ); + R::store( $duplicate ); + asrt( R::count( 'planet' ), 1 ); + asrt( R::count( 'user' ), 1 ); + asrt( R::count( 'document' ), 3 ); + asrt( R::count( 'page' ), 3 ); + asrt( R::count( 'spaceship' ), 0 ); + // same, but now with intermediate save, counts must be same + R::freeze( TRUE ); + $document = R::dispense( 'document' ); + $page = R::dispense( 'page' ); + $document->title = 'test'; + $page->content = 'lorem ipsum'; + $user = R::dispense( 'user' ); + $user->name = 'Leo'; + $document->sharedUser[] = $user; + $document->ownPage[] = $page; + $document->starship_id = 3; + $document->planet = R::dispense( 'planet' ); + R::store( $document ); + $duplicate = R::dup( $document ); + R::store( $document ); + R::store( $duplicate ); + R::store( $document ); + $duplicate = R::dup( $document ); + R::store( $document ); + R::store( $duplicate ); + asrt( R::count( 'planet' ), 2 ); + asrt( R::count( 'user' ), 2 ); + asrt( R::count( 'document' ), 6 ); + asrt( R::count( 'page' ), 6 ); + asrt( R::count( 'spaceship' ), 0 ); + R::freeze( FALSE ); + } + + /** + * Test Recursion + */ + public function testRecursion() + { + list( $d1, $d2 ) = R::dispense( 'document', 2 ); + $page = R::dispense( 'page' ); + list( $p1, $p2 ) = R::dispense( 'paragraph', 2 ); + list( $e1, $e2 ) = R::dispense( 'excerpt', 2 ); + $id2 = R::store( $d2 ); + $p1->name = 'a'; + $p2->name = 'b'; + $page->title = 'my page'; + $page->ownParagraph = array( $p1, $p2 ); + $p1->ownExcerpt[] = $e1; + $p2->ownExcerpt[] = $e2; + $e1->ownDocument[] = $d2; + $e2->ownDocument[] = $d1; + $d1->ownPage[] = $page; + $id1 = R::store( $d1 ); + $d1 = R::load( 'document', $id1 ); + $d = R::dup( $d1 ); + $ids = array(); + asrt( ( $d instanceof OODBBean ), TRUE ); + asrt( count( $d->ownPage ), 1 ); + foreach ( end( $d->ownPage )->ownParagraph as $p ) { + foreach ( $p->ownExcerpt as $e ) { + $ids[] = end( $e->ownDocument )->id; + } + } + sort( $ids ); + asrt( (int) $ids[0], 0 ); + asrt( (int) $ids[1], $id1 ); + R::store( $d ); + pass(); + $phillies = R::dispense( 'diner' ); + list( $lonelyman, $man, $woman ) = R::dispense( 'guest', 3 ); + $attendant = R::dispense( 'employee' ); + $lonelyman->name = 'Bennie Moten'; + $man->name = 'Daddy Stovepipe'; + $woman->name = 'Mississippi Sarah'; + $attendant->name = 'Gus Cannon'; + $phillies->sharedGuest = array( $lonelyman, $man, $woman ); + $phillies->ownEmployee[] = $attendant; + $props = R::dispense( 'prop', 2 ); + $props[0]->kind = 'cigarette'; + $props[1]->kind = 'coffee'; + $thought = R::dispense( 'thought' ); + $thought->content = 'Blues'; + $thought2 = R::dispense( 'thought' ); + $thought2->content = 'Jazz'; + $woman->ownProp[] = $props[0]; + $man->sharedProp[] = $props[1]; + $attendant->ownThought = array( $thought, $thought2 ); + R::store( $phillies ); + $diner = R::findOne( 'diner' ); + $diner2 = R::dup( $diner ); + $id2 = R::store( $diner2 ); + $diner2 = R::load( 'diner', $id2 ); + asrt( count( $diner->ownEmployee ), 1 ); + asrt( count( $diner2->ownEmployee ), 1 ); + asrt( count( $diner->sharedGuest ), 3 ); + asrt( count( $diner2->sharedGuest ), 3 ); + $employee = reset( $diner->ownEmployee ); + asrt( count( $employee->ownThought ), 2 ); + $employee = reset( $diner2->ownEmployee ); + asrt( count( $employee->ownThought ), 2 ); + // Can we change something in the duplicate without changing the original? + $employee->name = 'Marvin'; + $thought = R::dispense( 'thought' ); + $thought->content = 'depression'; + $employee->ownThought[] = $thought; + array_pop( $diner2->sharedGuest ); + $guest = reset( $diner2->sharedGuest ); + $guest->name = 'Arthur Dent'; + $id2 = R::store( $diner2 ); + $diner2 = R::load( 'diner', $id2 ); + asrt( count( $diner->ownEmployee ), 1 ); + asrt( count( $diner2->ownEmployee ), 1 ); + asrt( count( $diner->sharedGuest ), 3 ); + asrt( count( $diner2->sharedGuest ), 2 ); + $employeeOld = reset( $diner->ownEmployee ); + asrt( count( $employeeOld->ownThought ), 2 ); + $employee = reset( $diner2->ownEmployee ); + asrt( count( $employee->ownThought ), 3 ); + asrt( $employee->name, 'Marvin' ); + asrt( $employeeOld->name, 'Gus Cannon' ); + // However the shared beans must not be copied + asrt( R::count( 'guest' ), 3 ); + asrt( R::count( 'guest_prop' ), 1 ); + $arthur = R::findOne( 'guest', ' ' . R::getWriter()->esc( 'name' ) . ' = ? ', array( 'Arthur Dent' ) ); + asrt( $arthur->name, 'Arthur Dent' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Count.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Count.php new file mode 100644 index 000000000..3a3ab5cd3 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Count.php @@ -0,0 +1,147 @@ +sharedPage = R::dispense( 'page', 10 ); + R::store( $book ); + asrt( R::count('bookPage'), 10 ); + + try { + R::count( 'WrongTypeName' ); + fail(); + } catch ( RedException $ex ) { + pass(); + } + + try { + R::count( 'wrong_type_name' ); + fail(); + } catch ( RedException $ex ) { + pass(); + } + } + + /** + * Test count and wipe. + * + * @return void + */ + public function testCountAndWipe() + { + testpack( "Test count and wipe" ); + + $page = R::dispense( "page" ); + + $page->name = "ABC"; + + R::store( $page ); + + $n1 = R::count( "page" ); + + $page = R::dispense( "page" ); + + $page->name = "DEF"; + + R::store( $page ); + + $n2 = R::count( "page" ); + + asrt( $n1 + 1, $n2 ); + + R::wipe( "page" ); + + asrt( R::count( "page" ), 0 ); + asrt( R::getRedBean()->count( "page" ), 0 ); + asrt( R::getRedBean()->count( "kazoo" ), 0 ); // non existing table + + R::freeze( TRUE ); + + asrt( R::getRedBean()->count( "kazoo" ), 0 ); // non existing table + + R::freeze( FALSE ); + + $page = R::dispense( 'page' ); + + $page->name = 'foo'; + + R::store( $page ); + + $page = R::dispense( 'page' ); + + $page->name = 'bar'; + + R::store( $page ); + + asrt( R::count( 'page', ' name = ? ', array( 'foo' ) ), 1 ); + + // Now count something that does not exist, this should return 0. (just be polite) + asrt( R::count( 'teapot', ' name = ? ', array( 'flying' ) ), 0 ); + asrt( R::count( 'teapot' ), 0 ); + + $currentDriver = $this->currentlyActiveDriverID; + + // Some drivers don't support that many error codes. + if ( $currentDriver === 'mysql' || $currentDriver === 'postgres' ) { + try { + R::count( 'teaport', ' for tea ' ); + fail(); + } catch ( SQL $e ) { + pass(); + } + } + } + + public function testCountShared() { + + R::nuke(); + $book = R::dispense( 'book' ); + $book->sharedPageList = R::dispense( 'page', 5 ); + R::store( $book ); + asrt( $book->countShared('page'), 5 ); + asrt( $book->countShared('leaflet'), 0 ); + asrt( R::dispense( 'book' )->countShared('page'), 0 ); + $am = R::getRedBean()->getAssociationManager(); + asrt( $am->relatedCount( R::dispense( 'book' ), 'page' ), 0); + try { + $am->relatedCount( 'not a bean', 'type' ); + fail(); + } catch( RedException $e ) { + pass(); + } + + } + +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Cross.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Cross.php new file mode 100644 index 000000000..2538b699d --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Cross.php @@ -0,0 +1,533 @@ +name = 'Page 3'; + $book->xownPageList[] = $page; + R::store( $book ); + $book = $book->fresh(); + $texts = $book->aggr( 'ownPageList', 'text' ); + pass(); + asrt( count( $texts ), 0 ); + asrt( is_array( $texts ), TRUE ); + R::nuke(); + $book = R::dispense( 'book' ); + $page1 = R::dispense( 'page' ); + $page1->name = 'Page 1'; + $text1 = R::dispense('text'); + $text1->content = 'Text 1'; + $page1->text = $text1; + $book->xownPageList[] = $page1; + $page2 = R::dispense( 'page' ); + $page2->name = 'Page 2'; + $text2 = R::dispense( 'text' ); + $text2->content = 'Text 2'; + $page2->text = $text2; + $book->xownPageList[] = $page2; + $page3 = R::dispense( 'page' ); + $page3->name = 'Page 3'; + $book->xownPageList[] = $page3; + R::store( $book ); + $book = $book->fresh(); + $texts = $book->aggr( 'ownPageList', 'text' ); + pass(); + asrt( count( $texts ), 2 ); + } + + /** + * Test many different scenarios with self referential + * many-to-many relations. + * + * @return void + */ + public function testSelfReferentialCRUD() + { + R::nuke(); + $buddies = R::dispense( 'buddy', 4 ); + $buddies[0]->name = 'A'; + $buddies[1]->name = 'B'; + $buddies[2]->name = 'C'; + $buddies[3]->name = 'D'; + $buddies[0]->sharedBuddyList = array( $buddies[1], $buddies[2] ); + $buddies[3]->sharedBuddyList = array( $buddies[2] ); + R::storeAll( $buddies ); + $buddies[0] = $buddies[0]->fresh(); + asrt( count( $buddies[0]->sharedBuddyList ), 2 ); + + //does this yield valid combinations - cross relations / self ref n-m + //need to symmetric.... + + $names = R::gatherLabels( $buddies[0]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'B,C' ); + + unset( $buddies[0]->sharedBuddy ); + R::storeAll( $buddies ); + $buddies[0] = $buddies[0]->fresh(); + asrt( count( $buddies[0]->sharedBuddyList ), 2 ); + + $buddies[3] = $buddies[3]->fresh(); + asrt( count( $buddies[3]->sharedBuddyList ), 1 ); + + $names = R::gatherLabels( $buddies[3]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'C' ); + + $buddies[2] = $buddies[2]->fresh(); + asrt( count( $buddies[2]->sharedBuddyList ), 2 ); + + $names = R::gatherLabels( $buddies[2]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'A,D' ); + + $buddies[1] = $buddies[1]->fresh(); + asrt( count( $buddies[1]->sharedBuddyList ), 1 ); + + $names = R::gatherLabels( $buddies[1]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'A' ); + + //Can we add one? + $buddies[1]->sharedBuddyList[] = R::dispense('buddy')->setAttr('name', 'E'); + R::store( $buddies[1] ); + + $buddies[0] = $buddies[0]->fresh(); + asrt( count( $buddies[0]->sharedBuddyList ), 2 ); + + $names = R::gatherLabels( $buddies[0]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'B,C' ); + + $buddies[1] = $buddies[1]->fresh(); + asrt( count( $buddies[1]->sharedBuddyList ), 2 ); + + $names = R::gatherLabels( $buddies[1]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'A,E' ); + + $all = R::find( 'buddy' ); + asrt( count( $all ), 5 ); + + foreach( $buddies[1]->sharedBuddy as $buddy ) { + if ( $buddy->name === 'E' ) { + $buddyE = $buddy; + } + } + + asrt( isset( $buddyE ), TRUE ); + asrt( $buddyE->name, 'E' ); + + //can we update? + foreach( $buddies[0]->sharedBuddy as $buddy ) { + if ( $buddy->name === 'C' ) { + $buddy->name = 'C2'; + } + } + + R::store( $buddies[0] ); + + $buddies[0] = $buddies[0]->fresh(); + asrt( count( $buddies[0]->sharedBuddyList ), 2 ); + + $names = R::gatherLabels( $buddies[0]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'B,C2' ); + + $buddies[2] = $buddies[2]->fresh(); + asrt( count( $buddies[2]->sharedBuddyList ), 2 ); + + $names = R::gatherLabels( $buddies[2]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'A,D' ); + + //can we delete? + foreach( $buddies[0]->sharedBuddyList as $id => $buddy ) { + if ( $buddy->name === 'B' ) { + unset( $buddies[0]->sharedBuddyList[$id] ); + } + } + + R::store( $buddies[0] ); + + $buddies[0] = $buddies[0]->fresh(); + asrt( count( $buddies[0]->sharedBuddyList ), 1 ); + + $names = R::gatherLabels( $buddies[0]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'C2' ); + + $buddies[1] = $buddies[1]->fresh(); + asrt( count( $buddies[1]->sharedBuddyList ), 1 ); + + $names = R::gatherLabels( $buddies[1]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'E' ); + + asrt( R::count( 'buddy' ), 5 ); + asrt( R::count( 'buddyBuddy' ), 3 ); + + $buddies[3] = $buddies[3]->fresh(); + asrt( count( $buddies[3]->sharedBuddyList ), 1 ); + + $names = R::gatherLabels( $buddies[3]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'C2' ); + + $buddies[2] = $buddies[2]->fresh(); + asrt( count( $buddies[2]->sharedBuddyList ), 2 ); + + $names = R::gatherLabels( $buddies[2]->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'A,D' ); + + $buddyE = $buddyE->fresh(); + asrt( count( $buddyE->sharedBuddyList ), 1 ); + + $names = R::gatherLabels( $buddyE->sharedBuddyList ); + sort( $names ); + $names = implode( ',', $names ); + asrt( $names, 'B' ); + + //can we access linked_by -- o dear mysql again! cant have alias in WHERE! + if ( $this->currentlyActiveDriverID === 'mysql' ) { + $buddyE = $buddyE->fresh(); + asrt( count( $buddyE->with(' HAVING linked_by > 0 ')->sharedBuddyList ), 1 ); + $buddyE = $buddyE->fresh(); + asrt( count( $buddyE->with(' HAVING linked_by < 0 ')->sharedBuddyList ), 0 ); + } + + //even postgres sucks. Only SQLite knows how to handle this. + //I dont give a fuck whether it's an SQL standard or not, it should just work. + if ( $this->currentlyActiveDriverID === 'sqlite' ) { + $buddyE = $buddyE->fresh(); + asrt( count( $buddyE->withCondition(' linked_by > 0 ')->sharedBuddyList ), 1 ); + $buddyE = $buddyE->fresh(); + asrt( count( $buddyE->withCondition(' linked_by < 0 ')->sharedBuddyList ), 0 ); + } + + $buddyE = $buddyE->fresh(); + asrt( count( $buddyE->withCondition(' buddy_buddy.buddy_id > 0 AND buddy_buddy.buddy2_id > 0 ')->sharedBuddyList ), 1 ); + $buddyE = $buddyE->fresh(); + asrt( count( $buddyE->withCondition(' buddy_buddy.buddy_id < 0 AND buddy_buddy.buddy2_id < 0 ')->sharedBuddyList ), 0 ); + } + + /** + * Test self referential N-M relations (page_page). + * + * @return void + */ + public function testSelfReferential() + { + $page = R::dispense( 'page' )->setAttr( 'title', 'a' ); + $page->sharedPage[] = R::dispense( 'page' )->setAttr( 'title', 'b' ); + R::store( $page ); + $page = $page->fresh(); + $page = reset( $page->sharedPage ); + asrt( $page->title, 'b' ); + $tables = array_flip( R::inspect() ); + asrt( isset( $tables['page_page'] ), true ); + $columns = R::inspect( 'page_page' ); + asrt( isset( $columns['page2_id'] ), true ); + } + + /** + * Test the unique constraint. + * Just want to make sure it is not too limiting and functions + * properly for typical RedBeanPHP usage. + * + * @return void + */ + public function testUnique() + { + R::nuke(); + $page1 = R::dispense( 'page' ); + $tag1 = R::dispense( 'tag' ); + $page2 = R::dispense( 'page' ); + $tag2 = R::dispense( 'tag' ); + $page3 = R::dispense( 'page' ); + $tag3 = R::dispense( 'tag' ); + $page1->sharedTag[] = $tag1; + R::store( $page1 ); + //can we save all combinations with unique? + asrt( R::count( 'pageTag' ), 1); + $page1->sharedTag[] = $tag2; + R::store( $page1 ); + asrt( R::count( 'pageTag' ), 2 ); + $page1->sharedTag[] = $tag3; + $page2->sharedTag[] = $tag1; + $page2->sharedTag[] = $tag2; + $page2->sharedTag[] = $tag3; + $page3->sharedTag[] = $tag1; + $page3->sharedTag[] = $tag2; + $page3->sharedTag[] = $tag3; + R::storeAll( array( $page1, $page2, $page3 ) ); + asrt( R::count('pageTag'), 9 ); + $page1 = $page1->fresh(); + $page1->sharedTag[] = $tag3; + R::store( $page1 ); + //cant add violates unique + asrt( R::count( 'pageTag' ), 9 ); + } + + /** + * Shared lists can only be formed using types. + * If you happen to have two beans of the same type you can still + * have a shared list but not with a sense of direction. + * I.e. quest->sharedQuest returns all the quests that follow the first one, + * but also the ones that are followed by the first one. + * If you want to have some sort of direction; i.e. one quest follows another one + * you'll have to use an alias: quest->target, but now you can't use the shared list + * anymore because it will start looking for a type named 'target' (which is just an alias) + * for quest, but it cant find that table and it's not possible to 'keep remembering' + * the alias throughout the system. + * + * The aggr() method solves this inconvenience. + * Aggr iterates through the list identified by its first argument ('target' -> ownQuestTargetList) + * and fetches every ID of the target (quest_target.target_id), loads these beans in batch for + * optimal performance, puts them back in the beans (questTarget->target) and returns the + * references. + * + * @return void + */ + public function testAggregationInSelfRefNM() + { + R::nuke(); + $quest1 = R::dispense( 'quest' ); + $quest1->name = 'Quest 1'; + $quest2 = R::dispense( 'quest' ); + $quest2->name = 'Quest 2'; + $quest3 = R::dispense( 'quest' ); + $quest3->name = 'Quest 3'; + $quest4 = R::dispense( 'quest' ); + $quest4->name = 'Quest 4'; + + $quest1->link( 'questTarget' )->target = $quest2; + $quest1->link( 'questTarget' )->target = $quest3; + $quest3->link( 'questTarget' )->target = $quest4; + $quest3->link( 'questTarget' )->target = $quest1; + + R::storeAll( array( $quest1, $quest3 ) ); + + //There should be 4 links + asrt( (int) R::count('questTarget'), 4 ); + + $quest1 = $quest1->fresh(); + $targets = $quest1->aggr( 'ownQuestTargetList', 'target', 'quest' ); + + //can we aggregate the targets over the link type? + asrt( count( $targets), 2 ); + + //are the all valid beans? + foreach( $targets as $target ) { + //are they beans? + asrt( ( $target instanceof OODBBean ), TRUE ); + //are they fetched as quest? + asrt( ( $target->getMeta( 'type' ) ), 'quest' ); + } + + //list target should already have been loaded, nuke has no effect + R::nuke(); + $links = $quest1->ownQuestTargetList; + + //are the links still there, have they been set in the beans as well? + asrt( count( $links ), 2); + + //are they references instead of copies, changes in the aggregation set should affect the beans in links! + foreach( $targets as $target ) { + $target->name .= 'b'; + asrt( substr( $target->name, -1 ), 'b' ); + } + + //do the names end with a 'b' here as well ? i.e. have they been changed through references? + foreach( $links as $link ) { + asrt( substr( $target->name, -1 ), 'b' ); + } + + //now test the effect on existing shadow... + R::nuke(); + $quest1 = R::dispense('quest'); + $quest1->name = 'Quest 1'; + $quest2 = R::dispense('quest'); + $quest2->name = 'Quest 2'; + $quest3 = R::dispense('quest'); + $quest3->name = 'Quest 3'; + $quest4 = R::dispense('quest'); + $quest4->name = 'Quest 4'; + + $quest1->link( 'questTarget' )->target = $quest2; + $quest1->link( 'questTarget' )->target = $quest3; + + R::store($quest1); + asrt( (int) R::count( 'questTarget' ), 2 ); + + //now lets first build a shadow + $quest1->link( 'questTarget' )->target = $quest4; + + //$quest1 = $quest1->fresh(); + $targets = $quest1->aggr( 'ownQuestTargetList', 'target', 'quest' ); + + //targets should not include the new bean... + asrt( count($targets), 2 ); + + //this should not overwrite the existing beans + R::store($quest1); + asrt( (int) R::count( 'questTarget' ), 3 ); + } + + /** + * Test aggr without the aliasing. + * + * @return void + */ + public function testAggrBasic() + { + R::nuke(); + $book = R::dispense( 'book' ); + $page1 = R::dispense( 'page' ); + $page1->name = 'Page 1'; + $text1 = R::dispense('text'); + $text1->content = 'Text 1'; + $page1->text = $text1; + $book->xownPageList[] = $page1; + $page2 = R::dispense( 'page' ); + $page2->name = 'Page 2'; + $text2 = R::dispense( 'text' ); + $text2->content = 'Text 2'; + $page2->text = $text2; + $book->xownPageList[] = $page2; + R::store( $book ); + $book = $book->fresh(); + $texts = $book->aggr( 'ownPageList', 'text' ); + R::nuke(); + asrt( count( $texts ), 2 ); + foreach( $texts as $text ) { + asrt( ( $text instanceof OODBBean ), TRUE ); + } + $pages = $book->ownPageList; + asrt( count( $pages ), 2 ); + asrt( R::count( 'page' ), 0 ); + foreach( $pages as $page ) { + asrt( ( $page instanceof OODBBean ), TRUE ); + $text = $page->text; + asrt( ( $text instanceof OODBBean ), TRUE ); + $text->content = 'CHANGED'; + } + foreach( $texts as $text ) { + asrt( $text->content, 'CHANGED' ); + } + } + + /** + * Test aggr with basic aliasing. + * + * @return void + */ + public function testAggrWithOnlyAlias() + { + R::nuke(); + $book = R::dispense( 'book' ); + $page1 = R::dispense( 'page' ); + $page1->name = 'Page 1'; + $text1 = R::dispense( 'text' ); + $text1->content = 'Text 1'; + $page1->content = $text1; + $book->xownPageList[] = $page1; + $page2 = R::dispense( 'page' ); + $page2->name = 'Page 2'; + $text2 = R::dispense( 'text' ); + $text2->content = 'Text 2'; + $page2->content = $text2; + $book->xownPageList[] = $page2; + R::store( $book ); + $book = $book->fresh(); + $texts = $book->aggr( 'ownPageList', 'content', 'text' ); + R::nuke(); + asrt( count( $texts ), 2 ); + foreach( $texts as $text ) { + asrt( ( $text instanceof OODBBean), TRUE ); + } + $pages = $book->ownPageList; + asrt( count( $pages ), 2 ); + asrt( R::count( 'page' ), 0 ); + foreach( $pages as $page ) { + asrt( ( $page instanceof OODBBean ), TRUE ); + $text = $page->content; + asrt( ( $text instanceof OODBBean ), TRUE ); + $text->content = 'CHANGED'; + } + foreach( $texts as $text ) { + asrt( $text->content, 'CHANGED' ); + } + } + + /** + * The aggr method can only be used with own-list. + * + * @return void + */ + public function testErrorHandlingAggr() + { + $wrongLists = array( 'not-an-own-list', 'OWNlist', 'Ownpage', 'ownbook', 'own book', '!', 'sharedBook' ); + foreach( $wrongLists as $wrongList ) { + $bean = R::dispense( 'bean' ); + try { + $bean->aggr( $wrongList, 'field' ); + fail(); + } catch ( \Exception $exception ) { + pass(); + asrt( ( $exception instanceof RedException ), TRUE ); + } + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Cursors.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Cursors.php new file mode 100644 index 000000000..a74a8b569 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Cursors.php @@ -0,0 +1,95 @@ +number = $i; + $page->content = sha1( $i ); + R::store( $page ); + } + $collection = R::findCollection( 'page' ); + asrt( get_class( $collection ), 'RedBeanPHP\BeanCollection'); + $i = 0; + $list = array(); + while( $bean = $collection->next() ) { + asrt( ( $bean instanceof OODBBean ), TRUE ); + asrt( (string) $bean->number, strval( $i ) ); + asrt( $bean->content, sha1( $i ) ); + $list[] = $bean->content; + $i ++; + } + $collection = R::findCollection( 'page', ' ORDER BY content ASC ' ); + sort( $list ); + $i = 0; + while( $bean = $collection->next() ) { + asrt( $bean->content, $list[$i] ); + $i ++; + } + $collection = R::findCollection( 'page', ' ORDER BY content ASC LIMIT 5 ' ); + sort( $list ); + $i = 0; + while( $bean = $collection->next() ) { + asrt( $bean->content, $list[$i] ); + $i ++; + if ( $i > 5 ) break; + } + $key = array_rand( $list ); + $content = $list[ $key ]; + $collection = R::findCollection( 'page', ' content = ? ', array( $content ) ); + $bean = $collection->next(); + asrt( $bean->content, $content ); + $collection->close(); + } + + /** + * Test empty collections (NULLCursor). + * + * @return void + */ + public function testEmptyCollection() + { + R::nuke(); + $page = R::dispense( 'page' ); + $page->content = 'aaa'; + R::store( $page ); + $collection = R::findCollection( 'page' ); + asrt( get_class( $collection ), 'RedBeanPHP\BeanCollection'); + $collection = R::findCollection( 'page', ' content = ?', array( 'bbb' ) ); + asrt( get_class( $collection ), 'RedBeanPHP\BeanCollection'); + asrt( is_null( $collection->next() ), TRUE ); + $collection = R::findCollection( 'something' ); + asrt( get_class( $collection ), 'RedBeanPHP\BeanCollection'); + asrt( is_null( $collection->next() ), TRUE ); + $collection->close(); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Database.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Database.php new file mode 100644 index 000000000..edcdfc15f --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Database.php @@ -0,0 +1,395 @@ +getDatabase(); + $old = $driver->setMaxIntBind( 10 ); + //use SQLite to confirm... + if ( $this->currentlyActiveDriverID === 'sqlite' ) { + $type = R::getCell( 'SELECT typeof( ? ) ', array( 11 ) ); + asrt( $type, 'text' ); + $type = R::getCell( 'SELECT typeof( ? ) ', array( 10 ) ); + asrt( $type, 'integer' ); + $type = R::getCell( 'SELECT typeof( ? ) ', array( 9 ) ); + asrt( $type, 'integer' ); + } + $new = $driver->setMaxIntBind( $old ); + asrt( $new, 10 ); + try { + $driver->setMaxIntBind( '10' ); + fail(); + } catch( RedException $e ) { + pass(); + } + $new = $driver->setMaxIntBind( $old ); + asrt( $new, $old ); + $new = $driver->setMaxIntBind( $old ); + asrt( $new, $old ); + } + + /** + * Can we use colons in SQL? + * + * @return void + */ + public function testColonsInSQL() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book->title = 'About :'; + R::store( $book ); + pass(); + $book = R::findOne( 'book', ' title LIKE :this ', array( + ':this' => 'About :' + ) ); + asrt( ( $book instanceof OODBBean ), TRUE ); + //without the colon? + $book = R::findOne( 'book', ' title LIKE :this ', array( + 'this' => 'About :' + ) ); + asrt( ( $book instanceof OODBBean ), TRUE ); + $book = R::findOne( 'book', ' title LIKE :this ', array( + ':this' => '%:%' + ) ); + asrt( ( $book instanceof OODBBean ), TRUE ); + $book = R::findOne( 'book', ' title LIKE :this OR title LIKE :that', array( + 'this' => '%:%', ':that' => 'That' + ) ); + asrt( ( $book instanceof OODBBean ), TRUE ); + $records = R::getAll('SELECT * FROM book WHERE title LIKE :this', array( ':this' => 'About :' ) ); + asrt( count( $records ), 1 ); + $records = R::getAll('SELECT * FROM book WHERE title LIKE :this', array( 'this' => 'About :' ) ); + asrt( count( $records ), 1 ); + $records = R::getAll('SELECT * FROM book WHERE title LIKE :this OR title LIKE :that', array( ':this' => 'About :', ':that' => 'That' ) ); + asrt( count( $records ), 1 ); + $records = R::getRow('SELECT * FROM book WHERE title LIKE :this', array( ':this' => 'About :' ) ); + asrt( count( $records ), 2 ); + $records = R::getRow('SELECT * FROM book WHERE title LIKE :this', array( 'this' => 'About :' ) ); + asrt( count( $records ), 2 ); + $records = R::getRow('SELECT * FROM book WHERE title LIKE :this OR title LIKE :that', array( ':this' => 'About :', ':that' => 'That' ) ); + asrt( count( $records ), 2 ); + } + + /** + * Test setting direct PDO. + * Not much to test actually. + * + * @return void + */ + public function testDirectPDO() + { + $pdo = R::getDatabaseAdapter()->getDatabase()->getPDO(); + R::getDatabaseAdapter()->getDatabase()->setPDO( $pdo ); + pass(); + } + + /** + * Test for testConnection() method. + * + * @return void + */ + public function testConnectionTester() + { + asrt( R::testConnection(), TRUE ); + } + + /** + * Tests the various ways to fetch (select queries) + * data using adapter methods in the facade. + * Also tests the new R::getAssocRow() method, + * as requested in issue #324. + */ + public function testFetchTypes() + { + R::nuke(); + + $page = R::dispense( 'page' ); + $page->a = 'a'; + $page->b = 'b'; + R::store( $page ); + + $page = R::dispense( 'page' ); + $page->a = 'c'; + $page->b = 'd'; + R::store( $page ); + + $expect = '[{"id":"1","a":"a","b":"b"},{"id":"2","a":"c","b":"d"}]'; + asrt( json_encode( R::getAll( 'SELECT * FROM page' ) ), $expect ); + + $expect = '{"1":"a","2":"c"}'; + asrt( json_encode( R::getAssoc( 'SELECT id, a FROM page' ) ), $expect ); + + $expect = '{"1":{"a":"a","b":"b"},"2":{"a":"c","b":"d"}}'; + asrt( json_encode( R::getAssoc( 'SELECT id, a, b FROM page' ) ), $expect ); + + $expect = '[{"id":"1","a":"a"},{"id":"2","a":"c"}]'; + asrt( json_encode( R::getAssocRow( 'SELECT id, a FROM page' ) ), $expect ); + + $expect = '[{"id":"1","a":"a","b":"b"},{"id":"2","a":"c","b":"d"}]'; + asrt( json_encode( R::getAssocRow( 'SELECT id, a, b FROM page' ) ), $expect ); + + $expect = '{"id":"1","a":"a","b":"b"}'; + asrt( json_encode( R::getRow( 'SELECT * FROM page WHERE id = 1' ) ), $expect ); + + $expect = '"a"'; + asrt( json_encode( R::getCell( 'SELECT a FROM page WHERE id = 1' ) ), $expect ); + + $expect = '"b"'; + asrt( json_encode( R::getCell( 'SELECT b FROM page WHERE id = 1') ), $expect ); + + $expect = '"c"'; + asrt( json_encode( R::getCell('SELECT a FROM page WHERE id = 2') ), $expect ); + + $expect = '["a","c"]'; + asrt( json_encode( R::getCol( 'SELECT a FROM page' ) ), $expect ); + + $expect = '["b","d"]'; + asrt( json_encode( R::getCol('SELECT b FROM page') ), $expect ); + } + + /** + * Tests whether we can store an empty bean. + * An empty bean has no properties, only ID. Normally we would + * skip the ID field in an INSERT, this test forces the driver + * to specify a value for the ID field. Different writers have to + * use different values: Mysql uses NULL to insert a new auto-generated ID, + * while Postgres has to use DEFAULT. + */ + public function testEmptyBean() + { + testpack( 'Test Empty Bean Storage.' ); + R::nuke(); + $bean = R::dispense( 'emptybean' ); + $id = R::store( $bean ); + asrt( ( $id > 0 ), TRUE ); + asrt( R::count( 'emptybean' ), 1 ); + $bean = R::dispense( 'emptybean' ); + $id = R::store( $bean ); + asrt( ( $id > 0 ), TRUE ); + asrt( R::count( 'emptybean' ), 2 ); + //also test in frozen mode + R::freeze( TRUE ); + $bean = R::dispense( 'emptybean' ); + $id = R::store( $bean ); + asrt( ( $id > 0 ), TRUE ); + asrt( R::count( 'emptybean' ), 3 ); + R::freeze( FALSE ); + } + + /** + * Test the database driver and low level functions. + * + * @return void + */ + public function testDriver() + { + $currentDriver = $this->currentlyActiveDriverID; + + R::store( R::dispense( 'justabean' ) ); + + $adapter = new TroubleDapter( R::getToolBox()->getDatabaseAdapter()->getDatabase() ); + + $adapter->setSQLState( 'HY000' ); + + $writer = new SQLiteT( $adapter ); + $redbean = new OODB( $writer ); + $toolbox = new ToolBox( $redbean, $adapter, $writer ); + + // We can only test this for a known driver... + if ( $currentDriver === 'sqlite' ) { + try { + $redbean->find( 'bean' ); + + pass(); + } catch (\Exception $e ) { + var_dump( $e->getSQLState() ); + + fail(); + } + } + + $adapter->setSQLState( -999 ); + + try { + $redbean->find( 'bean' ); + + fail(); + } catch (\Exception $e ) { + pass(); + } + + try { + $redbean->wipe( 'justabean' ); + + fail(); + } catch (\Exception $e ) { + pass(); + } + + $toolbox = R::getToolBox(); + $adapter = $toolbox->getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + + $page = $redbean->dispense( "page" ); + + try { + $adapter->exec( "an invalid query" ); + fail(); + } catch ( SQL $e ) { + pass(); + } + + // Special data type description should result in magic number 99 (specified) + if ( $currentDriver == 'mysql' ) { + asrt( $writer->code( MySQL::C_DATATYPE_SPECIAL_DATE ), 99 ); + } + + if ( $currentDriver == 'pgsql' ) { + asrt( $writer->code( PostgreSQL::C_DATATYPE_SPECIAL_DATE ), 99 ); + } + + if ( $currentDriver == 'CUBRID' ) { + asrt( $writer->code( CUBRID::C_DATATYPE_SPECIAL_DATE ), 99 ); + } + + asrt( (int) $adapter->getCell( "SELECT 123" ), 123 ); + + $page->aname = "my page"; + + $id = (int) $redbean->store( $page ); + + asrt( (int) $page->id, 1 ); + asrt( (int) $pdo->GetCell( "SELECT count(*) FROM page" ), 1 ); + asrt( $pdo->GetCell( "SELECT aname FROM page LIMIT 1" ), "my page" ); + asrt( (int) $id, 1 ); + + $page = $redbean->load( "page", 1 ); + + asrt( $page->aname, "my page" ); + asrt( ( (bool) $page->getMeta( "type" ) ), TRUE ); + asrt( isset( $page->id ), TRUE ); + asrt( ( $page->getMeta( "type" ) ), "page" ); + asrt( (int) $page->id, $id ); + } + + /** + * Test selecting. + * + * @return void + */ + public function testSelects() + { + $rooms = R::dispense( 'room', 2 ); + + $rooms[0]->kind = 'suite'; + $rooms[1]->kind = 'classic'; + $rooms[0]->number = 6; + $rooms[1]->number = 7; + + R::store( $rooms[0] ); + R::store( $rooms[1] ); + + $rooms = R::getAssoc('SELECT * FROM room WHERE id < -999'); + asrt(is_array($rooms), TRUE); + asrt(count($rooms), 0); + + $rooms = R::getAssoc( 'SELECT ' . R::getWriter()->esc( 'number' ) . ', kind FROM room ORDER BY kind ASC' ); + + foreach ( $rooms as $key => $room ) { + asrt( ( $key === 6 || $key === 7 ), TRUE ); + asrt( ( $room == 'classic' || $room == 'suite' ), TRUE ); + } + + $rooms = R::getDatabaseAdapter()->getAssoc( 'SELECT kind FROM room' ); + foreach ( $rooms as $key => $room ) { + asrt( ( $room == 'classic' || $room == 'suite' ), TRUE ); + asrt( $room, $key ); + } + + $rooms = R::getAssoc( 'SELECT `number`, kind FROM rooms2 ORDER BY kind ASC' ); + + asrt( count( $rooms ), 0 ); + asrt( is_array( $rooms ), TRUE ); + + // GetCell should return NULL in case of exception + asrt( NULL, R::getCell( 'SELECT dream FROM fantasy' ) ); + } +} + +/** + * Malfunctioning database adapter to test exceptions. + */ +class TroubleDapter extends DBAdapter +{ + private $sqlState; + + public function setSQLState( $sqlState ) + { + $this->sqlState = $sqlState; + } + + public function get( $sql, $values = array() ) + { + $exception = new SQL( 'Just a trouble maker' ); + $exception->setSQLState( $this->sqlState ); + throw $exception; + } + + public function getRow( $sql, $aValues = array() ) + { + $this->get( $sql, $aValues ); + } + + public function exec( $sql, $aValues = array(), $noEvent = FALSE ) + { + $this->get( $sql, $aValues ); + } +} + diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Dispense.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Dispense.php new file mode 100644 index 000000000..09335edbf --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Dispense.php @@ -0,0 +1,171 @@ +dispense( "page" ); + + // Does it have a meta type? + asrt( ( (bool) $page->getMeta( "type" ) ), TRUE ); + + // Does it have an ID? + asrt( isset( $page->id ), TRUE ); + + // Type should be 'page' + asrt( ( $page->getMeta( "type" ) ), "page" ); + + // ID should be 0 because bean does not exist in database yet. + asrt( ( $page->id ), 0 ); + + // Try some faulty dispense actions. + foreach ( array( "", ".", "-") as $value ) { + try { + $redbean->dispense( $value ); + + fail(); + } catch (RedException $e ) { + pass(); + } + } + + $bean = $redbean->dispense( "testbean" ); + + $bean["property"] = 123; + $bean["abc"] = "def"; + + asrt( $bean["property"], 123 ); + asrt( $bean["abc"], "def" ); + asrt( $bean->abc, "def" ); + + asrt( isset( $bean["abd"] ), FALSE ); + asrt( isset( $bean["abc"] ), TRUE ); + } + + /** + * Tests the facade-only dispenseAll method. + * + * @return void + */ + public function testDispenseAll() + { + list( $book, $page ) = Facade::dispenseAll( 'book,page' ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( ( $page instanceof OODBBean ), TRUE ); + asrt( $book->getMeta( 'type' ), 'book'); + asrt( $page->getMeta( 'type' ), 'page'); + + list( $book, $page, $texts, $mark ) = R::dispenseAll( 'book,page,text*2,mark' ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( ( $page instanceof OODBBean ), TRUE ); + asrt( is_array( $texts ), TRUE ); + asrt( ( $mark instanceof OODBBean ), TRUE ); + asrt( $book->getMeta( 'type'), 'book' ); + asrt( $page->getMeta( 'type'), 'page' ); + asrt( $mark->getMeta( 'type'), 'mark' ); + asrt( $texts[0]->getMeta( 'type'), 'text' ); + asrt( $texts[1]->getMeta( 'type'), 'text' ); + + list( $eggs, $milk, $butter ) = R::dispenseAll( 'eggs*3,milk*1,butter*9' ); + asrt( count( $eggs ), 3 ); + asrt( ( $milk instanceof OODBBean ), TRUE ); + asrt( count( $butter ), 9 ); + + list( $eggs, $milk, $butter ) = R::dispenseAll( 'eggs*3,milk*1,butter*9', TRUE ); + asrt( count( $eggs ), 3 ); + asrt( count( $milk ), 1 ); + asrt( count( $eggs ), 3 ); + + list( $beer ) = R::dispenseAll( 'beer*0', TRUE ); + asrt( is_array( $beer ), TRUE ); + asrt( count( $beer ), 0 ); + + list( $beer ) = R::dispenseAll( 'beer*0', FALSE ); + asrt( is_array( $beer ), FALSE ); + asrt( is_null( $beer ), TRUE ); + asrt( count( $beer ), 0 ); + } + + /** + * Tests different return values of dispense(). + * + * @return void + */ + public function testDispenseArray() + { + $oodb = R::getRedBean(); + $array = $oodb->dispense( 'book', 0, TRUE ); + asrt( is_array( $array ), TRUE ); + $array = $oodb->dispense( 'book', 1, TRUE ); + asrt( is_array( $array ), TRUE ); + $array = $oodb->dispense( 'book', 2, TRUE ); + asrt( is_array( $array ), TRUE ); + $array = R::dispense( 'book', 0, TRUE ); + asrt( is_array( $array ), TRUE ); + $array = R::dispense( 'book', 1, TRUE ); + asrt( is_array( $array ), TRUE ); + $array = R::dispense( 'book', 2, TRUE ); + asrt( is_array( $array ), TRUE ); + + $array = $oodb->dispense( 'book', 0, FALSE ); + asrt( is_array( $array ), FALSE ); + asrt( is_null( $array ), TRUE ); + $array = $oodb->dispense( 'book', 1, FALSE ); + asrt( is_array( $array ), FALSE ); + asrt( ( $array instanceof OODBBean ), TRUE ); + $array = $oodb->dispense( 'book', 2, FALSE ); + asrt( is_array( $array ), TRUE ); + $array = R::dispense( 'book', 0, FALSE ); + asrt( is_array( $array ), FALSE ); + $array = R::dispense( 'book', 1, FALSE ); + asrt( is_array( $array ), FALSE ); + $array = R::dispense( 'book', 2, FALSE ); + asrt( is_array( $array ), TRUE ); + + $array = $oodb->dispense( 'book', 0 ); + asrt( is_array( $array ), FALSE ); + asrt( is_null( $array ), TRUE ); + $array = $oodb->dispense( 'book', 1 ); + asrt( is_array( $array ), FALSE ); + asrt( ( $array instanceof OODBBean ), TRUE ); + $array = $oodb->dispense( 'book', 2 ); + asrt( is_array( $array ), TRUE ); + $array = R::dispense( 'book', 0 ); + asrt( is_array( $array ), FALSE ); + $array = R::dispense( 'book', 1 ); + asrt( is_array( $array ), FALSE ); + $array = R::dispense( 'book', 2 ); + asrt( is_array( $array ), TRUE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Dup.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Dup.php new file mode 100644 index 000000000..bf009a506 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Dup.php @@ -0,0 +1,761 @@ +xownPageList[] = R::dispense( 'page' ); + R::store( $book ); + $bookID = $book->id; + $page = reset( $book->xownPageList ); + $pageID = $page->id; + $book = $book->fresh(); + $copy = R::duplicate( $book ); + asrt( $copy->getMeta( 'sys.dup-from-id' ), $bookID ); + $copyPage = reset( $copy->xownPageList ); + asrt( $copyPage->getMeta( 'sys.dup-from-id' ), $pageID ); + } + + /** + * Test export camelCase. + * + * @return void + */ + public function testExportCamelCase() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book->isCheap = true; + $book->hasISBNCode = false; + $page = R::dispense('page'); + $page->isWrittenWell = true; + $page->containsInterestingText = true; + $book->ownPageList[] = $page; + R::store( $book ); + $book = $book->fresh(); + $export = R::exportAll( $book ); + + asrt( isset( $export[0]['id'] ), true ); + asrt( isset( $export[0]['is_cheap'] ), true ); + asrt( isset( $export[0]['has_isbn_code'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['id'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['is_written_well'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['contains_interesting_text'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['book_id'] ), true ); + + R::useExportCase( 'camel' ); + $export = R::exportAll( $book ); + asrt( isset( $export[0]['id'] ), true ); + asrt( isset( $export[0]['isCheap'] ), true ); + asrt( isset( $export[0]['hasIsbnCode'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['id'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['isWrittenWell'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['containsInterestingText'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['bookId'] ), true ); + + R::useExportCase( 'dolphin' ); + $export = R::exportAll( $book ); + asrt( isset( $export[0]['id'] ), true ); + asrt( isset( $export[0]['isCheap'] ), true ); + asrt( isset( $export[0]['hasIsbnCode'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['id'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['isWrittenWell'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['containsInterestingText'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['bookID'] ), true ); + + R::useExportCase( 'default' ); + $export = R::exportAll( $book ); + asrt( isset( $export[0]['id'] ), true ); + asrt( isset( $export[0]['is_cheap'] ), true ); + asrt( isset( $export[0]['has_isbn_code'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['id'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['is_written_well'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['contains_interesting_text'] ), true ); + asrt( isset( $export[0]['ownPage']['0']['book_id'] ), true ); + + try { + R::useExportCase( 'invalid' ); + fail(); + } catch ( RedException $exception ) { + pass(); + } + } + + /** + * Test whether we can duplicate part of a tree + * without infinite loops. + * + * @return void + */ + public function testDupPortionOfATree() + { + R::nuke(); + $article = R::dispense( 'article' ); + $article->name = 'article 1'; + list( $article2, $article3 ) = R::dispense( 'article', 2 ); + $article2->name = 'article 2'; + $article3->name = 'article 3'; + list( $article4, $article5 ) = R::dispense( 'article' , 2); + $article4->name = 'article 4'; + $article5->name = 'article 5'; + list( $article6, $article7 ) = R::dispense( 'article' , 2); + $article6->name = 'article 6'; + $article7->name = 'article 7'; + $article3->xownArticleList[] = $article7; + $article4->xownArticleList[] = $article6; + $article2->xownArticleList = array( $article5, $article4 ); + $article->xownArticleList = array( $article2, $article3 ); + R::store( $article ); + asrt( R::count( 'article' ), 7 ); + $article2 = $article2->fresh(); + $dupArticle2 = R::duplicate( $article2 ); + $dupArticle2->name = 'article 2b'; + $dupBeans = $dupArticle2->xownArticleList; + foreach( $dupBeans as $dupBean ) { + $list[] = $dupBean->name; + } + sort( $list ); + $listStr = implode( ',', $list ); + asrt( $listStr, 'article 4,article 5' ); + foreach( $dupBeans as $dupBean ) { + if ( $dupBean->name === 'article 4' ) { + $dup4 = $dupBean; + } + } + asrt( isset( $dup4 ), TRUE ); + $dupBeans = $dup4->xownArticleList; + foreach( $dupBeans as $dupBean ) { + asrt( $dupBean->name, 'article 6' ); + } + + //so we have extracted part of the tree, can we store it? + $id = R::store( $dupArticle2 ); + asrt( ( $id > 0 ), TRUE ); + asrt( R::count( 'article' ), 11 ); + + $originalArticle = $article->fresh(); + asrt( $originalArticle->name, 'article 1' ); + + $subArticles = $originalArticle->xownArticleList; + $list = array(); + foreach( $subArticles as $subArticle ) { + $list[] = $subArticle->name; + } + sort( $list ); + $listStr = implode( ',', $list ); + asrt( $listStr, 'article 2,article 2b,article 3' ); + + foreach( $subArticles as $subArticle ) { + if ( $subArticle->name === 'article 2' ) { + $sub2 = $subArticle; + } + if ( $subArticle->name === 'article 3' ) { + $sub3 = $subArticle; + } + } + + $subArticles = $sub2->xownArticleList; + $list = array(); + foreach( $subArticles as $subArticle ) { + $list[] = $subArticle->name; + } + sort( $list ); + $listStr = implode( ',', $list ); + asrt( $listStr, 'article 4,article 5' ); + + $subArticles = $sub3->xownArticleList; + $list = array(); + foreach( $subArticles as $subArticle ) { + $list[] = $subArticle->name; + } + sort( $list ); + $listStr = implode( ',', $list ); + asrt( $listStr, 'article 7' ); + + $subArticles = $sub2->xownArticleList; + foreach( $subArticles as $subArticle ) { + if ( $subArticle->name === 'article 4' ) { + $sub4 = $subArticle; + } + if ( $subArticle->name === 'article 5' ) { + $sub5 = $subArticle; + } + } + + asrt( count( $sub4->xownArticleList ), 1 ); + $subBeans = $sub4->xownArticleList; + $subBean = reset( $subBeans ); + asrt( $subBean->name, 'article 6'); + + asrt( count( $sub5->xownArticleList ), 0 ); + + $dupArticle2 = $dupArticle2->fresh(); + $subArticles = $dupArticle2->xownArticleList; + $list = array(); + foreach( $subArticles as $subArticle ) { + $list[] = $subArticle->name; + } + sort( $list ); + $listStr = implode( ',', $list ); + asrt( $listStr, 'article 4,article 5' ); + + foreach( $subArticles as $subArticle ) { + if ( $subArticle->name === 'article 4' ) { + $sub4 = $subArticle; + } + if ( $subArticle->name === 'article 5' ) { + $sub5 = $subArticle; + } + } + + asrt( count( $sub4->xownArticleList ), 1 ); + $subBeans = $sub4->xownArticleList; + $subBean = reset( $subBeans ); + asrt( $subBean->name, 'article 6'); + + asrt( count( $sub5->xownArticleList ), 0 ); + } + + /** + * Test exportAll and caching. + * + * @return void + */ + public function testExportAllAndCache() + { + testpack( 'exportAll() and Cache' ); + + $can = R::dispense( 'can' )->setAttr( 'size', 3 ); + + $can->ownCoffee[] = R::dispense( 'coffee' )->setAttr( 'color', 'black' ); + $can->sharedTag[] = R::dispense( 'tag' )->setAttr( 'name', 'cool' ); + + $id = R::store( $can ); + + R::debug( TRUE ); + + ob_start(); + + $can = R::load( 'can', $id ); + + $cache = $this->getCache(); + + $data = R::exportAll( array( $can ), TRUE ); + + $queries = ob_get_contents(); + + R::debug( FALSE ); + ob_end_clean(); + $len1 = strlen( $queries ); + + $can = R::dispense( 'can' )->setAttr( 'size', 3 ); + $can->ownCoffee[] = R::dispense( 'coffee' )->setAttr( 'color', 'black' ); + $can->sharedTag[] = R::dispense( 'tag' )->setAttr( 'name', 'cool' ); + + $id = R::store( $can ); + + R::debug( TRUE ); + + ob_start(); + + $can = R::load( 'can', $id ); + + $cache = $this->getCache(); + + $data = R::exportAll( array( $can ), TRUE ); + + $queries = ob_get_contents(); + + R::debug( FALSE ); + + ob_end_clean(); + + $len2 = strlen( $queries ); + + asrt( ( $len1 ), ( $len2 ) ); + + $can = R::dispense( 'can' )->setAttr( 'size', 3 ); + + $can->ownCoffee[] = R::dispense( 'coffee' )->setAttr( 'color', 'black' ); + $can->sharedTag[] = R::dispense( 'tag' )->setAttr( 'name', 'cool' ); + + $id = R::store( $can ); + + R::debug( TRUE ); + + ob_start(); + + $can = R::load( 'can', $id ); + + $cache = $this->getCache(); + + R::getDuplicationManager()->setTables( $cache ); + + $data = R::exportAll( array( $can ), TRUE ); + + $queries = ob_get_contents(); + + R::debug( FALSE ); + + ob_end_clean(); + + $len3 = strlen( $queries ); + + asrt( ( ( $len3 ) < ( $len2 ) ), TRUE ); + asrt( count( $data ), 1 ); + asrt( $data[0]['ownCoffee'][0]['color'], 'black' ); + + R::getDuplicationManager()->setCacheTables( FALSE ); + } + + /** + * Test duplication and caching. + * + * @return void + */ + public function DupAndCache() + { + testpack( 'Dup() and Cache' ); + + $can = R::dispense( 'can' )->setAttr( 'size', 3 ); + + $can->ownCoffee[] = R::dispense( 'coffee' )->setAttr( 'color', 'black' ); + $can->sharedTag[] = R::dispense( 'tag' )->setAttr( 'name', 'cool' ); + + $can = R::load( 'can', R::store( $can ) ); + + $d = new DuplicationManager( R::getToolBox() ); + + $d->setCacheTables( TRUE ); + + ob_start(); + + R::debug( 1 ); + + $x = $d->dup( $can ); + + $queries = ob_get_contents(); + + R::debug( 0 ); + + ob_end_clean(); + + $len1 = strlen( $queries ); + + asrt( ( $len1 > 40 ), TRUE ); + asrt( isset( $x->ownCoffee ), TRUE ); + asrt( count( $x->ownCoffee ), 1 ); + asrt( isset( $x->sharedTag ), TRUE ); + asrt( count( $x->sharedTag ), 1 ); + + $cache = $d->getSchema(); + + R::nuke(); + + $can = R::dispense( 'can' )->setAttr( 'size', 3 ); + + $can->ownCoffee[] = R::dispense( 'coffee' )->setAttr( 'color', 'black' ); + $can->sharedTag[] = R::dispense( 'tag' )->setAttr( 'name', 'cool' ); + + $can = R::load( 'can', R::store( $can ) ); + + $d = new DuplicationManager( R::getToolBox() ); + + /** + * $cache = '{"book": { + * "id": "INTEGER", + * "title": "TEXT" + * }, "bean": { + * "id": "INTEGER", + * "prop": "INTEGER" + * }, "pessoa": { + * "id": "INTEGER", + * "nome": "TEXT", + * "nome_meio": "TEXT", + * "sobrenome": "TEXT", + * "nascimento": "NUMERIC", + * "reg_owner": "TEXT" + * }, "documento": { + * "id": "INTEGER", + * "nome_documento": "TEXT", + * "numero_documento": "TEXT", + * "reg_owner": "TEXT", + * "ownPessoa_id": "INTEGER" + * }, "can": { + * "id": "INTEGER", + * "size": "INTEGER" + * }, "coffee": { + * "id": "INTEGER", + * "color": "TEXT", + * "can_id": "INTEGER" + * }, "tag": { + * "id": "INTEGER", + * "name": "TEXT" + * }, "can_tag": { + * "id": "INTEGER", + * "tag_id": "INTEGER", + * "can_id": "INTEGER" + * }}' + */ + + $d->setTables( $cache ); + + ob_start(); + + R::debug( 1 ); + + $x = $d->dup( $can ); + + $queries = ob_get_contents(); + + ob_end_clean(); + + R::debug( 0 ); + + $len2 = strlen( $queries ); + + asrt( isset( $x->ownCoffee ), TRUE ); + asrt( count( $x->ownCoffee ), 1 ); + asrt( isset( $x->sharedTag ), TRUE ); + asrt( count( $x->sharedTag ), 1 ); + asrt( json_encode( $cache ), json_encode( $d->getSchema() ) ); + asrt( ( $len1 > $len2 ), TRUE ); + } + + /** + * Test duplication and tainting. + * + * @return void + */ + public function testDupAndExportNonTainting() + { + testpack( 'Dup() and Export() should not taint beans' ); + + $p = R::dispense( 'page' ); + $b = R::dispense( 'book' ); + + $b->ownPage[] = $p; + $b->title = 'a'; + + $id = R::store( $b ); + + $b = R::load( 'book', $id ); + + asrt( ( !$b->getMeta( 'tainted' ) ), TRUE ); + + R::exportAll( $b ); + + asrt( ( !$b->getMeta( 'tainted' ) ), TRUE ); + + R::dup( $b ); + + asrt( ( !$b->getMeta( 'tainted' ) ), TRUE ); + + testpack( 'Test issue with ownItems and stealing Ids.' ); + + R::nuke(); + $bill = R::dispense( 'bill' ); + $item = R::dispense( 'item' ); + $element = R::dispense( 'element' ); + $bill->ownItem[] = $item; + $bill->sharedElement[] = $element; + R::store( $bill ); + $bill = R::load( 'bill', 1 ); + $bill->ownItem; + $bill->sharedElement; + $copy = R::dup( $bill ); + R::store( $copy ); + + $rows = ( R::getAll( 'select * from bill_element' ) ); + asrt( count( $rows ), 2 ); + + $rows = ( R::getAll( 'select * from item' ) ); + + foreach ( $rows as $row ) { + asrt( ( $row['bill_id'] > 0 ), TRUE ); + } + + R::nuke(); + + $this->runOnce(); + + R::freeze( TRUE ); + + $this->runOnce( FALSE ); + + R::freeze( FALSE ); + } + + /** + * Test exporting with filters. + * + * @return void + */ + public function ExportWithFilters() + { + testpack( 'Export with filters' ); + + $book = R::dispense( 'book' ); + $pages = R::dispense( 'page', 2 ); + $texts = R::dispense( 'text', 2 ); + $images = R::dispense( 'image', 2 ); + $author = R::dispense( 'author' ); + $pub = R::dispense( 'publisher' ); + $bookmarks = R::dispense( 'bookmark', 2 ); + + $pages[0]->ownText = array( $texts[0] ); + $pages[0]->ownImage = array( $images[0] ); + $pages[1]->ownText = array( $texts[1] ); + $pages[1]->ownImage = array( $images[1] ); + + $pages[0]->sharedBookmark[] = $bookmarks[0]; + $pages[1]->sharedBookmark[] = $bookmarks[1]; + + $bookmarks[0]->ownNote[] = R::dispense( 'note' )->setAttr( 'text', 'a note' ); + $bookmarks[1]->ownNote[] = R::dispense( 'note' )->setAttr( 'text', 'a note' ); + + $book->ownPage = $pages; + $book->author = $author; + + $author->publisher = $pub; + $bookID = R::store( $book ); + + R::getDuplicationManager()->setTables( R::getWriter()->getTables() ); + + $objects = ( R::exportAll( array( $book ), TRUE, array() ) ); + + asrt( isset( $objects[0]['ownPage'] ), TRUE ); + asrt( count( $objects[0]['ownPage'] ), 2 ); + asrt( isset( $objects[0]['author'] ), TRUE ); + asrt( isset( $objects[0]['ownPage'][0]['ownText'] ), TRUE ); + asrt( count( $objects[0]['ownPage'][0]['ownText'] ), 1 ); + asrt( isset( $objects[0]['ownPage'][0]['ownImage'] ), TRUE ); + asrt( count( $objects[0]['ownPage'][0]['ownImage'] ), 1 ); + + $objects = ( R::exportAll( array( $book ), TRUE, array( 'page', 'author', 'text', 'image' ) ) ); + + asrt( isset( $objects[0]['ownPage'] ), TRUE ); + asrt( count( $objects[0]['ownPage'] ), 2 ); + asrt( isset( $objects[0]['author'] ), TRUE ); + asrt( isset( $objects[0]['ownPage'][0]['ownText'] ), TRUE ); + asrt( count( $objects[0]['ownPage'][0]['ownText'] ), 1 ); + asrt( isset( $objects[0]['ownPage'][0]['ownImage'] ), TRUE ); + asrt( count( $objects[0]['ownPage'][0]['ownImage'] ), 1 ); + + $objects = ( R::exportAll( array( $book ), TRUE, 'author' ) ); + + asrt( isset( $objects[0]['ownPage'] ), FALSE ); + asrt( isset( $objects[0]['ownPage'][0]['ownText'] ), FALSE ); + + $objects = ( R::exportAll( array( $book ), TRUE, array( 'page' ) ) ); + + asrt( isset( $objects[0]['author'] ), FALSE ); + asrt( isset( $objects[0]['ownPage'][0]['ownText'] ), FALSE ); + + $objects = ( R::exportAll( array( $book ), TRUE, array( 'page', 'text' ) ) ); + + asrt( isset( $objects[0]['author'] ), FALSE ); + asrt( isset( $objects[0]['ownPage'] ), TRUE ); + asrt( isset( $objects[0]['ownPage'][0]['ownText'] ), TRUE ); + asrt( count( $objects[0]['ownPage'][0]['ownText'] ), 1 ); + asrt( isset( $objects[0]['ownPage'][0]['ownImage'] ), FALSE ); + + $objects = ( R::exportAll( array( $book ), TRUE, array( 'none' ) ) ); + + asrt( isset( $objects[0]['author'] ), FALSE ); + asrt( isset( $objects[0]['ownPage'] ), FALSE ); + + $texts = R::find( 'text' ); + + R::getDuplicationManager()->setCacheTables( FALSE ); + + testpack( 'Keyless export' ); + + $book = R::load( 'book', $bookID ); + + $book->ownPage; + + $export = $book->export(); + + asrt( isset( $export['ownPage'][0] ), TRUE ); + + } + + /** + * Helper function getCache(). + * + * @return array + */ + private function getCache() + { + return array( + 'coffee' => array( + 'color' => 'color', + 'id' => 'id', + 'can_id' => 'can_id' + ), + 'can' => array( + 'size' => 'size', + 'id' => 'id' + ), + 'can_tag' => array( + 'id' => 'id', + 'can_id' => 'can_id', + 'tag_id' => 'tag_id' + ), + 'tag' => array( + 'id' => 'id', + 'name' => 'name' ) + ); + } + + /** + * Compares object with export + * + * @param type $object + * @param type $array + */ + private function compare( $object, $array ) + { + foreach ( $object as $property => $value ) { + if ( is_array( $value ) ) { + foreach ( $value as $index => $nestedObject ) { + if ( $nestedObject->id ) { + $foundMatch = FALSE; + //order might be different + foreach ( $array[$property] as $k => $a ) { + if ( $a['id'] == $nestedObject->id ) { + $foundMatch = TRUE; + $index = $k; + } + } + if ( !$foundMatch ) throw new\Exception( 'failed to find match for object ' . $nestedObject->id ); + } + $this->compare( $nestedObject, $array[$property][$index] ); + } + } elseif ( !is_object( $value ) ) { + asrt( strval( $array[$property] ), strval( $value ) ); + } + } + } + + /** + * Run tests + */ + private function runOnce( $n = TRUE ) + { + + $books = R::dispense( 'book', 10 ); + $pages = R::dispense( 'page', 10 ); + $readers = R::dispense( 'reader', 10 ); + $texts = R::dispense( 'text', 10 ); + + $i = 0; + foreach ( $books as $book ) $book->name = 'book-' . ( $i++ ); + $i = 0; + foreach ( $pages as $page ) $page->name = 'page-' . ( $i++ ); + $i = 0; + foreach ( $readers as $reader ) $reader->name = 'reader-' . ( $i++ ); + $i = 0; + foreach ( $texts as $text ) $text->content = 'lorem ipsum -' . ( $i++ ); + + foreach ( $texts as $text ) { + $pages[array_rand( $pages )]->ownText[] = $text; + } + foreach ( $pages as $page ) { + $books[array_rand( $books )]->ownPage[] = $page; + } + foreach ( $readers as $reader ) { + $books[array_rand( $books )]->sharedReader[] = $reader; + } + $i = $noOfReaders = $noOfPages = $noOfTexts = 0; + foreach ( $books as $key => $book ) { + $i++; + $noOfPages += count( $book->ownPage ); + $noOfReaders += count( $book->sharedReader ); + foreach ( $book->ownPage as $page ) $noOfTexts += count( $page->ownText ); + $arr = R::exportAll( $book ); + echo "\nIntermediate info: " . json_encode( $arr ) . ": Totals = $i,$noOfPages,$noOfReaders,$noOfTexts "; + + $this->compare( $book, $arr[0] ); + $copiedBook = R::dup( $book ); + $copiedBookArray = R::exportAll( $copiedBook ); + $this->compare( $book, $copiedBookArray[0] ); + $copiedBookArrayII = $copiedBook->export(); + $this->compare( $book, $copiedBookArrayII ); + $copyFromCopy = R::dup( $copiedBook ); + $copyFromCopyArray = R::exportAll( $copyFromCopy ); + $this->compare( $book, $copyFromCopyArray[0] ); + $copyFromCopyArrayII = $copyFromCopy->export(); + $this->compare( $book, $copyFromCopyArrayII ); + $id = R::store( $book ); + $copiedBook = R::dup( $book ); + R::store( $book ); //should not be damaged + $copiedBookArray = R::exportAll( $copiedBook ); + $originalBookArray = R::exportAll( $book ); + $this->compare( $copiedBook, $copiedBookArray[0] ); + $this->compare( $book, $originalBookArray[0] ); + $book = R::load( 'book', $id ); + $this->compare( $book, $originalBookArray[0] ); + $copiedBook = R::dup( $book ); + $this->compare( $copiedBook, $copiedBook->export() ); + R::store( $copiedBook ); + $this->compare( $copiedBook, $copiedBook->export() ); + $copyFromCopy = R::dup( $copiedBook ); + $this->compare( $copyFromCopy, $copyFromCopy->export() ); + R::store( $copyFromCopy ); + $newPage = R::dispense( 'page' ); + $newPage->name = 'new'; + $copyFromCopy->ownPage[] = $newPage; + $modifiedCopy = R::dup( $copyFromCopy ); + $exportMod = R::exportAll( $modifiedCopy ); + $this->compare( $modifiedCopy, $exportMod[0] ); + asrt( count( $modifiedCopy->ownPage ), count( $copiedBook->ownPage ) + 1 ); + R::store( $modifiedCopy ); + + if ( $n ) { + asrt( (int) R::getCell( 'SELECT count(*) FROM book' ), $i * 4 ); + asrt( (int) R::getCell( 'SELECT count(*) FROM page' ), ( $noOfPages * 4 ) + $i ); + asrt( (int) R::getCell( 'SELECT count(*) FROM text' ), $noOfTexts * 4 ); + asrt( (int) R::getCell( 'SELECT count(*) FROM book_reader' ), $noOfReaders * 4 ); + asrt( (int) R::getCell( 'SELECT count(*) FROM reader' ), $noOfReaders ); + } + } + + if ( $n ) { + asrt( $noOfTexts, 10 ); + asrt( $noOfReaders, 10 ); + asrt( $noOfPages, 10 ); + asrt( $i, 10 ); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Facade.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Facade.php new file mode 100644 index 000000000..c67edc820 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Facade.php @@ -0,0 +1,138 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + $a = new AssociationManager( $toolbox ); + asrt( R::getRedBean() instanceof OODB, TRUE ); + asrt( R::getToolBox() instanceof ToolBox, TRUE ); + asrt( R::getDatabaseAdapter() instanceof Adapter, TRUE ); + asrt( R::getWriter() instanceof QueryWriter, TRUE ); + $book = R::dispense( "book" ); + asrt( $book instanceof OODBBean, TRUE ); + $book->title = "a nice book"; + $id = R::store( $book ); + asrt( ( $id > 0 ), TRUE ); + $book = R::load( "book", (int) $id ); + asrt( $book->title, "a nice book" ); + asrt( R::load( 'book', 999 )->title, NULL ); + R::freeze( TRUE ); + try { + R::load( 'bookies', 999 ); + fail(); + } catch (\Exception $e ) { + pass(); + } + R::freeze( FALSE ); + $author = R::dispense( "author" ); + $author->name = "me"; + R::store( $author ); + $book9 = R::dispense( "book" ); + $author9 = R::dispense( "author" ); + $author9->name = "mr Nine"; + $a9 = R::store( $author9 ); + $book9->author_id = $a9; + $bk9 = R::store( $book9 ); + $book9 = R::load( "book", $bk9 ); + $author = R::load( "author", $book9->author_id ); + asrt( $author->name, "mr Nine" ); + R::trash( $author ); + R::trash( $book9 ); + pass(); + $book2 = R::dispense( "book" ); + $book2->title = "second"; + R::store( $book2 ); + $book3 = R::dispense( "book" ); + $book3->title = "third"; + R::store( $book3 ); + asrt( count( R::find( "book" ) ), 3 ); + asrt( count( R::findAll( "book" ) ), 3 ); + asrt( count( R::findAll( "book", " LIMIT 2" ) ), 2 ); + asrt( count( R::find( "book", " id=id " ) ), 3 ); + asrt( count( R::find( "book", " title LIKE ?", array( "third" ) ) ), 1 ); + asrt( count( R::find( "book", " title LIKE ?", array( "%d%" ) ) ), 2 ); + // Find without where clause + asrt( count( R::findAll( 'book', ' order by id' ) ), 3 ); + R::trash( $book3 ); + R::trash( $book2 ); + asrt( count( R::getAll( "SELECT * FROM book " ) ), 1 ); + asrt( count( R::getCol( "SELECT title FROM book " ) ), 1 ); + asrt( (int) R::getCell( "SELECT 123 " ), 123 ); + $book = R::dispense( "book" ); + $book->title = "not so original title"; + $author = R::dispense( "author" ); + $author->name = "Bobby"; + R::store( $book ); + $aid = R::store( $author ); + $author = R::findOne( "author", " name = ? ", array( "Bobby" ) ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Finding.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Finding.php new file mode 100644 index 000000000..1765dcd61 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Finding.php @@ -0,0 +1,861 @@ +color; + if ( !$noSort) sort( $colors ); + return implode( ',', $colors ); + } + + /** + * Inserts data for findMulti-tests. + * + * @return void + */ + private function insertBookData() + { + list( $books, $pages, $texts, $categories ) = R::dispenseAll( 'book*5,page*25,text*60,category*3' ); + $texts[0]->content = 'C is a beautiful language.'; + $texts[1]->content = 'But also a bit dangerous.'; + $texts[2]->content = 'You need to know what you are doing.'; + $texts[3]->content = 'Javascript is very flexible.'; + $texts[4]->content = 'It can be anything you want...'; + $texts[5]->content = 'But it can lead to chaos.'; + $texts[6]->content = 'CSS was meant for documents'; + $texts[7]->content = 'Now we use it for applications...'; + $texts[8]->content = 'PHP is an easy language to learn,'; + $texts[9]->content = 'Maybe a bit too easy...'; + $texts[10]->content = 'SQL is much more powerful than you think.'; + $pages[0]->ownTextList = array( $texts[0], $texts[1] ); + $pages[1]->ownTextList = array( $texts[2] ); + $pages[2]->ownTextList = array( $texts[3] ); + $pages[3]->ownTextList = array( $texts[4] ); + $pages[4]->ownTextList = array( $texts[5] ); + $pages[5]->ownTextList = array( $texts[6], $texts[7] ); + $pages[6]->ownTextList = array( $texts[8] ); + $pages[7]->ownTextList = array( $texts[9] ); + $pages[8]->ownTextList = array( $texts[10] ); + $books[0]->ownPageList = array( $pages[0], $pages[1] ); + $books[1]->ownPageList = array( $pages[2], $pages[3], $pages[4] ); + $books[2]->ownPageList = array( $pages[5] ); + $books[3]->ownPageList = array( $pages[6], $pages[7] ); + $books[4]->ownPageList = array( $pages[8] ); + $books[0]->title = 'Diehard C'; + $books[1]->title = 'Adventures in JavaScript'; + $books[2]->title = 'CSS ala Picasso'; + $books[3]->title = 'PHP Tips and Tricks'; + $books[4]->title = 'Secrets of SQL'; + $categories[0]->name = 'Programming'; + $categories[1]->name = 'Design'; + $categories[2]->name = 'Web Development'; + $books[0]->sharedCategoryList = array( $categories[0] ); + $books[1]->sharedCategoryList = array( $categories[0], $categories[2] ); + $books[2]->sharedCategoryList = array( $categories[0], $categories[2], $categories[1] ); + $books[3]->sharedCategoryList = array( $categories[0], $categories[2] ); + $books[4]->sharedCategoryList = array( $categories[0], $categories[2] ); + R::storeAll( $books ); + } + + /** + * A custom record-to-bean mapping function for findMulti test. + * + * @param string $parentName name of the parent bean + * @param string $childName name of the child bean + * + * @return array + */ + private function map($parentName,$childName) { + return array( + 'a' => $parentName, + 'b' => $childName, + 'matcher' => function( $parent, $child ) use ( $parentName ) { + $property = "{$parentName}ID"; + return ( $child->$property == $parent->id ); + }, + 'do' => function( $parent, $child ) use ( $childName ) { + $list = 'own'.ucfirst( $childName ).'List'; + $parent->noLoad()->{$list}[] = $child; + } + ); + } + + /** + * FindMulti should not throw errors in case of + * a record-type mismatch. + * + * @return void + */ + public function testFindMultiErrorHandling() + { + $result = R::findMulti('a,b', array()); + asrt( is_array( $result ), TRUE ); + asrt( count( $result ), 2 ); + asrt( isset( $result['a'] ), TRUE ); + asrt( isset( $result['b'] ), TRUE ); + asrt( is_array( $result['a'] ), TRUE ); + asrt( is_array( $result['b'] ), TRUE ); + asrt( count( $result['a'] ), 0 ); + asrt( count( $result['b'] ), 0 ); + pass(); + $result = R::findMulti( 'book', array( + array( 'book__title' => 'The missing ID.' ) + ) ); + asrt( is_array( $result ), TRUE ); + asrt( count( $result ), 1 ); + asrt( isset( $result['book'] ), TRUE ); + asrt( is_array( $result['book'] ), TRUE ); + asrt( count( $result['book'] ), 0 ); + pass(); + } + + /** + * You can build your own mapping functions to remap records to bean. + * Just like the preloader once did. However now you can define the + * mapping yourself using closures. This test verifies that such a + * function would actually work. + * + * This method also tests whether empty records (resulting from LEFT JOINS for + * instance) do not produce unnecessary, empty beans. + * + * @return void + */ + public function testFindMultiExtFunc() + { + R::nuke(); + $shop = R::dispense( 'shop' ); + $shop2 = R::dispense( 'shop' ); + $products = R::dispense( 'product', 3 ); + $price = R::dispense( 'price' ); + $price->tag = 5; + $products[0]->name = 'vase'; + $products[1]->name = 'candle'; + $products[2]->name = 'plate'; + $products[1]->ownPriceList[] = $price; + $shop->ownProduct[] = $products[0]; + $shop->ownProduct[] = $products[1]; + $shop2->ownProduct[] = $products[2]; + R::storeAll( array( $shop, $shop2 ) ); + $collection = R::findMulti( 'shop,product,price', ' + SELECT shop.*, product.*, price.* FROM shop + LEFT JOIN product ON product.shop_id = shop.id + LEFT JOIN price ON price.product_id = product.id + ', array(), array( + '0' => $this->map( 'shop', 'product' ), + '1' => $this->map( 'product', 'price' ), + )); + asrt( is_array( $collection ), TRUE ); + asrt( count( $collection ), 3 ); + asrt( count( $collection['shop'] ), 2 ); + asrt( count( $collection['product'] ), 3 ); + asrt( count( $collection['price'] ), 1 ); + $shop = reset( $collection['shop'] ); + asrt( count( $shop->ownProductList ), 2 ); + $shop2 = next( $collection['shop'] ); + asrt( count( $shop2->ownProductList ), 1 ); + $candle = NULL; + foreach( $shop->ownProduct as $product ) { + if ( $product->name == 'candle' ) { + $candle = $product; + } + } + asrt( is_null( $candle ), FALSE ); + asrt( count( $candle->ownPrice ), 1 ); + asrt( $candle->name, 'candle' ); + $price = reset( $candle->ownPrice ); + asrt( (int) $price->tag, 5 ); + } + + /** + * Test findMuli with self-made arrays. + * + * @return void + */ + public function testFindMultiDirectArray() + { + R::nuke(); + $collection = R::findMulti( 'shop,product', array( + array( 'shop__id' => 1, 'product__id' => 1, 'product__name' => 'vase', 'product__shop_id' => 1 ), + array( 'shop__id' => 1, 'product__id' => 2, 'product__name' => 'candle', 'product__shop_id' => 1 ), + array( 'shop__id' => 1, 'product__id' => 3, 'product__name' => 'plate', 'product__shop_id' => 1 ), + ) ); + asrt( is_array( $collection ), TRUE ); + asrt( isset( $collection['shop'] ), TRUE ); + asrt( isset( $collection['product'] ), TRUE ); + asrt( (int) $collection['shop'][1]->id, 1 ); + asrt( (int) $collection['product'][1]->id, 1 ); + asrt( (int) $collection['product'][2]->id, 2 ); + asrt( (int) $collection['product'][3]->id, 3 ); + asrt( (int) $collection['product'][1]->shopID, 1 ); + asrt( (int) $collection['product'][2]->shopID, 1 ); + asrt( (int) $collection['product'][3]->shopID, 1 ); + asrt( $collection['product'][1]->name, 'vase' ); + asrt( $collection['product'][2]->name, 'candle' ); + asrt( $collection['product'][3]->name, 'plate' ); + R::nuke(); + $shop = R::dispense('shop'); + $shop2 = R::dispense('shop'); + $products = R::dispense('product', 3); + $price = R::dispense('price'); + $price->tag = 5; + $products[0]->name = 'vase'; + $products[1]->name = 'candle'; + $products[2]->name = 'plate'; + $products[1]->ownPriceList[] = $price; + $shop->ownProduct = $products; + R::store($shop); + $collection = R::findMulti('shop,product,price', ' + SELECT shop.*, product.*, price.* FROM shop + LEFT JOIN product ON product.shop_id = shop.id + LEFT JOIN price ON price.product_id = product.id + ', array(), array( + '0' => $this->map('shop', 'product'), + '1' => $this->map('product', 'price'), + )); + $collection = R::findMulti( 'shop,product', array( + array( 'shop__id' => 1, 'product__id' => 1, 'product__name' => 'vase', 'product__shop_id' => 1 ), + array( 'shop__id' => 1, 'product__id' => 2, 'product__name' => 'candle', 'product__shop_id' => 1 ), + array( 'shop__id' => 1, 'product__id' => 3, 'product__name' => 'plate', 'product__shop_id' => 1 ), + array( 'shop__id' => 1, 'product__id' => 2, 'product__name' => 'candle', 'product__shop_id' => 1) + ), array(), array( + array( + 'a' => 'shop', + 'b' => 'product', + 'matcher' => function( $a, $b ) { return ( $b->shopID == $a->id ); }, + 'do' => function( $a, $b ) { return $a->noLoad()->ownProductList[] = $b; } + ) + ) ); + asrt( is_array( $collection ), TRUE ); + asrt( isset( $collection['shop'] ), TRUE ); + asrt( isset( $collection['product'] ), TRUE ); + asrt( (int) $collection['shop'][1]->id, 1 ); + asrt( (int) $collection['product'][1]->id, 1 ); + asrt( (int) $collection['product'][2]->id, 2 ); + asrt( (int) $collection['product'][3]->id, 3 ); + asrt( (int) $collection['product'][1]->shopID, 1 ); + asrt( (int) $collection['product'][2]->shopID, 1 ); + asrt( (int) $collection['product'][3]->shopID, 1 ); + asrt( $collection['product'][1]->name, 'vase' ); + asrt( $collection['product'][2]->name, 'candle' ); + asrt( $collection['product'][3]->name, 'plate' ); + asrt( isset( $collection['shop'][1]->ownProductList ), TRUE ); + asrt( is_array( $collection['shop'][1]->ownProductList ), TRUE ); + asrt( count( $collection['shop'][1]->ownProductList ), 3 ); + asrt( $collection['shop'][1]->ownProductList[0]->name, 'vase' ); + asrt( $collection['shop'][1]->ownProductList[1]->name, 'candle' ); + asrt( $collection['shop'][1]->ownProductList[2]->name, 'plate' ); + } + + /** + * Test findMulti() with manual crafted fields. + * + * @return void + */ + public function testFindMultiDIY() + { + R::nuke(); + $movie = R::dispense( 'movie' ); + $review = R::dispense( 'review' ); + $movie->ownReviewList[] = $review; + $review->stars = 5; + $movie->title = 'Gambit'; + R::store( $movie ); + $stuff = R::findMulti( 'movie,review', 'SELECT + movie.id AS movie__id, + movie.title AS movie__title, + review.id AS review__id, + review.stars AS review__stars, + review.movie_id AS review__movie_id + FROM movie + LEFT JOIN review ON review.movie_id = movie.id + ' ); + asrt( count( $stuff ), 2 ); + asrt( isset( $stuff['movie'] ), TRUE ); + asrt( isset( $stuff['review'] ), TRUE ); + asrt( is_array( $stuff['movie'] ), TRUE ); + asrt( is_array( $stuff['review'] ), TRUE ); + asrt( count( $stuff['movie'] ), 1 ); + asrt( count( $stuff['review'] ), 1 ); + $movie = reset( $stuff['movie'] ); + asrt( $movie->title, 'Gambit' ); + $review = reset( $stuff['review'] ); + asrt( (int) $review->stars, 5 ); + R::nuke(); + $movie = R::dispense( 'movie' ); + $review = R::dispense( 'review' ); + $movie->ownReviewList[] = $review; + $review->stars = 5; + $movie->title = 'Gambit'; + R::store( $movie ); + $stuff = R::findMulti( array( 'movie', 'review' ), 'SELECT + movie.id AS movie__id, + movie.title AS movie__title, + review.id AS review__id, + review.stars AS review__stars, + review.movie_id AS review__movie_id + FROM movie + LEFT JOIN review ON review.movie_id = movie.id + ' ); + asrt( count( $stuff ), 2 ); + asrt( isset( $stuff['movie'] ), TRUE ); + asrt( isset( $stuff['review'] ), TRUE ); + asrt( is_array( $stuff['movie'] ), TRUE ); + asrt( is_array( $stuff['review'] ), TRUE ); + asrt( count( $stuff['movie'] ), 1 ); + asrt( count( $stuff['review'] ), 1 ); + $movie = reset( $stuff['movie'] ); + asrt( $movie->title, 'Gambit' ); + $review = reset( $stuff['review'] ); + asrt( (int) $review->stars, 5 ); + } + + /** + * Test findMulti(). Basic version. + * + * @return void + */ + public function testFindMulti() + { + $book = R::dispense( 'book' ); + $book->title = 'My Book'; + $book->ownPageList = R::dispense( 'page', 3 ); + $no = 1; + foreach( $book->ownPageList as $page ) { + $page->num = $no++; + } + R::store( $book ); + $collection = R::findMulti( 'book,page', ' + SELECT book.*, page.* FROM book + LEFT JOIN page ON page.book_id = book.id + ' ); + asrt( count( $collection ), 2 ); + asrt( isset( $collection['book'] ), TRUE ); + asrt( isset( $collection['page'] ), TRUE ); + asrt( count( $collection['book'] ), 1 ); + asrt( count( $collection['page'] ), 3 ); + foreach( $collection['book'] as $bean ) asrt( ( $bean instanceof OODBBean ), TRUE ); + foreach( $collection['page'] as $bean ) asrt( ( $bean instanceof OODBBean ), TRUE ); + $book = reset( $collection['book'] ); + asrt( $book->title, 'My Book' ); + $no = 1; + foreach( $collection['page'] as $page ) asrt( (int) $page->num, $no++ ); + R::nuke(); + $book->noLoad()->ownPageList = $collection['page']; + asrt( count( $book->ownPageList ), 3 ); + } + + /** + * Tests the complex use case for findMulti(). + * + * @return void + */ + public function testMultiAdvanced() + { + $this->insertBookData(); + $collection = R::findMulti( 'book,page,text,category', ' + SELECT book.*, page.*, text.*, category.* + FROM book + LEFT JOIN page ON page.book_id = book.id + LEFT JOIN text ON text.page_id = page.id + LEFT JOIN book_category ON book_category.book_id = book.id + LEFT JOIN category ON book_category.category_id = category.id + ' ); + asrt( count( $collection ), 4 ); + asrt( isset( $collection['book'] ), TRUE ); + asrt( isset( $collection['page'] ), TRUE ); + asrt( isset( $collection['text'] ), TRUE ); + asrt( isset( $collection['category'] ), TRUE ); + asrt( count( $collection['book'] ), 5 ); + asrt( count( $collection['page'] ), 9 ); + asrt( count( $collection['text'] ), 11 ); + asrt( count( $collection['category'] ), 3 ); + foreach( $collection['book'] as $bean ) asrt( ( $bean instanceof OODBBean ), TRUE ); + foreach( $collection['page'] as $bean ) asrt( ( $bean instanceof OODBBean ), TRUE ); + foreach( $collection['text'] as $bean ) asrt( ( $bean instanceof OODBBean ), TRUE ); + foreach( $collection['category'] as $bean ) asrt( ( $bean instanceof OODBBean ), TRUE ); + foreach( $collection['book'] as $book ) $titles[] = $book->title; + asrt( in_array( 'Diehard C', $titles ), TRUE ); + asrt( in_array( 'Adventures in JavaScript', $titles ), TRUE ); + asrt( in_array( 'CSS ala Picasso', $titles ), TRUE ); + asrt( in_array( 'PHP Tips and Tricks', $titles ), TRUE ); + asrt( in_array( 'Secrets of SQL', $titles ), TRUE ); + $collection = R::findMulti( 'book,page,text,category,book_category', ' + SELECT book.*, page.*, text.*, category.*, book_category.* + FROM book + LEFT JOIN page ON page.book_id = book.id + LEFT JOIN text ON text.page_id = page.id + LEFT JOIN book_category ON book_category.book_id = book.id + LEFT JOIN category ON book_category.category_id = category.id + WHERE category_id > ? + ORDER BY book.title ASC + ', array( 0 ), array( + array( + 'b'=>'page', + 'a'=>'text', + 'do' => function( $a, $b ) { + $b->noLoad()->ownTextList[] = $a; + $b->clearHistory(); + }, + 'matcher' => function( $a, $b ){ return ($a->page_id == $b->id); } + ), + array( + 'b'=>'book', + 'a'=>'page', + 'do' => function( $a, $b ) { + $b->noLoad()->ownPageList[] = $a; + $b->clearHistory(); + }, + 'matcher' => function( $a, $b ){ return ($a->book_id == $b->id); } + ), + array( + 'b' => 'category', + 'a' => 'book', + 'do' => function($a, $b) { + $a->noLoad()->sharedCategoryList[] = $b; + $a->clearHistory(); + }, + 'matcher' => function( $a, $b, $beans ) { + foreach( $beans['book_category'] as $bean ) { + if ( $bean->book_id == $a->id && $bean->category_id == $b->id ) return TRUE; + } + return FALSE; + } + ), + ) + ); + $books = $collection['book']; + $book = reset( $books ); + asrt( $book->title, 'Adventures in JavaScript' ); + R::nuke(); + asrt( count( $book->ownPageList ), 3 ); + $page = reset( $book->ownPageList ); + asrt( count( $page->ownTextList ), 1 ); + asrt( count( $book->sharedCategoryList ), 2); + $categories = array(); + foreach( $book->sharedCategoryList as $category ) { + $categories[] = $category->name; + } + sort( $categories ); + asrt( implode( ',', $categories ), 'Programming,Web Development' ); + $book = next( $books ); + asrt( $book->title, 'CSS ala Picasso' ); + asrt( count( $book->ownPage ), 1 ); + $page = reset( $book->ownPage ); + asrt( count( $page->ownTextList ), 2 ); + $texts = array(); + foreach( $page->ownTextList as $text ) $texts[] = $text->content; + asrt( in_array( 'Now we use it for applications...', $texts ), TRUE ); + $categories = array(); + foreach( $book->sharedCategoryList as $category ) { + $categories[] = $category->name; + } + sort( $categories ); + asrt( implode( ',', $categories ), 'Design,Programming,Web Development' ); + $book = next( $books ); + asrt( $book->title, 'Diehard C' ); + asrt( count( $book->ownPageList ), 2 ); + $page = reset( $book->ownPageList ); + asrt( count( $page->ownTextList ), 2 ); + $page = next( $book->ownPageList ); + asrt( count( $page->ownTextList ), 1 ); + $categories = array(); + foreach( $book->sharedCategoryList as $category ) { + $categories[] = $category->name; + } + sort( $categories ); + asrt( implode( ',', $categories ), 'Programming' ); + //should have no effect, nothing should have changed + R::storeAll($books); + asrt( R::count('book'), 0 ); + asrt( R::count('page'), 0 ); + asrt( R::count('text'), 0 ); + } + + /** + * Test forming IN-clause using genSlots and flat. + * + * @return void + */ + public function testINClause() + { + list( $flowers, $shop ) = R::dispenseAll( 'flower*4,shop' ); + $flowers[0]->color = 'red'; + $flowers[1]->color = 'yellow'; + $flowers[2]->color = 'blue'; + $flowers[3]->color = 'purple'; + $flowers[0]->price = 10; + $flowers[1]->price = 15; + $flowers[2]->price = 20; + $flowers[3]->price = 25; + $shop->xownFlowerList = $flowers; + R::store( $shop ); + $colors = array( 'red', 'yellow' ); + $result = $this->getColors( R::find( 'flower', ' color IN ('.R::genSlots( $colors ).' ) AND price < ?' , R::flat( array( $colors, 100 ) ) ) ); + asrt( $result, 'red,yellow' ); + $colors = array( 'red', 'yellow' ); + $result = $this->getColors( R::find( 'flower', ' color IN ('.R::genSlots( $colors ).' ) AND price < ?' , R::flat( array( $colors, 10 ) ) ) ); + asrt( $result, '' ); + $colors = array( 'red', 'yellow' ); + $result = $this->getColors( R::find( 'flower', ' color IN ('.R::genSlots( $colors ).' ) AND price < ?' , R::flat( array( $colors, 15 ) ) ) ); + asrt( $result, 'red' ); + asrt( json_encode( R::flat( array( 'a', 'b', 'c' ) ) ), '["a","b","c"]' ); + asrt( json_encode( R::flat( array( 'a', array( 'b' ), 'c' ) ) ), '["a","b","c"]' ); + asrt( json_encode( R::flat( array( 'a', array( 'b', array( 'c' ) ) ) ) ), '["a","b","c"]' ); + asrt( json_encode( R::flat( array( array( 'a', array( 'b', array( array( 'c' ) ) ) ) ) ) ), '["a","b","c"]' ); + asrt( json_encode( R::flat( array( 'a', 'b', 'c', array() ) ) ), '["a","b","c"]' ); + asrt( genslots( array( 1, 2 ) ), '?,?' ); + asrt( json_encode( array_flatten( array( array( 'a', array( 'b', array( array( 'c' ) ) ) ) ) ) ), '["a","b","c"]' ); + asrt( genslots( array( 1, 2 ), 'IN (%s) AND' ), 'IN (?,?) AND' ); + asrt( genslots( array(), ' IN (%s) AND ' ), '' ); + $colors = array( 'blue', 'purple', 'red' ); + $flowers = R::find( 'flower', genslots( $colors, ' color IN (%s) AND ' ).' price > ? ', array_flatten( array( $colors, 11 ) ) ); + asrt( $this->getColors( $flowers ), 'blue,purple' ); + $flowers = R::find( 'flower', genslots( array(), ' color IN (%s) AND ' ).' price > ? ', array_flatten( array( array(), 11 ) ) ); + asrt( $this->getColors( $flowers ), 'blue,purple,yellow' ); + $flowers = R::find( 'flower', ' id > 0 AND '.genslots( $colors, ' color IN (%s) AND ' ).' price > ? ', array_flatten( array( $colors, 11 ) ) ); + asrt( $this->getColors( $flowers ), 'blue,purple' ); + $flowers = R::find( 'flower', ' id > 0 AND '.genslots( array(), ' color IN (%s) AND ' ).' price > ? ', array_flatten( array( array(), 11 ) ) ); + asrt( $this->getColors( $flowers ), 'blue,purple,yellow' ); + } + + /** + * Test findLike. + * + * @return void + */ + public function testFindLike2() + { + list( $flowers, $shop ) = R::dispenseAll( 'flower*4,shop' ); + $flowers[0]->color = 'red'; + $flowers[1]->color = 'yellow'; + $flowers[2]->color = 'blue'; + $flowers[3]->color = 'purple'; + $flowers[0]->price = 10; + $flowers[1]->price = 15; + $flowers[2]->price = 20; + $flowers[3]->price = 25; + $shop->xownFlowerList = $flowers; + R::store( $shop ); + asrt( $this->getColors( R::findLike( 'flower', array( 'color' => array( 'red', 'yellow' ) ), ' price < 20' ) ), 'red,yellow' ); + asrt( $this->getColors( R::findLike( 'flower', array( 'color' => array() ), '' ) ), 'blue,purple,red,yellow' ); + asrt( $this->getColors( R::findLike( 'flower', array( 'color' => array() ) ) ), 'blue,purple,red,yellow' ); + asrt( $this->getColors( R::findLike( 'flower', array( 'color' => array('blue') ), ' OR price = 25' ) ), 'blue,purple' ); + asrt( $this->getColors( R::findLike( 'flower', array( 'color' => array() ), ' price < 25' ) ), 'blue,red,yellow' ); + asrt( $this->getColors( R::findLike( 'flower', array( 'color' => array() ), ' price < 20' ) ), 'red,yellow' ); + asrt( $this->getColors( R::findLike( 'flower', array( 'color' => array() ), ' ORDER BY color DESC' ), TRUE ), 'yellow,red,purple,blue' ); + asrt( $this->getColors( R::findLike( 'flower', array( 'color' => array() ), ' ORDER BY color LIMIT 1' ) ), 'blue' ); + asrt( $this->getColors( R::findLike( 'flower', array( 'color' => array( 'yellow', 'blue' ) ), ' ORDER BY color ASC LIMIT 1' ) ), 'blue' ); + } + + /** + * Tests the findOrCreate method. + * + * @return void + */ + public function testFindOrCreate() + { + R::nuke(); + $book = R::findOrCreate( 'book', array( 'title' => 'my book', 'price' => 50 ) ); + asrt( ( $book instanceof OODBBean ), TRUE ); + $id = $book->id; + $book = R::findOrCreate( 'book', array( 'title' => 'my book', 'price' => 50 ) ); + asrt( $book->id, $id ); + asrt( $book->title, 'my book' ); + asrt( (int) $book->price, 50 ); + } + + /** + * Tests the findLike method. + * + * @return void + */ + public function testFindLike() + { + R::nuke(); + $book = R::dispense( array( + '_type' => 'book', + 'title' => 'my book', + 'price' => 80 + ) ); + R::store( $book ); + $book = R::dispense( array( + '_type' => 'book', + 'title' => 'other book', + 'price' => 80 + ) ); + R::store( $book ); + $books = R::findLike( 'book', array( 'price' => 80 ) ); + asrt( count( $books ), 2 ); + foreach( $books as $book ) { + asrt( $book->getMeta( 'type' ), 'book' ); + } + $books = R::findLike( 'book' ); + asrt( count( $books ), 2 ); + $books = R::findLike( 'book', array( 'title' => 'my book' ) ); + asrt( count( $books ), 1 ); + $books = R::findLike( 'book', array( 'title' => array( 'my book', 'other book' ) ) ); + asrt( count( $books ), 2 ); + $books = R::findLike( 'book', array( 'title' => 'strange book') ); + asrt( is_array( $books ), TRUE ); + asrt( count( $books ), 0 ); + $books = R::findLike( 'magazine' ); + asrt( is_array( $books ), TRUE ); + asrt( count( $books ), 0 ); + } + + /** + * Test whether findOne gets a LIMIT 1 + * clause. + * + * @return void + */ + public function testFindOneLimitOne() + { + R::nuke(); + list( $book1, $book2 ) = R::dispense( 'book', 2 ); + $book1->title = 'a'; + $book2->title = 'b'; + R::storeAll( array( $book1, $book2 ) ); + $logger = R::debug( 1, 1 ); + $logger->clear(); + $found = R::findOne( 'book' ); + asrt( count( $logger->grep('LIMIT 1') ), 1 ); + asrt( ( $found instanceof \RedBeanPHP\OODBBean ), TRUE ); + $logger->clear(); + $found = R::findOne( 'book', ' title = ? ', array( 'a' ) ); + asrt( count( $logger->grep('LIMIT 1') ), 1 ); + asrt( ( $found instanceof \RedBeanPHP\OODBBean ), TRUE ); + $logger->clear(); + $found = R::findOne( 'book', ' title = ? LIMIT 1', array( 'b' ) ); + asrt( count( $logger->grep('LIMIT 1') ), 1 ); + $logger->clear(); + $found = R::findOne( 'book', ' title = ? limit 1', array( 'b' ) ); + asrt( count( $logger->grep('LIMIT 1') ), 0 ); + asrt( count( $logger->grep('limit 1') ), 1 ); + asrt( ( $found instanceof \RedBeanPHP\OODBBean ), TRUE ); + $found = R::findOne( 'book', ' title = ? LIMIT 2', array( 'b' ) ); + asrt( count( $logger->grep('LIMIT 2') ), 1 ); + asrt( ( $found instanceof \RedBeanPHP\OODBBean ), TRUE ); + } + + /** + * Begin testing. + * This method runs the actual test pack. + * + * @return void + */ + public function testFinding() + { + $toolbox = R::getToolBox(); + $adapter = $toolbox->getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + $a = new AssociationManager( $toolbox ); + $page = $redbean->dispense( "page" ); + $page->name = "John's page"; + $idpage = $redbean->store( $page ); + $page2 = $redbean->dispense( "page" ); + $page2->name = "John's second page"; + $idpage2 = $redbean->store( $page2 ); + $a->associate( $page, $page2 ); + $pageOne = $redbean->dispense( "page" ); + $pageOne->name = "one"; + $pageMore = $redbean->dispense( "page" ); + $pageMore->name = "more"; + $pageEvenMore = $redbean->dispense( "page" ); + $pageEvenMore->name = "evenmore"; + $pageOther = $redbean->dispense( "page" ); + $pageOther->name = "othermore"; + set1toNAssoc( $a, $pageOther, $pageMore ); + set1toNAssoc( $a, $pageOne, $pageMore ); + set1toNAssoc( $a, $pageOne, $pageEvenMore ); + asrt( count( $redbean->find( "page", array(), " name LIKE '%more%' ", array() ) ), 3 ); + asrt( count( $redbean->find( "page", array(), " name LIKE :str ", array( ":str" => '%more%' ) ) ), 3 ); + asrt( count( $redbean->find( "page", array(), array( " name LIKE :str ", array( ":str" => '%more%' ) ) ) ), 3 ); + asrt( count( $redbean->find( "page", array(), " name LIKE :str ", array( ":str" => '%mxore%' ) ) ), 0 ); + asrt( count( $redbean->find( "page", array( "id" => array( 2, 3 ) ) ) ), 2 ); + $bean = $redbean->dispense( "wine" ); + $bean->name = "bla"; + for ( $i = 0; $i < 10; $i++ ) { + $redbean->store( $bean ); + } + $redbean->find( "wine", array( "id" => 5 ) ); // Finder:where call OODB::convertToBeans + $bean2 = $redbean->load( "anotherbean", 5 ); + asrt( $bean2->id, 0 ); + $keys = $adapter->getCol( "SELECT id FROM page WHERE " . $writer->esc( 'name' ) . " LIKE '%John%'" ); + asrt( count( $keys ), 2 ); + $pages = $redbean->batch( "page", $keys ); + asrt( count( $pages ), 2 ); + $p = R::findLast( 'page' ); + pass(); + $row = R::getRow( 'select * from page ' ); + asrt( is_array( $row ), TRUE ); + asrt( isset( $row['name'] ), TRUE ); + // Test findAll -- should not throw an exception + asrt( count( R::findAll( 'page' ) ) > 0, TRUE ); + asrt( count( R::findAll( 'page', ' ORDER BY id ' ) ) > 0, TRUE ); + $beans = R::findOrDispense( "page" ); + asrt( count( $beans ), 6 ); + asrt( is_null( R::findLast( 'nothing' ) ), TRUE ); + try { + R::find( 'bean', ' id > 0 ', 'invalid bindings argument' ); + fail(); + } catch ( RedException $exception ) { + pass(); + } + R::nuke(); + $bean = R::findOneOrDispense( 'jellybean' ); + asrt( is_object( $bean ), TRUE ); + } + + /** + * Test tree traversal with searchIn(). + * + * @return void + */ + public function testTreeTraversal() + { + testpack( 'Test Tree Traversal' ); + R::nuke(); + $page = R::dispense( 'page', 10 ); + //Setup the test data for this series of tests + $i = 0; + foreach( $page as $pageItem ) { + $pageItem->name = 'page' . $i; + $pageItem->number = $i; + $i++; + R::store( $pageItem ); + } + $page[0]->ownPage = array( $page[1], $page[2] ); + $page[1]->ownPage = array( $page[3], $page[4] ); + $page[3]->ownPage = array( $page[5] ); + $page[5]->ownPage = array( $page[7] ); + $page[9]->document = $page[8]; + $page[9]->book = R::dispense('book'); + R::store( $page[9] ); + $id = R::store( $page[0] ); + $book = $page[9]->book; + } + + /** + * Test find and export. + * + * @return void + */ + public function testFindAndExport() + { + R::nuke(); + $pages = R::dispense( 'page', 3 ); + $i = 1; + foreach( $pages as $page ) { + $page->pageNumber = $i++; + } + R::storeAll( $pages ); + $pages = R::findAndExport( 'page' ); + asrt( is_array( $pages ), TRUE ); + asrt( isset( $pages[0] ), TRUE ); + asrt( is_array( $pages[0] ), TRUE ); + asrt( count( $pages ), 3 ); + } + + /** + * Test error handling of SQL states. + * + * @return void + */ + public function testFindError() + { + R::freeze( FALSE ); + $page = R::dispense( 'page' ); + $page->title = 'abc'; + R::store( $page ); + //Column does not exist, in fluid mode no error! + try { + R::find( 'page', ' xtitle = ? ', array( 'x' ) ); + pass(); + } catch ( SQL $e ) { + fail(); + } + //Table does not exist, in fluid mode no error! + try { + R::find( 'pagex', ' title = ? ', array( 'x' ) ); + pass(); + } catch ( SQL $e ) { + fail(); + } + //Syntax error, error in fluid mode if possible to infer from SQLSTATE (MySQL/Postgres) + try { + R::find( 'page', ' invalid SQL ' ); + //In SQLite only get HY000 - not very descriptive so suppress more errors in fluid mode then. + if ( + $this->currentlyActiveDriverID === 'sqlite' + || $this->currentlyActiveDriverID === 'CUBRID' ) { + pass(); + } else { + fail(); + } + } catch ( SQL $e ) { + pass(); + } + //Frozen, always error... + R::freeze( TRUE ); + //Column does not exist, in frozen mode error! + try { + R::find( 'page', ' xtitle = ? ', array( 'x' ) ); + fail(); + } catch ( SQL $e ) { + pass(); + } + //Table does not exist, in frozen mode error! + try { + R::find( 'pagex', ' title = ? ', array( 'x' ) ); + fail(); + } catch ( SQL $e ) { + pass(); + } + //Syntax error, in frozen mode error! + try { + R::find( 'page', ' invalid SQL ' ); + fail(); + } catch ( SQL $e ) { + pass(); + } + R::freeze( FALSE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Foreignkeys.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Foreignkeys.php new file mode 100644 index 000000000..c2d28b5ca --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Foreignkeys.php @@ -0,0 +1,439 @@ +cover = $page; + R::store( $book ); + $book = $book->fresh(); + asrt( $book->getMeta('sys.autoresolved.cover'), NULL ); + $book->cover; + asrt( $book->getMeta('sys.autoresolved.cover'), 'page' ); + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->cover = $page; + R::store( $book ); + $book = $book->fresh(); + asrt( $book->getMeta('sys.autoresolved.cover'), NULL ); + $book->fetchAs('page')->cover; + asrt( $book->getMeta('sys.autoresolved.cover'), NULL ); + R::nuke(); + R::aliases( array( 'cover' => 'page' ) ); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->cover = $page; + R::store( $book ); + $book = $book->fresh(); + asrt( $book->getMeta('sys.autoresolved.cover'), NULL ); + $cover = $book->cover; + asrt( ( $cover instanceof OODBBean ), TRUE ); + asrt( $cover->getMeta( 'type' ), 'page' ); + asrt( $book->getMeta('sys.autoresolved.cover'), NULL ); + R::aliases( array() ); + R::nuke(); + R::setAutoResolve( FALSE ); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->cover = $page; + R::store( $book ); + $book = $book->fresh(); + asrt( $book->getMeta('sys.autoresolved.cover'), NULL ); + $book->cover; + asrt( $book->getMeta('sys.autoresolved.cover'), NULL ); + R::setAutoResolve( TRUE ); + } + + /** + * Test whether unique constraints are properly created using + * reflection. + * + * @return void + */ + public function testUniqueInspect() + { + $writer = R::getWriter(); + R::nuke(); + $book = R::dispense( 'book' ); + $category = R::dispense( 'category' ); + $book->sharedCategory[] = $category; + R::store( $book ); + asrt( count( get_uniques_for_type('book_category') ), 1 ); + asrt( are_cols_in_unique( 'book_category', array( 'book_id', 'category_id' ) ), TRUE ); + R::nuke(); + $book = R::dispense( 'book' ); + $category = R::dispense( 'category' ); + $book->via( 'library' )->sharedCategory[] = $category; + R::store( $book ); + asrt( count( get_uniques_for_type('book_category') ), 0 ); + asrt( are_cols_in_unique( 'book_category', array( 'book_id', 'category_id' ) ), FALSE ); + asrt( count( get_uniques_for_type('library') ), 1 ); + asrt( are_cols_in_unique( 'library', array( 'book_id', 'category_id' ) ), TRUE ); + AQueryWriter::clearRenames(); + R::nuke(); + $book = R::dispense( 'book' ); + $category = R::dispense( 'category' ); + $book->sharedCategory[] = $category; + R::store( $book ); + asrt( count( get_uniques_for_type('book_category') ), 1 ); + asrt( are_cols_in_unique( 'book_category', array( 'book_id', 'category_id' ) ), TRUE ); + asrt( count( get_uniques_for_type('library') ), 0 ); + asrt( are_cols_in_unique( 'library', array( 'book_id', 'category_id' ) ), FALSE ); + R::nuke(); + $book = R::dispense( 'book' ); + $book2 = R::dispense( 'book' ); + $book->sharedBook[] = $book2; + R::store( $book ); + asrt( count( get_uniques_for_type('book_book') ), 1 ); + asrt( are_cols_in_unique( 'book_book', array( 'book_id', 'book2_id' ) ), TRUE ); + try { + $result = R::getWriter()->addUniqueConstraint( 'nonexistant', array( 'a', 'b' ) ); + } catch( \Exception $e ) { + print_r( $e ); exit; + } + pass(); //dont crash! + asrt( $result, FALSE ); + } + + /** + * Tests foreign keys but checks using ProxyWriter. + * + * @return void + */ + public function testFKInspect() + { + $faultyWriter = new \FaultyWriter( R::getDatabaseAdapter() ); + try { + $null = \ProxyWriter::callMethod( $faultyWriter, 'getForeignKeyForTypeProperty', 'test', 'test' ); + pass(); + } catch( \Exception $e ) { + fail(); + } + asrt( is_null( $null ), TRUE ); + $writer = R::getWriter(); + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->xownPage[] = $page; + R::store( $book ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'book_id' ); + asrt( is_array( $keys ), TRUE ); + asrt( $keys['on_delete'], 'CASCADE' ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'id' ); + asrt( is_null( $keys ), TRUE ); + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->ownPage[] = $page; + R::store( $book ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'book_id' ); + asrt( is_array( $keys ), TRUE ); + asrt( $keys['on_delete'], 'SET NULL' ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'id' ); + asrt( is_null( $keys ), TRUE ); + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->alias('magazine')->xownPage[] = $page; + R::store( $book ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'magazine_id' ); + asrt( is_array( $keys ), TRUE ); + asrt( $keys['on_delete'], 'CASCADE' ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'book_id' ); + asrt( is_null( $keys ), TRUE ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'id' ); + asrt( is_null( $keys ), TRUE ); + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->cover= $page; + R::store( $book ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book', 'cover_id' ); + asrt( is_array( $keys ), TRUE ); + asrt( $keys['on_delete'], 'SET NULL' ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book', 'page_id' ); + asrt( is_null( $keys ), TRUE ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book', 'id' ); + asrt( is_null( $keys ), TRUE ); + R::nuke(); + $book = R::dispense( 'book' ); + $category = R::dispense( 'category' ); + $book->sharedTag[] = $category; + R::store( $book ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book_category', 'book_id' ); + asrt( is_array( $keys ), TRUE ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book_category', 'category_id' ); + asrt( is_array( $keys ), TRUE ); + $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book_category', 'id' ); + asrt( is_null( $keys ), TRUE ); + } + + /** + * Test dependencies. + * + * @return void + */ + public function testDependency() + { + $can = $this->createBeanInCan( FALSE ); + + asrt( R::count( 'bean' ), 1 ); + + R::trash( $can ); + + // Bean stays + asrt( R::count( 'bean' ), 1 ); + } + + /** + * Test dependencies (variation). + * + * @return void + */ + public function testDependency2() + { + $can = $this->createBeanInCan( TRUE ); + + asrt( R::count( 'bean' ), 1 ); + + R::trash( $can ); + + // Bean gone + asrt( R::count( 'bean' ), 0 ); + + $can = $this->createBeanInCan( FALSE ); + + asrt( R::count( 'bean' ), 1 ); + + R::trash( $can ); + + // Bean stays, constraint removed + asrt( R::count( 'bean' ), 0 ); + + //need to recreate table to get rid of constraint! + R::nuke(); + + $can = $this->createBeanInCan( FALSE ); + + asrt( R::count( 'bean' ), 1 ); + + R::trash( $can ); + + // Bean stays, constraint removed + asrt( R::count( 'bean' ), 1 ); + + } + + /** + * Tests dependencies (variation). + * + * @return void + */ + public function testDependency3() + { + R::nuke(); + + $can = $this->createCanForBean(); + + asrt( R::count( 'bean' ), 1 ); + + R::trash( $can ); + + asrt( R::count( 'bean' ), 1 ); + } + + /** + * Tests dependencies (variation). + * + * @return void + */ + public function testDependency4() + { + R::nuke(); + + $can = $this->createBeanInCan( TRUE ); + + R::store( $can ); + + R::trash( $can ); + + $can = $this->createCanForBean(); + + asrt( R::count( 'bean' ), 1 ); + + R::trash( $can ); + + asrt( R::count( 'bean' ), 0 ); + + $can = $this->createBeanInCan( TRUE ); + + R::store( $can ); + + R::trash( $can ); + + $can = $this->createCanForBean(); + + asrt( R::count( 'bean' ), 1 ); + + R::trash( $can ); + + asrt( R::count( 'bean' ), 0 ); + } + + /** + * Issue #171 + * The index name argument is not unique in processEmbeddedBean etc. + * + * @return void + */ + public function testIssue171() + { + R::getDatabaseAdapter()->addEventListener( 'sql_exec', $this ); + + $account = R::dispense( 'account' ); + $user = R::dispense( 'user' ); + $player = R::dispense( 'player' ); + + $account->ownUser[] = $user; + + R::store( $account ); + + asrt( strpos( implode( ',', $this->queries ), 'index_foreignkey_user_account' ) !== FALSE, TRUE ); + + $this->queries = array(); + + $account->ownPlayer[] = $player; + + R::store( $account ); + + asrt( strpos( implode( ',', $this->queries ), 'index_foreignkey_player_accou' ) !== FALSE, TRUE ); + } + + /** + * Tests whether foreign keys are created correctly for certain + * relations. + * + * @return void + */ + public function testCreationOfForeignKeys() + { + $this->queries = array(); + + $account = R::dispense( 'account' ); + $user = R::dispense( 'user' ); + $player = R::dispense( 'player' ); + + $user->account = $account; + + R::store( $user ); + + asrt( strpos( implode( ',', $this->queries ), 'index_foreignkey_user_account' ) !== FALSE, TRUE ); + + $this->queries = array(); + + $player->account = $account; + + R::store( $player ); + + asrt( strpos( implode( ',', $this->queries ), 'index_foreignkey_player_accou' ) !== FALSE, TRUE ); + } + + /** + * Test helper method. + * Creates a bean in a can. The bean will get a reference + * to the can and can be made dependent. + * + * @return OODBBean $can + */ + private function createBeanInCan( $isExcl ) + { + $can = R::dispense( 'can' ); + $bean = R::dispense( 'bean' ); + + $can->name = 'bakedbeans'; + $bean->taste = 'salty'; + + if ($isExcl) { + $can->xownBean[] = $bean; + } else { + $can->ownBean[] = $bean; + } + + R::store( $can ); + + return $can; + } + + /** + * Test helper method. + * Creates a bean in a can beginning with the bean. The bean will get a reference + * to the can and can be made dependent. + * + * @return OODBBean $can + */ + private function createCanForBean() + { + $can = R::dispense( 'can' ); + $bean = R::dispense( 'bean' ); + + $bean->can = $can; + + R::store( $bean ); + + return $can; + } + + /** + * Log queries + * + * @param string $event + * @param Adapter $info + */ + public function onEvent( $event, $info ) + { + $this->queries[] = $info->getSQL(); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Frozen.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Frozen.php new file mode 100644 index 000000000..2cf9167c8 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Frozen.php @@ -0,0 +1,115 @@ +xownPageList[] = R::dispense( 'page' ); + $book->sharedTagList[] = R::dispense( 'tag' ); + R::store( $book ); + $book = $book->fresh(); + R::freeze( TRUE ); + + $book->xownPageList = array(); + + R::store( $book ); + $book = $book->fresh(); + + asrt( R::count('page'), 0 ); + + $book->xownPageList[] = R::dispense( 'page' ); + + R::store( $book ); + $book = $book->fresh(); + + asrt( R::count('page'), 1 ); + + $book->xownPageList; + $book->sharedTagList; + R::trash( $book ); + + asrt( R::count('book'), 0 ); + asrt( R::count('page'), 0 ); + asrt( R::count('tag'), 1 ); + asrt( R::count('book_tag'), 0 ); + + R::freeze( FALSE ); + } + + /** + * Tests whether invalid list checks are + * operational in frozen mode. + * + * @return void + */ + public function testInvalidList() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book->xownPageList[] = R::dispense( 'page' ); + $book->sharedTagList[] = R::dispense( 'tag' ); + R::store( $book ); + R::freeze( TRUE ); + + $book = R::dispense( 'book' ); + $book->xownPageList[] = 'nonsense'; + try { + R::store( $book ); + fail(); + } catch( \Exception $e ) { + pass(); + } + + R::freeze( FALSE ); + } + + /** + * Tests whether loading non-existant beans + * returns the same results in frozen mode. + * + * @return + */ + public function testLoadNonExistant() + { + R::nuke(); + R::store( R::dispense( 'bean' ) ); + R::freeze( TRUE ); + $bean = R::load( 'bean', 123 ); + R::freeze( FALSE ); + asrt( ( $bean instanceof OODBBean ), TRUE ); + asrt( $bean->id, 0 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Fuse.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Fuse.php new file mode 100644 index 000000000..9f3219560 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Fuse.php @@ -0,0 +1,406 @@ +getBeanHelper(); + asrt( ( $oldBeanHelper instanceof SimpleFacadeBeanHelper ), TRUE ); + R::getRedBean()->setBeanHelper( $customBeanHelper ); + $meal = R::dispense( 'meal' ); + asrt( ( $meal->box() instanceof \Model_Soup ), TRUE ); + $cake = R::dispense( 'cake' ); + asrt( is_null( $cake->box() ), TRUE ); + $bean = R::dispense( 'coffee' ); + asrt( ( $bean->box() instanceof \Model_Coffee ), TRUE ); + $meal->setFlavour( 'tomato' ); + asrt( $meal->getFlavour(), 'tomato' ); + $meal->rating = 5; + R::store( $meal ); + asrt( $meal->getFlavour(), 'tomato' ); + $meal = $meal->unbox(); + asrt( $meal->getFlavour(), 'tomato' ); + $meal = R::findOne( 'meal' ); + asrt( ( $meal->box() instanceof \Model_Soup ), TRUE ); + asrt( $meal->getFlavour(), '' ); + $meal->setFlavour( 'tomato' ); + asrt( $meal->getFlavour(), 'tomato' ); + $meal = $meal->unbox(); + asrt( $meal->getFlavour(), 'tomato' ); + R::getRedBean()->setBeanHelper( $oldBeanHelper ); + } + + /** + * Test FUSE hooks (i.e. open, update, update_after etc..) + * + * @return void + */ + public function testHooks() + { + R::nuke(); + $probe = R::dispense( 'probe' ); + $probe->name = 'test'; + asrt( $probe->getLogActionCount(), 1 ); + asrt( $probe->getLogActionCount( 'dispense' ), 1 ); + asrt( $probe->getLogActionCount( 'open' ), 0 ); + asrt( $probe->getLogActionCount( 'update' ), 0 ); + asrt( $probe->getLogActionCount( 'after_update' ), 0 ); + asrt( $probe->getLogActionCount( 'delete' ), 0 ); + asrt( $probe->getLogActionCount( 'after_delete' ), 0 ); + asrt( ( $probe->getDataFromLog( 0, 'bean' ) === $probe ), TRUE ); + R::store( $probe ); + asrt( $probe->getLogActionCount(), 3 ); + asrt( $probe->getLogActionCount( 'dispense' ), 1 ); + asrt( $probe->getLogActionCount( 'open' ), 0 ); + asrt( $probe->getLogActionCount( 'update' ), 1 ); + asrt( $probe->getLogActionCount( 'after_update' ), 1 ); + asrt( $probe->getLogActionCount( 'delete' ), 0 ); + asrt( $probe->getLogActionCount( 'after_delete' ), 0 ); + asrt( ( $probe->getDataFromLog( 2, 'bean' ) === $probe ), TRUE ); + $probe = R::load( 'probe', $probe->id ); + asrt( $probe->getLogActionCount(), 2 ); + asrt( $probe->getLogActionCount( 'dispense' ), 1 ); + asrt( $probe->getLogActionCount( 'open' ), 1 ); + asrt( $probe->getLogActionCount( 'update' ), 0 ); + asrt( $probe->getLogActionCount( 'after_update' ), 0 ); + asrt( $probe->getLogActionCount( 'delete' ), 0 ); + asrt( $probe->getLogActionCount( 'after_delete' ), 0 ); + asrt( ( $probe->getDataFromLog( 0, 'bean' ) === $probe ), TRUE ); + asrt( ( $probe->getDataFromLog( 1, 'id' ) === $probe->id ), TRUE ); + $probe->clearLog(); + R::trash( $probe ); + asrt( $probe->getLogActionCount(), 2 ); + asrt( $probe->getLogActionCount( 'dispense' ), 0 ); + asrt( $probe->getLogActionCount( 'open' ), 0 ); + asrt( $probe->getLogActionCount( 'update' ), 0 ); + asrt( $probe->getLogActionCount( 'after_update' ), 0 ); + asrt( $probe->getLogActionCount( 'delete' ), 1 ); + asrt( $probe->getLogActionCount( 'after_delete' ), 1 ); + asrt( ( $probe->getDataFromLog( 0, 'bean' ) === $probe ), TRUE ); + asrt( ( $probe->getDataFromLog( 1, 'bean' ) === $probe ), TRUE ); + //less 'normal scenarios' + $probe = R::dispense( 'probe' ); + $probe->name = 'test'; + asrt( $probe->getLogActionCount(), 1 ); + asrt( $probe->getLogActionCount( 'dispense' ), 1 ); + asrt( $probe->getLogActionCount( 'open' ), 0 ); + asrt( $probe->getLogActionCount( 'update' ), 0 ); + asrt( $probe->getLogActionCount( 'after_update' ), 0 ); + asrt( $probe->getLogActionCount( 'delete' ), 0 ); + asrt( $probe->getLogActionCount( 'after_delete' ), 0 ); + asrt( ( $probe->getDataFromLog( 0, 'bean' ) === $probe ), TRUE ); + R::store( $probe ); + asrt( $probe->getLogActionCount(), 3 ); + asrt( $probe->getLogActionCount( 'dispense' ), 1 ); + asrt( $probe->getLogActionCount( 'open' ), 0 ); + asrt( $probe->getLogActionCount( 'update' ), 1 ); + asrt( $probe->getLogActionCount( 'after_update' ), 1 ); + asrt( $probe->getLogActionCount( 'delete' ), 0 ); + asrt( $probe->getLogActionCount( 'after_delete' ), 0 ); + asrt( ( $probe->getDataFromLog( 2, 'bean' ) === $probe ), TRUE ); + asrt( $probe->getMeta( 'tainted' ), FALSE ); + asrt( $probe->getMeta( 'changed' ), FALSE ); + R::store( $probe ); //not tainted, no FUSE save! + asrt( $probe->getLogActionCount(), 3 ); + asrt( $probe->getLogActionCount( 'dispense' ), 1 ); + asrt( $probe->getLogActionCount( 'open' ), 0 ); + asrt( $probe->getLogActionCount( 'update' ), 1 ); + asrt( $probe->getLogActionCount( 'after_update' ), 1 ); + asrt( $probe->getLogActionCount( 'delete' ), 0 ); + asrt( $probe->getLogActionCount( 'after_delete' ), 0 ); + asrt( ( $probe->getDataFromLog( 2, 'bean' ) === $probe ), TRUE ); + $probe->xownProbeList[] = R::dispense( 'probe' ); + //tainted, not changed, triggers FUSE + asrt( $probe->getMeta( 'tainted' ), TRUE ); + asrt( $probe->getMeta( 'changed' ), FALSE ); + R::store( $probe ); + asrt( $probe->getMeta( 'tainted' ), FALSE ); + asrt( $probe->getMeta( 'changed' ), FALSE ); + asrt( $probe->getLogActionCount(), 5 ); + asrt( $probe->getLogActionCount( 'dispense' ), 1 ); + asrt( $probe->getLogActionCount( 'open' ), 0 ); + asrt( $probe->getLogActionCount( 'update' ), 2 ); + asrt( $probe->getLogActionCount( 'after_update' ), 2 ); + asrt( $probe->getLogActionCount( 'delete' ), 0 ); + asrt( $probe->getLogActionCount( 'after_delete' ), 0 ); + asrt( ( $probe->getDataFromLog( 2, 'bean' ) === $probe ), TRUE ); + } + + /** + * Tests the SimpleFacadeBeanHelper factory setter. + * + * @return void + */ + public function testFactory() + { + SimpleFacadeBeanHelper::setFactoryFunction( function( $name ) { + $model = new $name(); + $model->setNote( 'injected', 'dependency' ); + return $model; + } ); + + $bean = R::dispense( 'band' )->box(); + + asrt( ( $bean instanceof \Model_Band ), TRUE ); + asrt( ( $bean->getNote('injected') ), 'dependency' ); + + SimpleFacadeBeanHelper::setFactoryFunction( NULL ); + } + + /** + * Make sure that beans of type book_page can be fused with + * models like BookPage (beautified) as well as Book_Page (non-beautified). + */ + public function testBeutificationOfLinkModel() + { + $page = R::dispense( 'page' ); + $widget = R::dispense( 'widget' ); + $page->sharedWidgetList[] = $widget; + R::store( $page ); + $testReport = \Model_PageWidget::getTestReport(); + asrt( $testReport, 'didSave' ); + + $page = R::dispense( 'page' ); + $gadget = R::dispense( 'gadget' ); + $page->sharedGadgetList[] = $gadget; + R::store( $page ); + $testReport = \Model_Gadget_Page::getTestReport(); + asrt( $testReport, 'didSave' ); + } + + /** + * Only theoretical. + * + * @return void + */ + public function testTheoreticalBeautifications() + { + $bean = R::dispense('bean'); + $bean->setMeta('type', 'a_b_c'); + R::store($bean); + $testReport = \Model_A_B_C::getTestReport(); + asrt( $testReport, 'didSave' ); + } + + /** + * Test extraction of toolbox. + * + * @return void + */ + public function testGetExtractedToolBox() + { + $helper = new SimpleFacadeBeanHelper; + + list( $redbean, $database, $writer, $toolbox ) = $helper->getExtractedToolbox(); + + asrt( ( $redbean instanceof OODB ), TRUE ); + asrt( ( $database instanceof Adapter ), TRUE ); + asrt( ( $writer instanceof QueryWriter ), TRUE ); + asrt( ( $toolbox instanceof ToolBox ), TRUE ); + } + + /** + * Test FUSE and model formatting. + * + * @todo move tagging tests to tag tester. + * + * @return void + */ + public function testFUSE() + { + $toolbox = R::getToolBox(); + $adapter = $toolbox->getDatabaseAdapter(); + $blog = R::dispense( 'blog' ); + $blog->title = 'testing'; + $blog->blog = 'tesing'; + R::store( $blog ); + $blogpost = R::load( "blog", 1 ); + $post = R::dispense( "post" ); + $post->message = "hello"; + $blog->sharedPost[] = $post; + R::store($blog); + $a = R::getAll( "select * from blog " ); + R::tag( $post, "lousy,smart" ); + asrt( implode( ',', R::tag( $post ) ), "lousy,smart" ); + R::tag( $post, "clever,smart" ); + $tagz = implode( ',', R::tag( $post ) ); + asrt( ( $tagz == "smart,clever" || $tagz == "clever,smart" ), TRUE ); + R::tag( $blog, array( "smart", "interesting" ) ); + asrt( implode( ',', R::tag( $blog ) ), "smart,interesting" ); + try { + R::tag( $blog, array( "smart", "interesting", "lousy!" ) ); + pass(); + } catch ( RedException $e ) { + fail(); + } + asrt( implode( ',', R::tag( $blog ) ), "smart,interesting,lousy!" ); + asrt( implode( ",", R::tag( $blog ) ), "smart,interesting,lousy!" ); + R::untag( $blog, array( "smart", "interesting" ) ); + asrt( implode( ",", R::tag( $blog ) ), "lousy!" ); + asrt( R::hasTag( $blog, array( "lousy!" ) ), TRUE ); + asrt( R::hasTag( $blog, array( "lousy!", "smart" ) ), TRUE ); + asrt( R::hasTag( $blog, array( "lousy!", "smart" ), TRUE ), FALSE ); + R::tag( $blog, FALSE ); + asrt( count( R::tag( $blog ) ), 0 ); + R::tag( $blog, array( "funny", "comic" ) ); + asrt( count( R::tag( $blog ) ), 2 ); + R::addTags( $blog, array( "halloween" ) ); + asrt( count( R::tag( $blog ) ), 3 ); + asrt( R::hasTag( $blog, array( "funny", "commic", "halloween" ), TRUE ), FALSE ); + R::unTag( $blog, array( "funny" ) ); + R::addTags( $blog, "horror" ); + asrt( count( R::tag( $blog ) ), 3 ); + asrt( R::hasTag( $blog, array( "horror", "commic", "halloween" ), TRUE ), FALSE ); + // No double tags + R::addTags( $blog, "horror" ); + asrt( R::hasTag( $blog, array( "horror", "commic", "halloween" ), TRUE ), FALSE ); + asrt( count( R::tag( $blog ) ), 3 ); + } + + /** + * Test error handling options FUSE. + */ + public function testModelErrorHandling() + { + $test = R::dispense( 'feed' ); + $test->nonExistantMethod(); + pass(); + $old = R::setErrorHandlingFUSE( OODBBean::C_ERR_LOG ); + asrt( is_array( $old ), TRUE ); + asrt( count( $old ), 2 ); + asrt( $old[0], FALSE ); + asrt( $old[1], NULL); + $test->nonExistantMethod(); //we cant really test this... :( + pass(); + $old = R::setErrorHandlingFUSE( OODBBean::C_ERR_NOTICE ); + asrt( is_array( $old ), TRUE ); + asrt( count( $old ), 2 ); + asrt( $old[0], OODBBean::C_ERR_LOG ); + asrt( $old[1], NULL); + set_error_handler(function($error, $str) { + asrt( $str, 'FUSE: method does not exist in model: nonExistantMethod' ); + }, E_USER_NOTICE); + $test->nonExistantMethod(); + restore_error_handler(); + $old = OODBBean::setErrorHandlingFUSE( OODBBean::C_ERR_WARN ); + asrt( is_array( $old ), TRUE ); + asrt( count( $old ), 2 ); + asrt( $old[0], OODBBean::C_ERR_NOTICE ); + asrt( $old[1], NULL); + set_error_handler(function($error, $str) { + asrt( $str, 'FUSE: method does not exist in model: nonExistantMethod' ); + }, E_USER_WARNING); + $test->nonExistantMethod(); + restore_error_handler(); + $old = OODBBean::setErrorHandlingFUSE( OODBBean::C_ERR_FATAL ); + asrt( is_array( $old ), TRUE ); + asrt( count( $old ), 2 ); + asrt( $old[0], OODBBean::C_ERR_WARN ); + asrt( $old[1], NULL); + set_error_handler(function($error, $str) { + asrt( $str, 'FUSE: method does not exist in model: nonExistantMethod' ); + }, E_USER_ERROR); + $test->nonExistantMethod(); + restore_error_handler(); + $old = OODBBean::setErrorHandlingFUSE( OODBBean::C_ERR_EXCEPTION ); + asrt( is_array( $old ), TRUE ); + asrt( count( $old ), 2 ); + asrt( $old[0], OODBBean::C_ERR_FATAL ); + asrt( $old[1], NULL); + try { + $test->nonExistantMethod(); + fail(); + } catch (\Exception $e) { + pass(); + } + global $test_bean; + $test_bean = $test; + global $has_executed_error_func_fuse; + $has_executed_error_func_fuse = FALSE; + $old = OODBBean::setErrorHandlingFUSE( OODBBean::C_ERR_FUNC, function( $info ){ + global $has_executed_error_func_fuse; + global $test_bean; + $has_executed_error_func_fuse = TRUE; + asrt( is_array( $info ), TRUE ); + asrt( $info['method'], 'nonExistantMethod' ); + asrt( json_encode( $info['bean']->export() ), json_encode( $test_bean->export() ) ); + asrt( $info['message'], 'FUSE: method does not exist in model: nonExistantMethod' ); + } ); + asrt( is_array( $old ), TRUE ); + asrt( count( $old ), 2 ); + asrt( $old[0], OODBBean::C_ERR_EXCEPTION ); + asrt( $old[1], NULL); + $test->nonExistantMethod(); + asrt( $has_executed_error_func_fuse, TRUE ); + $old = OODBBean::setErrorHandlingFUSE( OODBBean::C_ERR_IGNORE ); + asrt( is_array( $old ), TRUE ); + asrt( count( $old ), 2 ); + asrt( $old[0], OODBBean::C_ERR_FUNC ); + asrt( is_callable( $old[1] ), TRUE ); + $old = OODBBean::setErrorHandlingFUSE( OODBBean::C_ERR_IGNORE ); + asrt( is_array( $old ), TRUE ); + asrt( count( $old ), 2 ); + asrt( $old[0], OODBBean::C_ERR_IGNORE ); + asrt( $old[1], NULL); + try { + OODBBean::setErrorHandlingFUSE( 900 ); + fail(); + } catch (\Exception $e) { + pass(); + asrt( $e->getMessage(), 'Invalid error mode selected' ); + } + try { + OODBBean::setErrorHandlingFUSE( OODBBean::C_ERR_FUNC, 'hello' ); + fail(); + } catch (\Exception $e) { + pass(); + asrt( $e->getMessage(), 'Invalid error handler' ); + } + OODBBean::setErrorHandlingFUSE( OODBBean::C_ERR_EXCEPTION ); + //make sure ignore FUSE events + $test = R::dispense('feed'); + R::store( $test ); + $test = $test->fresh(); + R::trash( $test ); + pass(); + OODBBean::setErrorHandlingFUSE( OODBBean::C_ERR_IGNORE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Indexes.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Indexes.php new file mode 100644 index 000000000..b2e7c5594 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Indexes.php @@ -0,0 +1,136 @@ +ownPageList[] = $page; + R::store( $book ); + $indexes = getIndexes( 'page' ); + asrt( in_array( 'index_foreignkey_page_book', $indexes ), TRUE ); + } + + /** + * Tests indexes on parent beans. + * + * @return void + */ + public function testIndexCreationParentBean() + { + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $page->book = $book; + R::store( $page ); + $indexes = getIndexes( 'page' ); + asrt( in_array( 'index_foreignkey_page_book', $indexes ), TRUE ); + } + + /** + * Tests indexes on link tables. + * + * @return void + */ + public function testIndexCreationMany2Many() + { + R::nuke(); + $book = R::dispense( 'book' ); + $category = R::dispense( 'category' ); + $book->sharedCategoryList[] = $category; + R::store( $book ); + $indexes = getIndexes( 'book_category' ); + asrt( in_array( 'index_foreignkey_book_category_book', $indexes ), TRUE ); + asrt( in_array( 'index_foreignkey_book_category_category', $indexes ), TRUE ); + R::nuke(); + R::nuke(); + $book = R::dispense( 'book' ); + $category = R::dispense( 'category' ); + $category->sharedBookList[] = $book; + R::store( $category ); + $indexes = getIndexes( 'book_category' ); + asrt( in_array( 'index_foreignkey_book_category_book', $indexes ), TRUE ); + asrt( in_array( 'index_foreignkey_book_category_category', $indexes ), TRUE ); + } + + /** + * Tests indexes on aliases. + * + * @return void + */ + public function testIndexCreationAlias() + { + R::nuke(); + $book = R::dispense( 'book' ); + $author = R::dispense( 'author' ); + $book->coAuthor = $author; + R::store( $book ); + $indexes = getIndexes( 'book' ); + asrt( in_array( 'index_foreignkey_book_co_author', $indexes ), TRUE ); + R::nuke(); + $project = R::dispense( 'project' ); + $person = R::dispense( 'person' ); + $person->alias( 'teacher' )->ownProject[] = $project; + $person2 = R::dispense( 'person' ); + $person2->alias( 'student' )->ownProject[] = $project; + R::store( $person ); + $indexes = getIndexes( 'project' ); + asrt( in_array( 'index_foreignkey_project_teacher', $indexes ), TRUE ); + R::store( $person2 ); + $indexes = getIndexes( 'project' ); + asrt( in_array( 'index_foreignkey_project_student', $indexes ), TRUE ); + } + + /** + * Tests index fails. + * + * @return void + */ + public function testIndexCreationFail() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book->author_id = 'a'; + R::store( $book ); + $indexes = getIndexes( 'book' ); + //should just work fine + asrt( in_array( 'index_foreignkey_book_author', $indexes ), TRUE ); + //these should just pass, no indexes but no errors as well + R::getWriter()->addIndex( 'book', 'bla', 'nonexist' ); + pass(); + R::getWriter()->addIndex( 'book', '@#$', 'nonexist' ); + pass(); + R::getWriter()->addIndex( 'nonexist', 'bla', 'nonexist' ); + pass(); + $indexesAfter = getIndexes( 'book' ); + asrt( count( $indexesAfter ), count( $indexes ) ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue259.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue259.php new file mode 100644 index 000000000..a24d60db5 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue259.php @@ -0,0 +1,69 @@ +desc = 'I am mother'; + R::store( $mother ); + $child = R::dispense( 'child' ); + $child->mother = $mother; + $child->desc = 'I am child'; + $id = R::store( $child ); + R::findOne( 'child', ' id = ?', array( $id ) ); + R::find( 'child', ' id = ? ', array( $id ) ); + R::load( 'child', $id ); + } +} +/** + * Mock Model. + */ +class Model_Mother extends SimpleModel +{ + public function open() + { + $bean = $this->bean; + // $this & $bean are both referencing child incorrectly! + asrt( $this->bean->desc, 'I am mother' ); + } +} +/** + * Mock Model. + */ +class Model_Child extends SimpleModel +{ + public function open() + { + $this->bean->mother; + asrt( $this->bean->desc, 'I am child' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue303.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue303.php new file mode 100644 index 000000000..626b419ac --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue303.php @@ -0,0 +1,58 @@ +setAttr( 'invalid.property', 'value' ) ); + fail(); + } catch (RedException $e ) { + asrt( $e->getMessage(), 'Invalid Bean property: property invalid.property' ); + } + + try { + R::store( R::dispense( 'invalidbean' )->setAttr( 'property', array() ) ); + fail(); + } catch (RedException $e ) { + asrt( $e->getMessage(), 'Invalid Bean value: property property' ); + } + + try { + R::store( R::dispense( 'invalidbean' )->setAttr( 'property', new \stdClass ) ); + fail(); + } catch (RedException $e ) { + asrt( $e->getMessage(), 'Invalid Bean value: property property' ); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue408.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue408.php new file mode 100644 index 000000000..8e389dd3c --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue408.php @@ -0,0 +1,82 @@ +post = array( + 'first', + 'second' + ); + R::store( $feed ); + $rows = R::getAll('SELECT * FROM feed'); + asrt( $rows[0]['post'], '["first","second"]' ); + $feed = $feed->fresh(); + asrt( is_array( $feed->post ), TRUE ); + asrt( $feed->post[0], 'first' ); + asrt( $feed->post[1], 'second' ); + R::store( $feed ); + $rows = R::getAll('SELECT * FROM feed'); + asrt( $rows[0]['post'], '["first","second"]' ); + $feed = R::load( 'feed', $feed->id ); + $feed->post[] = 'third'; + R::store( $feed ); + $rows = R::getAll('SELECT * FROM feed'); + asrt( $rows[0]['post'], '["first","second","third"]' ); + $feed = $feed->fresh(); + asrt( is_array( $feed->post ), TRUE ); + asrt( $feed->post[0], 'first' ); + asrt( $feed->post[1], 'second' ); + asrt( $feed->post[2], 'third' ); + //now the catch: can we use export? + //PHP Fatal error: Call to a member function export() on a non-object + $feeds = R::exportAll( R::find( 'feed' ) ); + asrt( is_array( $feeds ), TRUE ); + $feed = reset( $feeds ); + asrt( $feed['post'][0], 'first' ); + asrt( $feed['post'][1], 'second' ); + asrt( $feed['post'][2], 'third' ); + //can we also dup()? + $feedOne = R::findOne( 'feed' ); + R::store( R::dup( $feedOne ) ); + asrt( R::count( 'feed' ), 2 ); + //can we delete? + R::trash( $feedOne ); + asrt( R::count( 'feed' ), 1 ); + $feedTwo = R::findOne( 'feed' ); + $feed = $feedTwo->export(); + asrt( $feed['post'][0], 'first' ); + asrt( $feed['post'][1], 'second' ); + asrt( $feed['post'][2], 'third' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue90.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue90.php new file mode 100644 index 000000000..f9e367c77 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Issue90.php @@ -0,0 +1,44 @@ +name = 'a'; + $f = R::dispense( 'bottle' ); + $s->ownBottle[] = $f; + R::store( $s ); + $s2 = R::dispense( 'box' ); + $s2->name = 'a'; + R::store( $s2 ); + R::trash( $s2 ); + pass(); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Joins.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Joins.php new file mode 100644 index 000000000..488ea471a --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Joins.php @@ -0,0 +1,238 @@ +title = 'x'; + $author->xownBookList[] = $book; + $book->info = $info; + $book = R::dispense( 'book' ); + $info = R::dispense( 'info' ); + $info->title = 'y'; + $author->xownBookList[] = $book; + $book->info = $info; + R::store( $author ); + $author = $author->fresh(); + $books = $author->withCondition(' @joined.info.title != ? ', array('x'))->countOwn('book'); + asrt($books, 1); + $books = $author->withCondition(' @joined.info.title != ? ', array('y'))->countOwn('book'); + asrt($books, 1); + $books = $author->withCondition(' @joined.info.title IN (?,?) ', array('x','y'))->countOwn('book'); + asrt($books, 2); + } + + /** + * Test Joins. + * + * @return void + */ + public function testJoins() + { + R::nuke(); + list($a1, $a2, $a3) = R::dispense('area', 3); + list($p1, $p2) = R::dispense('person', 2); + list($v1, $v2, $v3, $v4) = R::dispense('visit', 4); + $a1->name = 'Belgium'; + $a2->name = 'Arabia'; + $a3->name = 'France'; + $v1->person = $p1; + $v2->person = $p1; + $v3->person = $p2; + $v4->person = $p2; + $v1->area = $a3; + $v2->area = $a2; + $v3->area = $a2; + $v4->area = $a1; + $v1->label = 'v1 to France'; + $v2->label = 'v2 to Arabia'; + $v3->label = 'v3 to Arabia'; + $v4->label = 'v4 to Belgium'; + R::storeAll( array($v1,$v2,$v3,$v4) ); + $visits = $p1->ownVisit; + asrt( is_array( $visits ), TRUE ); + asrt( count( $visits ), 2 ); + $names = array(); + foreach( $visits as $visit ) { + asrt( isset( $visit->label ), TRUE ); + asrt( isset( $visit->name ), FALSE ); + asrt( isset( $visit->visit_id ), FALSE ); + $names[] = $visit->label; + } + $labelList = implode( ',', $names ); + asrt( $labelList, 'v1 to France,v2 to Arabia' ); + $visits = $p1 + ->with('ORDER BY @joined.area.name ASC')->ownVisit; + asrt( is_array( $visits ), TRUE ); + asrt( count( $visits ), 2 ); + $names = array(); + foreach( $visits as $visit ) { + asrt( isset( $visit->label ), TRUE ); + asrt( isset( $visit->name ), FALSE ); + asrt( isset( $visit->visit_id ), FALSE ); + $names[] = $visit->label; + } + $labelList = implode( ',', $names ); + asrt( $labelList, 'v2 to Arabia,v1 to France' ); + } + + /** + * Helper for the next test. + * + * @param array $books the books we are going to check + * @param string $numberList the numbers that are expected + * + * @return void + */ + private function checkBookNumbers( $books, $numberList ) + { + $numbers = explode( ',', $numberList ); + asrt( is_array( $books ), TRUE ); + asrt( count( $books ), count( $numbers ) ); + $bookNumbers = ''; + $bookNumberArray = array(); + foreach( $books as $book ) { + asrt( isset( $book->num ), TRUE ); + asrt( isset( $book->title), FALSE ); + $bookNumberArray[] = $book->num; + } + $bookNumbers = implode( ',', $bookNumberArray); + asrt( $bookNumbers, $numberList ); + } + + /** + * Tests the more complicated scenarios for + * with-joins. + * + * @return void + */ + private function testComplexCombinationsJoins() + { + $author = R::dispense( 'author' ); + $books = R::dispense( 'book', 4 ); + $books[0]->num = 0; + $books[1]->num = 1; + $books[2]->num = 2; + $books[3]->num = 3; + $books[0]->info = R::dispense('info')->setAttr('title', 'Learning PHP'); + $books[1]->info = R::dispense('info')->setAttr('title', 'Learning PHP and JavaScript'); + $books[2]->info = R::dispense('info')->setAttr('title', 'Learning Cobol'); + $books[3]->info = R::dispense('info')->setAttr('title','Gardening for Beginners'); + $books[0]->category = R::dispense('category')->setAttr('title', 'computers'); + $books[1]->category = R::dispense('category')->setAttr('title', 'computers'); + $books[2]->category = R::dispense('category')->setAttr('title', 'computers'); + $books[3]->category = R::dispense('category')->setAttr('title','gardening'); + $author->ownBookList = $books; + R::store($author); + //Base test... + $books = $author->ownBookList; + $this->checkBookNumbers( $books, '0,1,2,3' ); + //Just a basic Join... + $books = $author->withCondition(' @joined.info.title LIKE ? ORDER BY book.num ASC ', array( '%PHP%' ) )->ownBookList; + $this->checkBookNumbers( $books, '0,1' ); + //Mix Join and criteria + $books = $author->withCondition(' @joined.info.title LIKE ? AND num > 0 ORDER BY book.num ASC ', array( '%PHP%' ) )->ownBookList; + $this->checkBookNumbers( $books, '1' ); + //Basic join + $books = $author->withCondition(' @joined.info.title LIKE ? ORDER BY book.num ASC', array( '%ing%' ) )->ownBookList; + $this->checkBookNumbers( $books, '0,1,2,3' ); + //Two joins + $books = $author->withCondition(' @joined.info.title LIKE ? AND @joined.category.title = ? ORDER BY book.num ASC', array( '%ing%', 'computers' ) )->ownBookList; + $this->checkBookNumbers( $books, '0,1,2' ); + //Join the same type twice... and order + $books = $author->withCondition(' @joined.info.title LIKE ? AND @joined.category.title = ? ORDER BY @joined.info.title ASC ', array( '%ing%', 'computers' ) )->ownBookList; + $this->checkBookNumbers( $books, '2,0,1' ); + //Join the same type twice + $books = $author->withCondition(' @joined.info.title LIKE ? AND @joined.info.title LIKE ? ORDER BY book.num ASC', array( '%ing%', '%Learn%' ) )->ownBookList; + $this->checkBookNumbers( $books, '0,1,2' ); + //Join the same type 3 times and order + $books = $author->withCondition(' @joined.info.title LIKE ? AND @joined.info.title LIKE ? ORDER BY @joined.info.title DESC', array( '%ing%', '%Learn%' ) )->ownBookList; + $this->checkBookNumbers( $books, '1,0,2' ); + //Join the same type 3 times and order and limit + $books = $author->withCondition(' @joined.info.title LIKE ? AND @joined.info.title LIKE ? ORDER BY @joined.info.title DESC LIMIT 1', array( '%ing%', '%Learn%' ) )->ownBookList; + $this->checkBookNumbers( $books, '1' ); + //Other combinations I can think of... + $books = $author->withCondition(' @joined.category.title LIKE ? ORDER BY @joined.info.title DESC', array( '%ing%' ) )->ownBookList; + $this->checkBookNumbers( $books, '3' ); + $books = $author->withCondition(' @joined.category.title LIKE ? AND num < 4 ORDER BY @joined.info.title DESC', array( '%ing%' ) )->ownBookList; + $this->checkBookNumbers( $books, '3' ); + //multiple ordering + $books = $author->with(' ORDER BY @joined.category.title ASC, @joined.info.title ASC' )->ownBookList; + $this->checkBookNumbers( $books, '2,0,1,3' ); + $books = $author->with(' ORDER BY @joined.category.title DESC, @joined.info.title ASC' )->ownBookList; + $this->checkBookNumbers( $books, '3,2,0,1' ); + $books = $author->with(' ORDER BY @joined.category.title DESC, @joined.info.title ASC LIMIT 2' )->ownBookList; + $this->checkBookNumbers( $books, '3,2' ); + } + + /** + * Tests the more complicated scenarios for + * with-joins. + * + * @return void + */ + public function testComplexInFrozenMode() + { + R::freeze( FALSE ); + $this->testComplexCombinationsJoins(); + R::freeze( TRUE ); + $this->testComplexCombinationsJoins(); + R::freeze( FALSE ); + } + + /** + * Tests R::setNarrowFieldMode() and + * OODBBean::ignoreJoinFeature(). + */ + public function testSystemWideSettingsForJoins() + { + R::nuke(); + $author = R::dispense( 'author' ); + $book = R::dispense( 'book' ); + $info = R::dispense( 'info' ); + $info->title = 'x'; + $author->xownBookList[] = $book; + $book->info = $info; + R::store( $author ); + $author = $author->fresh(); + $books = $author->withCondition(' @joined.info.title != ? ', array('y1') )->xownBookList; + $firstBook = reset( $books ); + asrt( isset( $firstBook->title ), FALSE ); + R::setNarrowFieldMode( FALSE ); + $author = $author->fresh(); + $books = $author->withCondition(' @joined.info.title != ? ', array('y2') )->xownBookList; + $firstBook = reset( $books ); + asrt( isset( $firstBook->title ), TRUE ); + R::setNarrowFieldMode( TRUE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Keywords.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Keywords.php new file mode 100644 index 000000000..1281fcd52 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Keywords.php @@ -0,0 +1,71 @@ +$k = $k; + $id = R::store( $bean ); + $bean = R::load( $k, $id ); + $bean2 = R::dispense( 'other' ); + $bean2->name = $k; + $bean->bean = $bean2; + $bean->ownBean[] = $bean2; + $bean->sharedBean[] = $bean2; + $id = R::store( $bean ); + R::trash( $bean ); + pass(); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Largenum.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Largenum.php new file mode 100644 index 000000000..66d3fbf76 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Largenum.php @@ -0,0 +1,42 @@ +name = 'big number'; + R::store( $number ); + //This should not cause an error... (some people use LIMIT 0, HUGE to simulate OFFSET on MYSQL). + $beans = R::findAll( 'number', ' LIMIT ? ', array( PHP_INT_MAX ) ); + asrt( is_array( $beans ), TRUE ); + asrt( count( $beans ), 1 ); + pass(); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Logging.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Logging.php new file mode 100644 index 000000000..0357ed01c --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Logging.php @@ -0,0 +1,112 @@ + 0 ), TRUE ); + asrt( ( R::getLogger() instanceof Logger ), TRUE ); + R::stopLogging(); + R::store( R::dispense( 'book' ) ); + $logs = R::getLogs(); + asrt( ( count( $logs ) === 0 ), TRUE ); + } + + /** + * Can we manually set a logger and enable logging? + * + * @return void + */ + public function testCanSetLogger() + { + R::nuke(); + R::store( R::dispense( 'bean' ) ); + $logger = new RDefault; + $logger->setMode( RDefault::C_LOGGER_ARRAY ); + $database = R::getDatabaseAdapter()->getDatabase(); + $database->setLogger( $logger ); + asrt( $database->getLogger(), $logger ); + $database->setEnableLogging( FALSE ); + $logs = $logger->getLogs(); + asrt( is_array( $logs ), TRUE ); + asrt( count( $logs ), 0 ); + $database->setEnableLogging( TRUE ); + $logs = $logger->getLogs(); + asrt( is_array( $logs ), TRUE ); + asrt( count( $logs ), 0 ); + R::findOne( 'bean' ); //writes 3 log entries + $logs = $logger->getLogs(); + asrt( is_array( $logs ), TRUE ); + asrt( count( $logs ), 3 ); + } + + /** + * Test query counter. + * + * @return void + */ + public function testQueryCount() + { + R::nuke(); + R::store( R::dispense( 'bean' ) ); + R::resetQueryCount(); + asrt( R::getQueryCount(), 0 ); + R::findOne( 'bean' ); + asrt( R::getQueryCount(), 1 ); + R::resetQueryCount(); + asrt( R::getQueryCount(), 0 ); + R::findOne( 'bean' ); + R::findOne( 'bean' ); + R::findOne( 'bean' ); + asrt( R::getQueryCount(), 0 ); + R::store( R::dispense( 'bean2' ) ); + R::resetQueryCount(); + R::findOne( 'bean' ); + R::findOne( 'bean2' ); + asrt( R::getQueryCount(), 2 ); + R::resetQueryCount(); + R::findOne( 'bean', ' id < 100' ); + R::findOne( 'bean', ' id < 101' ); + R::findOne( 'bean', ' id < 102' ); + R::findOne( 'bean', ' id < 103' ); + asrt( R::getQueryCount(), 4 ); + R::findOne( 'bean', ' id < 100' ); + R::findOne( 'bean', ' id < 101' ); + R::findOne( 'bean', ' id < 102' ); + R::findOne( 'bean', ' id < 103' ); + asrt( R::getQueryCount(), 4 ); + R::findOne( 'bean', ' id < 104' ); + asrt( R::getQueryCount(), 5 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Misc.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Misc.php new file mode 100644 index 000000000..45794824a --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Misc.php @@ -0,0 +1,542 @@ +pages = 100; + $book->title = 'book'; + R::store( $book ); + $book = R::findOne( 'book' ); + asrt( $book->hasChanged( 'title' ), FALSE ); + $book->title = 'yes'; + R::store( $book ); + asrt( $book->hasChanged( 'title' ), TRUE ); + OODB::autoClearHistoryAfterStore( TRUE ); + $book = R::findOne( 'book' ); + asrt( $book->hasChanged( 'title' ), FALSE ); + $book->title = 'yes2'; + R::store( $book ); + asrt( $book->hasChanged( 'title' ), FALSE ); + OODB::autoClearHistoryAfterStore( FALSE ); + $book = R::findOne( 'book' ); + asrt( $book->hasChanged( 'title' ), FALSE ); + $book->title = 'yes'; + R::store( $book ); + asrt( $book->hasChanged( 'title' ), TRUE ); + } + + /** + * Tests the R::inspect() method on the Facade. + * + * @return void + */ + public function testInspect() { + + testpack( 'Test R::inspect() ' ); + R::nuke(); + R::store( R::dispense( 'book' )->setAttr( 'title', 'book' ) ); + $info = R::inspect(); + asrt( count( $info ), 1 ); + asrt( strtolower( $info[0] ), 'book' ); + $info = R::inspect( 'book' ); + asrt( count( $info ), 2 ); + $keys = array_keys( $info ); + sort($keys); + asrt( strtolower( $keys[0] ), 'id' ); + asrt( strtolower( $keys[1] ), 'title' ); + } + + /** + * Test whether we can use the tableExist() method in OODB + * instances directly to help us determine + * the existance of a table. + * + * @return void + */ + public function testTableExist() + { + R::nuke(); + R::store( R::dispense( 'book' ) ); + R::freeze( FALSE ); + asrt( R::getRedBean()->tableExists( 'book' ), TRUE ); + asrt( R::getRedBean()->tableExists( 'book2' ), FALSE ); + R::freeze( TRUE ); + asrt( R::getRedBean()->tableExists( 'book' ), TRUE ); + asrt( R::getRedBean()->tableExists( 'book2' ), FALSE ); + R::freeze( FALSE ); + } + + /** + * Normally the check() method is always called indirectly when + * dealing with beans. This test ensures we can call check() + * directly. Even though frozen repositories do not rely on + * bean checking to improve performance the method should still + * offer the same functionality when called directly. + * + * @return void + */ + public function testCheckDirectly() + { + $bean = new OODBBean; + $bean->id = 0; + $bean->setMeta( 'type', 'book' ); + R::getRedBean()->check( $bean ); + $bean->setMeta( 'type', '.' ); + try { + R::getRedBean()->check( $bean ); + fail(); + } catch ( \Exception $e ) { + pass(); + } + //check should remain the same even if frozen repo is used, method is public after all! + //we dont want to break the API! + R::freeze( TRUE ); + try { + R::getRedBean()->check( $bean ); + fail(); + } catch ( \Exception $e ) { + pass(); + } + R::freeze( FALSE ); + } + + /** + * Test Backward compatibility writer ESC-method. + * + * @return void + */ + public function testLegacyCode() + { + testpack( 'Test Backward compatibility methods in writer.' ); + asrt( R::getWriter()->safeColumn( 'column', TRUE ), R::getWriter()->esc( 'column', TRUE ) ); + asrt( R::getWriter()->safeColumn( 'column', FALSE ), R::getWriter()->esc( 'column', FALSE ) ); + asrt( R::getWriter()->safeTable( 'table', TRUE ), R::getWriter()->esc( 'table', TRUE ) ); + asrt( R::getWriter()->safeTable( 'table', FALSE ), R::getWriter()->esc( 'table', FALSE ) ); + } + + /** + * Test beautification and array functions. + * + * @return void + */ + public function testBeauficationAndArrayFunctions() + { + $bean = R::dispense( 'bean' ); + $bean->isReallyAwesome = TRUE; + asrt( isset( $bean->isReallyAwesome ), TRUE ); + asrt( isset( $bean->is_really_awesome ), TRUE ); + unset( $bean->is_really_awesome ); + asrt( isset( $bean->isReallyAwesome ), FALSE ); + asrt( isset( $bean->is_really_awesome ), FALSE ); + } + + /** + * Test beautification of column names. + * + * @return void + */ + public function testBeautifulColumnNames() + { + testpack( 'Beautiful column names' ); + $town = R::dispense( 'town' ); + $town->isCapital = FALSE; + $town->hasTrainStation = TRUE; + $town->name = 'BeautyVille'; + $houses = R::dispense( 'house', 2 ); + $houses[0]->isForSale = TRUE; + $town->ownHouse = $houses; + R::store( $town ); + $town = R::load( 'town', $town->id ); + asrt( ( $town->isCapital == FALSE ), TRUE ); + asrt( ( $town->hasTrainStation == TRUE ), TRUE ); + asrt( ( $town->name == 'BeautyVille' ), TRUE ); + testpack( 'Accept datetime objects.' ); + $cal = R::dispense( 'calendar' ); + $cal->when = new\DateTime( '2000-01-01', new\DateTimeZone( 'Pacific/Nauru' ) ); + asrt( $cal->when, '2000-01-01 00:00:00' ); + testpack( 'Affected rows test' ); + $currentDriver = $this->currentlyActiveDriverID; + $toolbox = R::getToolBox(); + $adapter = $toolbox->getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + $bean = $redbean->dispense( 'bean' ); + $bean->prop = 3; //make test run with strict mode as well + $redbean->store( $bean ); + $adapter->exec( 'UPDATE bean SET prop = 2' ); + asrt( $adapter->getAffectedRows(), 1 ); + testpack( 'Testing Logger' ); + R::getDatabaseAdapter()->getDatabase()->setLogger( new RDefault ); + asrt( ( R::getDatabaseAdapter()->getDatabase()->getLogger() instanceof Logger ), TRUE ); + asrt( ( R::getDatabaseAdapter()->getDatabase()->getLogger() instanceof RDefault ), TRUE ); + $bean = R::dispense( 'bean' ); + $bean->property = 1; + $bean->unsetAll( array( 'property' ) ); + asrt( $bean->property, NULL ); + asrt( ( $bean->setAttr( 'property', 2 ) instanceof OODBBean ), TRUE ); + asrt( $bean->property, 2 ); + asrt( preg_match( '/\d\d\d\d\-\d\d\-\d\d/', R::isoDate() ), 1 ); + asrt( preg_match( '/\d\d\d\d\-\d\d\-\d\d\s\d\d:\d\d:\d\d/', R::isoDateTime() ), 1 ); + $redbean = R::getRedBean(); + $adapter = R::getDatabaseAdapter(); + $writer = R::getWriter(); + asrt( ( $redbean instanceof OODB ), TRUE ); + asrt( ( $adapter instanceof Adapter ), TRUE ); + asrt( ( $writer instanceof QueryWriter ), TRUE ); + R::setRedBean( $redbean ); + pass(); //cant really test this + R::setDatabaseAdapter( $adapter ); + pass(); //cant really test this + R::setWriter( $writer ); + pass(); //cant really test this + $u1 = R::dispense( 'user' ); + $u1->name = 'Gabor'; + $u1->login = 'g'; + $u2 = R::dispense( 'user' ); + $u2->name = 'Eric'; + $u2->login = 'e'; + R::store( $u1 ); + R::store( $u2 ); + $list = R::getAssoc( 'select login,' . R::getWriter()->esc( 'name' ) . ' from ' . R::getWriter()->esc( 'user' ) . ' ' ); + asrt( $list['e'], 'Eric' ); + asrt( $list['g'], 'Gabor' ); + $painting = R::dispense( 'painting' ); + $painting->name = 'Nighthawks'; + $id = R::store( $painting ); + testpack( 'Testing SQL Error Types' ); + foreach ( $writer->typeno_sqltype as $code => $text ) { + asrt( is_integer( $code ), TRUE ); + asrt( is_string( $text ), TRUE ); + } + foreach ( $writer->sqltype_typeno as $text => $code ) { + asrt( is_integer( $code ), TRUE ); + asrt( is_string( $text ), TRUE ); + } + testpack( 'Testing Nowhere Pt. 1 (unfrozen)' ); + foreach ( + array( + 'exec', 'getAll', 'getCell', 'getAssoc', 'getRow', 'getCol' + ) + as $method ) { + R::$method( 'select * from nowhere' ); + pass(); + } + testpack( 'Testing Nowhere Pt. 2 (frozen)' ); + R::freeze( TRUE ); + foreach ( + array( + 'exec', 'getAll', 'getCell', 'getAssoc', 'getRow', 'getCol' + ) + as $method ) { + try { + R::$method( 'select * from nowhere' ); + fail(); + } catch ( SQL $e ) { + pass(); + } + } + R::freeze( FALSE ); + } + + /** + * Test reflectional functions of database. + * + * @return void + */ + public function testDatabaseProperties() + { + testpack( 'Testing Database Properties' ); + $adapter = R::getDatabaseAdapter(); + if ( method_exists( R::getDatabaseAdapter()->getDatabase(), 'getPDO' ) ){ + asrt( $adapter->getDatabase()->getPDO() instanceof \PDO, TRUE ); + } + asrt( strlen( $adapter->getDatabase()->getDatabaseVersion() ) > 0, TRUE ); + asrt( strlen( $adapter->getDatabase()->getDatabaseType() ) > 0, TRUE ); + } + + /** + * Test Transactions. + * + * @return void + */ + public function testTransactions() + { + testpack( 'transactions' ); + R::begin(); + $bean = R::dispense( 'bean' ); + R::store( $bean ); + R::commit(); + asrt( R::count( 'bean' ), 1 ); + R::wipe( 'bean' ); + R::freeze( 1 ); + R::begin(); + $bean = R::dispense( 'bean' ); + R::store( $bean ); + R::rollback(); + asrt( R::count( 'bean' ), 0 ); + R::freeze( FALSE ); + testpack( 'genSlots' ); + asrt( R::genSlots( array( 'a', 'b' ) ), '?,?' ); + asrt( R::genSlots( array( 'a' ) ), '?' ); + asrt( R::genSlots( array() ), '' ); + } + + /** + * Test nested FUSE scenarios. + * + * @return void + */ + public function testFUSEnested() + { + testpack( 'FUSE models cant touch nested beans in update() - issue 106' ); + $spoon = R::dispense( 'spoon' ); + $spoon->name = 'spoon for test bean'; + $deep = R::dispense( 'deep' ); + $deep->name = 'deepbean'; + $item = R::dispense( 'item' ); + $item->val = 'Test'; + $item->deep = $deep; + $test = R::dispense( 'test' ); + $test->item = $item; + $test->sharedSpoon[] = $spoon; + $test->isnowtainted = TRUE; + $id = R::store( $test ); + $test = R::load( 'test', $id ); + asrt( $test->item->val, 'Test2' ); + $can = reset( $test->ownCan ); + $spoon = reset( $test->sharedSpoon ); + asrt( $can->name, 'can for bean' ); + asrt( $spoon->name, 'S2' ); + asrt( $test->item->deep->name, '123' ); + asrt( count( $test->ownCan ), 1 ); + asrt( count( $test->sharedSpoon ), 1 ); + asrt( count( $test->sharedPeas ), 10 ); + asrt( count( $test->ownChip ), 9 ); + } + + /** + * Tests FUSE and lists, FUSE enforces no more than + * 3 sugar cubes in coffee. + * + * @return void + */ + public function testCoffeeWithSugarAndFUSE() + { + $coffee = R::dispense( 'coffee' ); + $coffee->size = 'XL'; + $coffee->ownSugar = R::dispense( 'sugar', 5 ); + $id = R::store( $coffee ); + $coffee = R::load( 'coffee', $id ); + asrt( count( $coffee->ownSugar ), 3 ); + $coffee->ownSugar = R::dispense( 'sugar', 2 ); + $id = R::store( $coffee ); + $coffee = R::load( 'coffee', $id ); + asrt( count( $coffee->ownSugar ), 2 ); + $cocoa = R::dispense( 'cocoa' ); + $cocoa->name = 'Fair Cocoa'; + list( $taste1, $taste2 ) = R::dispense( 'taste', 2 ); + $taste1->name = 'sweet'; + $taste2->name = 'bitter'; + $cocoa->ownTaste = array( $taste1, $taste2 ); + R::store( $cocoa ); + $cocoa->name = 'Koko'; + R::store( $cocoa ); + if ( method_exists( R::getDatabaseAdapter()->getDatabase(), 'getPDO' ) ) { + $pdo = R::getDatabaseAdapter()->getDatabase()->getPDO(); + $driver = new RPDO( $pdo ); + pass(); + asrt( $pdo->getAttribute(\PDO::ATTR_ERRMODE ),\PDO::ERRMODE_EXCEPTION ); + asrt( $pdo->getAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE ),\PDO::FETCH_ASSOC ); + asrt( strval( $driver->GetCell( 'select 123' ) ), '123' ); + } + $a = new SQL; + $a->setSqlState( 'test' ); + $b = strval( $a ); + asrt( ( strpos( $b, '[test] - ' ) === 0 ), TRUE ); + } + + /** + * ENUM Basic tests. + * + * @return void + */ + public function testENUMBasics() { + asrt( R::enum( 'gender:male' )->name, 'MALE' ); + asrt( R::enum( 'country:South-Africa' )->name, 'SOUTH_AFRICA' ); + asrt( R::enum( 'tester:T@E S_t' )->name, 'T_E_S_T' ); + } + + /** + * Test ENUM in Queries and with short hand notation. + * + * @return void + */ + public function testENUMInQuery() + { + testpack('Test ENUM in Query and test ENUM short notation'); + R::nuke(); + $coffee = R::dispense( 'coffee' ); + $coffee->taste = R::enum( 'flavour:mocca' ); + R::store( $coffee ); + $coffee = R::dispense( 'coffee' ); + $coffee->taste = R::enum( 'flavour:banana' ); + R::store( $coffee ); + $coffee = R::dispense( 'coffee' ); + $coffee->taste = R::enum( 'flavour:banana' ); + R::store( $coffee ); + //now we have two flavours + asrt( R::count('flavour'), 2 ); + //use in query + asrt( R::count( 'coffee', ' taste_id = ? ', array( R::enum( 'flavour:mocca' )->id ) ), 1); + //use in quer with short notation + asrt( R::count( 'coffee', ' taste_id = ? ', array( EID( 'flavour:mocca' ) ) ), 1); + //use in query + asrt( R::count( 'coffee', ' taste_id = ? ', array( R::enum( 'flavour:banana' )->id ) ), 2); + //use in quer with short notation + asrt( R::count( 'coffee', ' taste_id = ? ', array( EID( 'flavour:banana' ) ) ), 2); + //use in query + asrt( R::count( 'coffee', ' taste_id = ? ', array( R::enum( 'flavour:strawberry' )->id ) ), 0); + //use in quer with short notation + asrt( R::count( 'coffee', ' taste_id = ? ', array( EID( 'flavour:strawberry' ) ) ), 0); + } + + /** + * Test ENUM functionality offered by Label Maker. + * + * @return void + */ + public function testENUM() { + testpack('test ENUM'); + $coffee = R::dispense( 'coffee' ); + $coffee->taste = R::enum( 'flavour:mocca' ); + //did we create an enum? + asrt( implode( '', R::gatherLabels( R::enum( 'flavour' ) ) ), 'MOCCA' ); + R::store( $coffee ); + $coffee = $coffee->fresh(); + //test enum identity check - with alias + asrt( $coffee->fetchAs( 'flavour' )->taste->equals( R::enum('flavour:mocca') ), TRUE ); + asrt( $coffee->fetchAs( 'flavour' )->taste->equals( R::enum('flavour:banana') ), FALSE ); + //now we have two flavours + asrt( R::count( 'flavour' ), 2 ); + asrt( implode( ',', R::gatherLabels( R::enum( 'flavour') ) ), 'BANANA,MOCCA' ); + $coffee->flavour = R::enum( 'flavour:mocca' ); + R::store($coffee); + //same results, can we have multiple flavours? + asrt( $coffee->fetchAs( 'flavour' )->taste->equals( R::enum( 'flavour:mocca' ) ), TRUE ); + asrt( $coffee->fetchAs( 'flavour' )->taste->equals( R::enum( 'flavour:banana' ) ), FALSE ); + asrt( $coffee->flavour->equals( R::enum( 'flavour:mocca' ) ), TRUE ); + //no additional mocca enum... + asrt( R::count( 'flavour' ), 2 ); + $drink = R::dispense( 'drink' ); + $drink->flavour = R::enum( 'flavour:choco' ); + R::store( $drink ); + //now we have three! + asrt( R::count('flavour'), 3 ); + $drink = R::load( 'drink', $drink->id ); + asrt( $drink->flavour->equals( R::enum('flavour:mint') ), FALSE ); + asrt( $drink->flavour->equals( R::enum('flavour:choco') ), TRUE ); + asrt( R::count( 'flavour' ), 4 ); + //trash should not affect flavour! + R::trash( $drink ); + asrt( R::count( 'flavour' ), 4 ); + } + + /** + * Test trashAll(). + */ + public function testMultiDeleteUpdate() + { + testpack( 'test multi delete and multi update' ); + $beans = R::dispenseLabels( 'bean', array( 'a', 'b' ) ); + $ids = R::storeAll( $beans ); + asrt( (int) R::count( 'bean' ), 2 ); + R::trashAll( R::batch( 'bean', $ids ) ); + asrt( (int) R::count( 'bean' ), 0 ); + testpack( 'test assocManager check' ); + $rb = new OODB( R::getWriter() ); + try { + $rb->getAssociationManager(); + fail(); + } catch ( RedException $e ) { + pass(); + } + } + + /** + * Test Bean identity equality. + */ + public function testBeanIdentityEquality() { + $beanA = R::dispense( 'bean' ); + $beanB = R::dispense( 'bean' ); + $beanA->id = 1; + $beanB->id = 1; + asrt( $beanA->equals( $beanB ), TRUE ); + asrt( $beanB->equals( $beanA ), TRUE ); + asrt( $beanA->equals( $beanA ), TRUE ); + asrt( $beanB->equals( $beanB ), TRUE ); + $beanB->id = 2; + asrt( $beanA->equals( $beanB ), FALSE ); + asrt( $beanB->equals( $beanA ), FALSE ); + $beanA->id = '2'; + asrt( $beanA->equals( $beanB ), TRUE ); + asrt( $beanB->equals( $beanA ), TRUE ); + $beanB = R::dispense( 'carrot' ); + $beanB->id = $beanA->id; + asrt( $beanA->equals( $beanB ), FALSE ); + asrt( $beanB->equals( $beanA ), FALSE ); + } + + /** + * Test if adding SimpleModles to a shared list will auto unbox them. + */ + public function testSharedListsAutoUnbox() { + $boxedBean = R::dispense( 'boxedbean' ); + $bean = R::dispense( 'bean' ); + $model = new SimpleModel(); + $model->loadBean($boxedBean); + $bean->ownBoxedbeanList[] = $model; + try { + R::store( $bean ); + pass(); + } catch ( \Exception $e ) { + fail(); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Namedparams.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Namedparams.php new file mode 100644 index 000000000..95d4b3137 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Namedparams.php @@ -0,0 +1,103 @@ +title = 'book'; + $book->sharedPage[] = $page; + R::store($book); + //should not give error like: Uncaught [HY093] - SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters + $books = $page->withCondition(' title = :title ', array( ':title' => 'book' ) )->sharedBook; + asrt( count( $books ), 1 ); + //should not give error... + $books = $page->withCondition( ' title = :title ', array( ':title' => 'book' ) )->sharedBook; + asrt( count( $books ), 1 ); + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->title = 'book'; + $book->comment = 'comment'; + $page->title = 'page'; + $book->ownPage[] = $page; + R::store( $book ); + //should also not give error.. + $count = $book->countOwn( 'page' ); + asrt( $count, 1 ); + $book = $book->fresh(); + //should also not give error.. + $count = $book->withCondition( ' title = ? ', array( 'page' ) )->countOwn( 'page' ); + asrt( $count, 1 ); + $book = $book->fresh(); + //should also not give error.. + $count = $book->withCondition( ' title = :title ', array( ':title' => 'page' ) )->countOwn( 'page' ); + asrt( $count, 1 ); + $book = $book->fresh(); + $pages = $book->withCondition( ' title = :title ', array( ':title' => 'page' ) )->ownPage; + asrt( count( $pages ), 1 ); + //test with duplicate slots... + $page = reset( $pages ); + $page2 = R::dispense( 'page' ); + $page2->ownPage[] = $page; + R::store( $page2 ); + $page2 = $page2->fresh(); + $pages = $page2->withCondition( ' title = :title ', array( ':title' => 'page' ) )->ownPage; + asrt( count( $pages ), 1 ); + //test with find() + $books = R::getRedBean()->find( 'book', + array( + 'title' => array('book')), + ' AND title = :title ', array(':title'=>'book')); + asrt( count( $books ), 1 ); + $books = R::getRedBean()->find( 'book', + array( + 'title' => array('book', 'book2'), + 'comment' => array('comment', 'comment2')), + ' AND title = :title ', array(':title'=>'book')); + asrt( count( $books ), 1 ); + //just check numeric works as well... + $books = R::getRedBean()->find( 'book', + array( + 'title' => array('book', 'book2'), + 'comment' => array('comment', 'comment2')), + ' AND title = ? ', array('book')); + asrt( count( $books ), 1 ); + //just extra check to verify glue works + $books = R::getRedBean()->find( 'book', + array( + 'title' => array('book', 'book2'), + 'comment' => array('comment', 'comment2')), + ' ORDER BY id '); + asrt( count( $books ), 1 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Nuke.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Nuke.php new file mode 100644 index 000000000..857e7c57e --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Nuke.php @@ -0,0 +1,47 @@ +getTables() ), 1 ); + R::nuke(); + asrt( count( R::getWriter()->getTables() ), 0 ); + $bean = R::dispense( 'bean' ); + R::store( $bean ); + asrt( count( R::getWriter()->getTables() ), 1 ); + R::freeze(); + R::nuke(); + // No effect + asrt( count( R::getWriter()->getTables() ), 1 ); + R::freeze( FALSE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Observers.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Observers.php new file mode 100644 index 000000000..ecd9b9d10 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Observers.php @@ -0,0 +1,55 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + asrt( ( $adapter instanceof DBAdapter ), TRUE ); + asrt( ( $writer instanceof QueryWriter ), TRUE ); + asrt( ( $redbean instanceof OODB ), TRUE ); + $observable = new \ObservableMock(); + $observer = new \ObserverMock(); + $observable->addEventListener( "event1", $observer ); + $observable->addEventListener( "event3", $observer ); + $observable->test( "event1", "testsignal1" ); + asrt( $observer->event, "event1" ); + asrt( $observer->info, "testsignal1" ); + $observable->test( "event2", "testsignal2" ); + asrt( $observer->event, "event1" ); + asrt( $observer->info, "testsignal1" ); + $observable->test( "event3", "testsignal3" ); + asrt( $observer->event, "event3" ); + asrt( $observer->info, "testsignal3" ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Performance.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Performance.php new file mode 100644 index 000000000..58fa3324e --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Performance.php @@ -0,0 +1,126 @@ +title = 'book'; + $pages = R::dispense( 'page', 10 ); + foreach( $pages as $page ) { + $page->content = 'lorem ipsum'; + $page->title = 'data'; + $page->sequence = 'data'; + $page->order = 'data'; + $page->columns = 'data'; + $page->paragraphs = 'data'; + $page->paragraphs1 = 'data'; + $page->paragraphs2 = 'data'; + $page->paragraphs3 = 'data'; + $page->paragraphs4 = 'data'; + } + $book->xownPageList = $pages; + $tags = R::dispense( 'tag', 6 ); + foreach( $tags as $tag ) { + $tag->label = 'tag'; + } + $book->sharedTagList = $tags; + R::store( $book ); + } + + /** + * CRUD performance. + * + * @return void + */ + public function crud() + { + R::freeze( TRUE ); + + $book = R::dispense( 'book' ); + $book->title = 'Book'; + $page = R::dispense('page'); + $page->content = 'Content'; + $page->title = 'data'; + $page->sequence = 'data'; + $page->order = 'data'; + $page->columns = 'data'; + $page->paragraphs = 'data'; + $page->paragraphs1 = 'data'; + $page->paragraphs2 = 'data'; + $page->paragraphs3 = 'data'; + $page->paragraphs4 = 'data'; + $tag = R::dispense('tag'); + $tag->label = 'Tag '; + $book->noLoad()->ownPage[] = $page; + $book->noLoad()->sharedTag[] = $tag; + R::store( $book ); + $book = $book->fresh(); + $book->ownPage; + $book->sharedTag; + R::trash( $book ); + + } + + /** + * CRUD performance Array Access. + * + * @return void + */ + public function crudaa() + { + R::freeze( TRUE ); + + $book = R::dispense( 'book' ); + $book['title'] = 'Book'; + $page = R::dispense('page'); + $page['content'] = 'Content'; + $page['title'] = 'data'; + $page['sequence'] = 'data'; + $page['order'] = 'data'; + $page['columns'] = 'data'; + $page['paragraphs'] = 'data'; + $page['paragraphs1'] = 'data'; + $page['paragraphs2'] = 'data'; + $page['paragraphs3'] = 'data'; + $page['paragraphs4'] = 'data'; + $tag = R::dispense('tag'); + $tag['label'] = 'Tag '; + $book->ownPage[] = $page; + $book->noLoad()->sharedTag[] = $tag; + R::store( $book ); + $book = $book->fresh(); + $book->ownPage; + $book->sharedTag; + R::trash( $book ); + + } +} \ No newline at end of file diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Prefixes.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Prefixes.php new file mode 100644 index 000000000..73d2564bc --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Prefixes.php @@ -0,0 +1,269 @@ +dispense($type); +}); + +define('BOOK', 'tbl_book'); +define('AUTHOR', 'tbl_author'); +define('COAUTHOR', 'coAuthor'); +define('FRIEND', 'tbl_friend'); +define('PUBLISHER', 'tbl_publisher'); +define('BOOKLIST', 'ownTbl_book'); +define('FRIENDLIST', 'sharedTbl_friend'); + +/** + * Prefixes + * + * Tests whether we can use tables with prefixes. + * Some people seem to like that. + * + * @file RedUNIT/Base/Prefixes.php + * @desc Tests whether you can use RedBeanPHP with table prefixes. + * @author Gabor de Mooij and the RedBeanPHP Community + * @license New BSD/GPLv2 + * + * (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community. + * This source file is subject to the New BSD/GPLv2 License that is bundled + * with this source code in the file license.txt. + */ +class Prefixes extends Base +{ + /** + * Test prerequisites. + */ + public function testPrerequisites() + { + R::nuke(); + $bean = R::xdispense( 'type_with_underscore' ); + asrt( ( $bean instanceof OODBBean ), TRUE ); + asrt( constant( 'BOOK' ), 'tbl_book' ); + asrt( constant( 'AUTHOR' ), 'tbl_author' ); + asrt( constant( 'PUBLISHER' ), 'tbl_publisher' ); + asrt( constant( 'FRIEND' ), 'tbl_friend' ); + asrt( constant( 'BOOKLIST' ), 'ownTbl_book' ); + asrt( constant( 'FRIENDLIST' ), 'sharedTbl_friend' ); + asrt( constant( 'COAUTHOR' ), 'coAuthor' ); + } + + /** + * Test basic CRUD operations. + */ + public function testBasicOperations() + { + //Can we dispense a naughty bean? (with underscore) + $author = R::xdispense( AUTHOR ); + asrt( ( $author instanceof OODBBean ), TRUE ); + asrt( $author->getMeta('type'), AUTHOR ); + $author->name = 'Mr. Quill'; + $book = R::xdispense( BOOK ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( $book->getMeta('type'), BOOK ); + $book->title = 'Good Stories'; + $friend = R::xdispense( FRIEND ); + $friend->name = 'Muse'; + asrt( ( $friend instanceof OODBBean ), TRUE ); + asrt( $friend->getMeta('type'), FRIEND ); + $publisher = R::xdispense( PUBLISHER ); + $publisher->name = 'Good Books'; + asrt( ( $publisher instanceof OODBBean ), TRUE ); + asrt( $publisher->getMeta('type'), PUBLISHER ); + asrt( is_array( $author->{BOOKLIST} ), TRUE ); + //add books to the book list using the constant + $author->{BOOKLIST}[] = $book; + asrt( count( $author->{BOOKLIST} ), 1 ); + //can we also add friends? (N-M) + $author->{FRIENDLIST}[] = $friend; + $author->{PUBLISHER} = $publisher; + $id = R::store( $author ); + asrt( ( $id > 0 ), TRUE ); + $author = $author->fresh(); + //Can we add another friend after reload? + $author->{FRIENDLIST}[] = R::xdispense( FRIEND )->setAttr( 'name', 'buddy' ); + R::store($author); + $author = $author->fresh(); + //Now check the contents of the bean, its lists (books,friends) and parent (publisher) + asrt( $author->name, 'Mr. Quill' ); + asrt( count( $author->{BOOKLIST} ), 1 ); + $firstBook = reset( $author->{BOOKLIST} ); + asrt( $firstBook->title, 'Good Stories' ); + asrt( count( $author->{FRIENDLIST} ), 2 ); + $firstFriend = reset( $author->{FRIENDLIST} ); + $parent = $author->{PUBLISHER}; + asrt( ( $parent instanceof OODBBean ), TRUE ); + $tables = R::inspect(); + //have all tables been prefixed? + foreach( $tables as $table ) asrt( strpos( $table, 'tbl_' ), 0 ); + //Can we make an export? + $export = R::exportAll( R::findOne( AUTHOR ), TRUE ); + $export = reset( $export ); + asrt( isset( $export[ PUBLISHER ] ), TRUE ); + asrt( isset( $export[ BOOKLIST ] ), TRUE ); + asrt( isset( $export[ FRIENDLIST ] ), TRUE ); + asrt( isset( $export[ 'ownBook' ] ), FALSE ); + asrt( isset( $export[ 'sharedFriend' ] ), FALSE ); + asrt( isset( $export[ 'publisher' ] ), FALSE ); + //Can we duplicate? + $copy = R::dup( $author ); + $copy->name = 'Mr. Clone'; + R::store( $copy ); + $copy = $copy->fresh(); + asrt( $copy->name, 'Mr. Clone' ); + asrt( count( $copy->{BOOKLIST} ), 1 ); + $firstBook = reset( $copy->{BOOKLIST} ); + asrt( $firstBook->title, 'Good Stories' ); + asrt( count( $copy->{FRIENDLIST} ), 2 ); + $firstFriend = reset( $copy->{FRIENDLIST} ); + $parent = $copy->{PUBLISHER}; + asrt( ( $parent instanceof OODBBean ), TRUE ); + //Can we count? + asrt( R::count( AUTHOR ), 2 ); + $copy = $copy->fresh(); + asrt( $copy->countOwn( BOOK ), 1 ); + asrt( $copy->countShared( FRIEND ), 2 ); + //Can we delete? + R::trash( $author ); + asrt( R::count( AUTHOR ), 1 ); + //Can we nuke? + R::nuke(); + asrt( R::count( AUTHOR ), 0 ); + asrt( count( R::inspect() ), 0 ); + } + + /** + * Test basic operations in frozen mode. + */ + public function testBasicOperationsFrozen() + { + R::nuke(); + $author = R::xdispense( AUTHOR ); + $author->name = 'Mr. Quill'; + $book = R::xdispense( BOOK ); + $book->title = 'Good Stories'; + $book2 = R::xdispense( BOOK ); + $book2->title = 'Good Stories 2'; + $friend = R::xdispense( FRIEND ); + $friend->name = 'Muse'; + $publisher = R::xdispense( PUBLISHER ); + $publisher->name = 'Good Books'; + $author->{BOOKLIST} = array( $book, $book2 ); + $author->{FRIENDLIST}[] = $friend; + $author->{PUBLISHER} = $publisher; + $coAuthor = R::xdispense( AUTHOR ); + $coAuthor->name = 'Xavier'; + $book2->{COAUTHOR} = $coAuthor; + R::store( $author ); + R::freeze( TRUE ); + asrt( $author->name, 'Mr. Quill' ); + asrt( count( $author->{BOOKLIST} ), 2 ); + $firstBook = reset( $author->{BOOKLIST} ); + asrt( $firstBook->title, 'Good Stories' ); + asrt( count( $author->{FRIENDLIST} ), 1 ); + $firstFriend = reset( $author->{FRIENDLIST} ); + $parent = $author->{PUBLISHER}; + asrt( ( $parent instanceof OODBBean ), TRUE ); + $tables = R::inspect(); + //have all tables been prefixed? + foreach( $tables as $table ) asrt( strpos( $table, 'tbl_' ), 0 ); + //Can we make an export? + $export = R::exportAll( R::findOne( AUTHOR ), TRUE ); + $export = reset( $export ); + asrt( isset( $export[ PUBLISHER ] ), TRUE ); + asrt( isset( $export[ BOOKLIST ] ), TRUE ); + asrt( isset( $export[ FRIENDLIST ] ), TRUE ); + asrt( isset( $export[ 'ownBook' ] ), FALSE ); + asrt( isset( $export[ 'sharedFriend' ] ), FALSE ); + asrt( isset( $export[ 'publisher' ] ), FALSE ); + R::freeze( FALSE ); + } + + /** + * Test conditions and aliases. + */ + public function testConditionsAndAliases() + { + R::nuke(); + $author = R::xdispense( AUTHOR ); + $author->name = 'Mr. Quill'; + $book = R::xdispense( BOOK ); + $book->title = 'Good Stories'; + $book2 = R::xdispense( BOOK ); + $book2->title = 'Good Stories 2'; + $friend = R::xdispense( FRIEND ); + $friend->name = 'Muse'; + $publisher = R::xdispense( PUBLISHER ); + $publisher->name = 'Good Books'; + $author->{BOOKLIST} = array( $book, $book2 ); + $author->{FRIENDLIST}[] = $friend; + $author->{PUBLISHER} = $publisher; + $coAuthor = R::xdispense( AUTHOR ); + $coAuthor->name = 'Xavier'; + $book2->{COAUTHOR} = $coAuthor; + R::store( $author ); + $author = $author->fresh(); + asrt( R::count( AUTHOR ), 2 ); + //Can we use with and withCondition? + asrt( count( $author->{BOOKLIST} ), 2 ); + asrt( count( $author->with(' LIMIT 1 ')->{BOOKLIST} ), 1 ); + asrt( count( $author->withCondition(' title LIKE ? ', array( '%2%' ) )->{BOOKLIST} ), 1 ); + //Can we use an alias? + $book2 = $book2->fresh(); + asrt( $book2->fetchAs( AUTHOR )->{COAUTHOR}->name, 'Xavier' ); + $coAuthor = $book2->fetchAs( AUTHOR )->{COAUTHOR}->fresh(); + asrt( count( $coAuthor->alias( COAUTHOR )->{BOOKLIST} ), 1 ); + } + + /** + * Test prettier tables using via(). + */ + public function testViaPrettification() + { + R::nuke(); + R::renameAssociation( 'tbl_author_tbl_friend', 'tbl_author_friend' ); + $author = R::xdispense( AUTHOR ); + $author->name = 'Mr. Quill'; + $friend = R::xdispense( FRIEND ); + $friend->name = 'Muse'; + $author->{FRIENDLIST}[] = $friend; + $id = R::store( $author ); + //print_r(R::inspect()); exit; + $author = R::load( AUTHOR, $id ); + $tables = array_flip( R::inspect() ); + asrt( isset( $tables[ 'tbl_author_friend' ] ), TRUE ); + asrt( isset( $tables[ 'tbl_author_tbl_friend' ] ), FALSE ); + asrt( count( $author->{FRIENDLIST} ), 1 ); + AQueryWriter::clearRenames(); + } + + /** + * Test self-referential N-M relations. + */ + public function testSelfRefNM() + { + R::nuke(); + $friend1 = R::xdispense( FRIEND ); + $friend1->name = 'f1'; + $friend2 = R::xdispense( FRIEND ); + $friend2->name = 'f2'; + $friend3 = R::xdispense( FRIEND ); + $friend3->name = 'f3'; + $friend1->{FRIENDLIST} = array( $friend2, $friend3 ); + $friend3->{FRIENDLIST} = array( $friend1 ); + R::storeAll( array( $friend1, $friend2, $friend3 ) ); + $friend1 = $friend1->fresh(); + $friend2 = $friend2->fresh(); + $friend3 = $friend3->fresh(); + asrt( count( $friend1->{FRIENDLIST} ), 2 ); + asrt( count( $friend2->{FRIENDLIST} ), 1 ); + asrt( count( $friend3->{FRIENDLIST} ), 1 ); + $friend = reset( $friend3->{FRIENDLIST} ); + asrt( $friend->name, 'f1' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/PullRequest530.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/PullRequest530.php new file mode 100644 index 000000000..e22ba87e1 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/PullRequest530.php @@ -0,0 +1,54 @@ +if ($bean->$linkField != $id) $bean->$linkField = $id; + * + * @return void + */ + public function testPullRequest530() + { + testpack( 'Testing Pull Request #530 - OODBBean __set() checks if $property is a field link' ); + R::freeze(false); + R::setAutoResolve(true); + $linkedObjects = R::dispense('linkedobject', 2); + R::storeAll($linkedObjects); + $tester = R::dispense('parent'); + $tester->linked = $linkedObjects[0]; + R::store($tester); + $tester = R::findOne('parent'); + asrt($tester->linked->id, $linkedObjects[0]->id); + $tester->linked_id = $linkedObjects[1]->id; + R::store($tester); + asrt($tester->linked->id, $linkedObjects[1]->id); + } +} + +?> diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Relations.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Relations.php new file mode 100644 index 000000000..cde555625 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Relations.php @@ -0,0 +1,1250 @@ +author = $author; + $book->author->name = 'x'; + $book->author->setMeta( 'tainted', false ); + R::store( $book ); + $author = $author->fresh(); + asrt( isset( $author->name ), false ); + } + + /** + * Tests whether via() applies camelcase-to-snakecase + * conversion. Although most of the time you do not need + * this since via() is meant to remap typical link tables + * to bean - but alas. + * + * @return void + */ + public function testCamelCasingVia() + { + R::nuke(); + $book = R::dispense('book'); + $book->sharedPage[] = R::dispense('page'); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book->via('bookPage')->sharedPage ), 1 ); + $book = $book->fresh(); + asrt( count( $book->via('book_page')->sharedPage ), 1 ); + } + + /** + * Test whether we can't add more than one FK. + */ + public function testDuplicateFK() + { + R::nuke(); + list( $book, $page ) = R::dispenseAll( 'book,page' ); + $book->sharedPage[] = $page; + R::store( $page ); + R::store( $book ); + $writer = R::getWriter(); + $added1 = $writer->addFK( 'book_page', 'book', 'book_id', 'id', TRUE ); + $added2 = $writer->addFK( 'book_page', 'page', 'page_id', 'id', TRUE ); + $added = ( $added1 && $added2 ); + asrt( $added, FALSE ); + } + + /** + * Test whether ->all() reloads a list. + * + * @return void + */ + public function testAllPrefix() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book->ownPage = R::dispense( 'page', 10 ); + $book->sharedTag = R::dispense( 'tag', 2 ); + $i = 0; + foreach( $book->ownPage as $page ) { + $page->pageno = $i++; + } + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book->ownPage ), 10 ); + asrt( count( $book->withCondition(' pageno < 5 ')->ownPage ), 5 ); + asrt( count( $book->ownPage ), 5 ); + asrt( count( $book->all()->ownPage ), 10 ); + asrt( count( $book->with(' LIMIT 3 ')->ownPage ), 3 ); + asrt( count( $book->ownPage ), 3 ); + asrt( count( $book->all()->ownPage ), 10 ); + asrt( count( $book->sharedTag ), 2 ); + asrt( count( $book->with( ' LIMIT 1 ' )->sharedTag ), 1 ); + asrt( count( $book->sharedTag ), 1 ); + asrt( count( $book->all()->sharedTag ), 2 ); + } + + /** + * Test Relations and conditions. + * + * @return void + */ + public function testRelationsAndConditions() + { + list( $book1, $book2 ) = R::dispense( 'book', 2 ); + list( $page1, $page2, $page3, $page4 ) = R::dispense( 'page', 4 ); + list( $author1, $author2 ) = R::dispense( 'author', 2 ); + $book1->title = 'a'; + $book2->title = 'b'; + $page1->thename = '1'; + $page2->thename = '2'; + $page3->thename = '3'; + $page3->thename = '4'; + $book1->ownPage = array( $page1, $page2 ); + $book2->ownPage = array( $page3, $page4 ); + $author1->sharedBook = array( $book1, $book2 ); + $author2->sharedBook = array( $book2 ); + R::storeAll( array( $author1, $author2 ) ); + asrt( count( $author1->sharedBook ), 2 ); + asrt( count( $author1->withCondition( ' title = ? ', array( 'a' ) )->sharedBook ), 1 ); + R::store( $author1 ); + asrt( count( $author1->sharedBook ), 2 ); + asrt( count( $author1->withCondition( ' xtitle = ? ', array( 'a' ) )->sharedBook ), 0 ); + R::store( $author1 ); + asrt( count( $author1->sharedBook ), 2 ); + $book1 = R::load( 'book', $book1->id ); + $book2 = $book2->fresh(); + asrt( count( $book1->ownPage ), 2 ); + asrt( count( $book1->with( ' LIMIT 1 ' )->ownPage ), 1 ); + $book1 = $book1->fresh(); + asrt( count( $book1->ownPage ), 2 ); + asrt( count( $book1->withCondition( ' thename = ? ', array( '1' ) )->ownPage ), 1 ); + } + + /** + * Test filtering relations on links (using columns in the link table). + * + * @return void + */ + public function testSharedLinkCond() + { + testpack( 'Test new shared relations with link conditions' ); + $w = R::getWriter(); + list( $b1, $b2 ) = R::dispense( 'book', 2 ); + $b1->name = 'book1'; + $b2->name = 'book2'; + list( $p1, $p2, $p3 ) = R::dispense( 'page', 3 ); + $p1->text = 'page1'; + $p1->number = 3; + $p2->text = 'page2'; + $p3->text = 'page3'; + $b1->link( 'book_page', array( 'order' => 1 ) )->page = $p1; + $b1->link( 'bookPage', array( 'order' => 2 ) )->page = $p2; + $b2->link( 'book_page', array( 'order' => 1 ) )->page = $p3; + $b2->link( 'bookPage', array( 'order' => 2 ) )->page = $p2; + $b2->link( 'book_page', array( 'order' => 3 ) )->page = $p1; + R::storeAll( array( $b1, $b2 ) ); + $b1 = R::load( 'book', $b1->id ); + $b2 = R::load( 'book', $b2->id ); + $pages = $b1->withCondition( ' book_page.' . $w->esc( 'order' ) . ' = 2 ' )->sharedPage; + $page = reset( $pages ); + asrt( $page->text, 'page2' ); + $pages = $b2->withCondition( ' ' . $w->esc( 'order' ) . ' = 3 ' )->sharedPage; + $page = reset( $pages ); + asrt( $page->text, 'page1' ); + $b1 = R::load( 'book', $b1->id ); + $b2 = R::load( 'book', $b2->id ); + $pages = $b1->withCondition( ' book_page.' . $w->esc( 'order' ) . ' < 3 AND page.number = 3' )->sharedPage; + $page = reset( $pages ); + asrt( $page->text, 'page1' ); + $pages = $b2->withCondition( ' ' . $w->esc( 'order' ) . ' > 1 ORDER BY book_page.' . $w->esc( 'order' ) . ' ASC ' )->sharedPage; + $page = array_shift( $pages ); + asrt( $page->text, 'page2' ); + $page = array_shift( $pages ); + asrt( $page->text, 'page1' ); + testpack( 'Test new shared relations and cache' ); + + /** + * why does this not destroy cache in psql? + * ah: An error occurred: SQLSTATE[42703]: Undefined column: 7 + * ERROR: column "page" of relation "page" does not exist + */ + R::exec( 'UPDATE page SET ' . $w->esc( 'number' ) . ' = 1 ' ); + R::getWriter()->setUseCache( TRUE ); + $p1 = R::load( 'page', (int) $p1->id ); + // Someone else changes the records. Cache remains. + R::exec( ' UPDATE page SET ' . $w->esc( 'number' ) . ' = 9 -- keep-cache' ); + $b1 = R::load( 'book', $b1->id ); + $p1 = R::load( 'page', (int) $p1->id ); + // Yupz a stale cache, phantom read! + asrt( (int) $p1->number, 1 ); + $pages = $b1->withCondition( ' book_page.' . $w->esc( 'order' ) . ' = 1 ' )->sharedPage; + $page = reset( $pages ); + // Inconsistent, sad but TRUE, different query -> cache key is different + asrt( (int) $page->number, 9 ); + // However, cache must have been invalidated by this query + $p1 = R::load( 'page', (int) $p1->id ); + // Yes! we're consistent again! -- as if the change just happened later! + asrt( (int) $page->number, 9 ); + // By doing this we keep getting 9 instead of 8 + $b1->fresh()->withCondition( ' book_page.' . $w->esc( 'order' ) . ' = 1 ' )->sharedPage; + // Someone else is busy again... + R::exec( ' UPDATE page SET ' . $w->esc( 'number' ) . ' = 8 -- keep-cache' ); + $b1 = R::load( 'book', $b1->id ); + $pages = $b1->withCondition( ' book_page.' . $w->esc( 'order' ) . ' = 1 ' )->sharedPage; + $page = reset( $pages ); + + /** + * yes! we get 9 instead of 8, why because the cache key has not changed, + * our last query was PAGE-BOOK-RELATION and now we ask for + * PAGE-BOOK-RELATION again. if we would have used just a load page + * query we would have gotten the new value (8).... let's test that! + */ + asrt( (int) $page->number, 9 ); + R::exec( ' UPDATE page SET ' . $w->esc( 'number' ) . ' = 9' ); + $p1 = R::load( 'page', (int) $p1->id ); + asrt( (int) $page->number, 9 ); + // Someone else is busy again... + R::exec( ' UPDATE page SET ' . $w->esc( 'number' ) . ' = 8 -- keep-cache' ); + $b1 = R::load( 'book', $b1->id ); + $pages = $b1->withCondition( ' book_page.' . $w->esc( 'order' ) . ' = 1 ' )->sharedPage; + $page = reset( $pages ); + // Yes, keep-cache wont help, cache key changed! + asrt( (int) $page->number, 8 ); + R::getWriter()->setUseCache( FALSE ); + } + + /** + * Test related count using via(). + * + * @return void + */ + public function testRelatedCountVia() + { + testpack( 'Test relatedCount with via()' ); + $shop = R::dispense( 'shop' ); + $shop->ownRelation = R::dispense( 'relation', 13 ); + foreach ( $shop->ownRelation as $relation ) { + $relation->shop = $shop; + $relation->customer = R::dispense( 'customer' ); + } + R::store( $shop ); + $shop = $shop->fresh(); + asrt( $shop->via( 'relation' )->countShared( 'customer' ), 13 ); + } + + /** + * Test counting and aliasing. + * + * @return void + */ + public function testCountingAndAliasing() + { + $book = R::dispense( 'book' ); + $book->ownPage = R::dispense( 'page', 10 ); + $book2 = R::dispense( 'book' ); + $book2->ownPage = R::dispense( 'page', 4 ); + list( $Bill, $James, $Andy ) = R::dispense( 'person', 3 ); + $book->author = $Bill; + $book->coAuthor = $James; + $book2->author = $Bill; + $book2->coAuthor = $Andy; + $book->price = 25; + $book2->price = 50; + $notes = R::dispense( 'note', 10 ); + $book->sharedNote = array( $notes[0], $notes[1], $notes[2] ); + $book2->sharedNote = array( $notes[3], $notes[4], $notes[1], $notes[0] ); + $books = R::dispense( 'book', 5 ); + $books[2]->title = 'boe'; + $book->sharedBook = array( $books[0], $books[1] ); + $book2->sharedBook = array( $books[0], $books[2], $books[4] ); + R::storeAll( array( $book, $book2 ) ); + asrt( $book->countOwn( 'page' ), 10 ); + asrt( $book->withCondition( ' id < 5 ' )->countOwn( 'page' ), 4 ); + asrt( $Bill->alias( 'author' )->countOwn( 'book' ), 2 ); + asrt( $Andy->alias( 'coAuthor' )->countOwn( 'book' ), 1 ); + asrt( $James->alias( 'coAuthor' )->countOwn( 'book' ), 1 ); + asrt( $Bill->alias( 'author' )->countOwn( 'book' ), 2 ); + asrt( $book->countShared( 'note' ), 3 ); + asrt( $book2->countShared( 'note' ), 4 ); + asrt( $book2->countShared( 'book' ), 3 ); + $book2 = $book2->fresh(); + asrt( $book2->withCondition( ' title = ? ', array( 'boe' ) )->countShared( 'book' ), 1 ); + } + + /** + * Test via. + * + * @return void + */ + public function testVia() + { + testpack( 'Test via()' ); + $d = R::dispense( 'doctor' )->setAttr( 'name', 'd1' ); + $p = R::dispense( 'patient' )->setAttr( 'name', 'p1' ); + $d->via( 'consult' )->sharedPatient[] = $p; + R::store( $d ); + $d = R::load( 'doctor', $d->id ); + asrt( count( $d->sharedPatient ), 1 ); + asrt( in_array( 'consult', R::getWriter()->getTables() ), TRUE ); + } + + /** + * Issue #348 via() should reload shared list + * + * @return void + */ + public function testIssue348() + { + $product = R::dispense( 'product' ); + $product->name = 'test'; + $color = R::dispense( 'color' ); + $color->name = 'cname'; + $color->code = 'ccode'; + R::store( $product ); + R::store( $color ); + $product->link( 'productColor', array( + 'stock' => 1, + 'position' => 0 + ) )->color = $color; + R::store( $product ); + asrt( count( $product->sharedColor ), 0 ); + asrt( count( $product->via( 'product_color' )->sharedColor ), 1 ); + asrt( count( $product->sharedColor ), 1 ); + R::renameAssociation( 'color_product', NULL ); + } + + /** + * Test creation of link table. + * + * @return void + */ + public function testCreationOfLinkTable() + { + asrt( in_array( 'consult', R::getWriter()->getTables() ), FALSE ); + $d = R::dispense( 'doctor' )->setAttr( 'name', 'd1' ); + $p = R::dispense( 'patient' )->setAttr( 'name', 'p1' ); + $d->sharedPatient[] = $p; + R::store($d); + asrt( in_array( 'consult', R::getWriter()->getTables() ), TRUE ); + } + + /** + * Fast track link block code should not affect self-referential N-M relations. + * + * @return void + */ + public function testFastTrackRelations() + { + testpack( 'Test fast-track linkBlock exceptions' ); + list( $donald, $mickey, $goofy, $pluto ) = R::dispense( 'friend', 4 ); + $donald->name = 'D'; + $mickey->name = 'M'; + $goofy->name = 'G'; + $pluto->name = 'P'; + $donald->sharedFriend = array( $mickey, $goofy ); + $mickey->sharedFriend = array( $pluto, $goofy ); + $mickey->sharedBook = array( R::dispense( 'book' ) ); + R::storeAll( array( $mickey, $donald, $goofy, $pluto ) ); + $donald = R::load( 'friend', $donald->id ); + $mickey = R::load( 'friend', $mickey->id ); + $goofy = R::load( 'friend', $goofy->id ); + $pluto = R::load( 'friend', $pluto->id ); + $names = implode( ',', R::gatherLabels( $donald->sharedFriend ) ); + asrt( $names, 'G,M' ); + $names = implode( ',', R::gatherLabels( $goofy->sharedFriend ) ); + asrt( $names, 'D,M' ); + $names = implode( ',', R::gatherLabels( $mickey->sharedFriend ) ); + asrt( $names, 'D,G,P' ); + $names = implode( ',', R::gatherLabels( $pluto->sharedFriend ) ); + asrt( $names, 'M' ); + // Now in combination with with() conditions... + $donald = R::load( 'friend', $donald->id ); + $names = implode( ',', R::gatherLabels( $donald->withCondition( ' name = ? ', array( 'M' ) )->sharedFriend ) ); + asrt( $names, 'M' ); + // Now in combination with with() conditions... + $donald = R::load( 'friend', $donald->id ); + $names = implode( ',', R::gatherLabels( $donald->with( ' ORDER BY name ' )->sharedFriend ) ); + asrt( $names, 'G,M' ); + // Now counting + $goofy = R::load( 'friend', $goofy->id ); + asrt( (int) $goofy->countShared( 'friend' ), 2 ); + asrt( (int) $donald->countShared( 'friend' ), 2 ); + asrt( (int) $mickey->countShared( 'friend' ), 3 ); + asrt( (int) $pluto->countShared( 'friend' ), 1 ); + } + + /** + * Test list beautifications. + * + * @return void + */ + public function testListBeautifications() + { + testpack( 'Test list beautifications' ); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' )->setAttr( 'name', 'a' ); + $book->sharedPage[] = $page; + $id = R::store( $book ); + $book = R::load( 'book', $id ); + $p = reset( $book->ownBookPage ); + asrt( $p->page->name, 'a' ); + $bean = R::dispense( 'bean' ); + $bean->sharedAclRole[] = R::dispense( 'role' )->setAttr( 'name', 'x' ); + R::store( $bean ); + asrt( R::count( 'role' ), 1 ); + $aclrole = R::getRedBean()->dispense( 'acl_role' ); + $aclrole->name = 'role'; + $bean = R::dispense( 'bean' ); + $bean->sharedAclRole[] = $aclrole; + R::store( $bean ); + asrt( count( $bean->sharedAclRole ), 1 ); + } + + /** + * Test list add and delete. + * + * @return void + */ + public function testListAddDelete() + { + testpack( 'Test list add/delete scenarios.' ); + R::nuke(); + $b = R::dispense( 'book' ); + $p = R::dispense( 'page' ); + $b->title = 'a'; + $p->name = 'b'; + $b->xownPage[] = $p; + R::store( $b ); + $b->xownPage = array(); + R::store( $b ); + asrt( R::count( 'page' ), 0 ); + $p = R::dispense( 'page' ); + $z = R::dispense( 'paper' ); + $z->xownPage[] = $p; + R::store( $z ); + asrt( R::count( 'page' ), 1 ); + $z->xownPage = array(); + R::store( $z ); + asrt( R::count( 'page' ), 0 ); + $i = R::dispense( 'magazine' ); + $i->ownPage[] = R::dispense( 'page' ); + R::store( $i ); + asrt( R::count( 'page' ), 1 ); + $i->ownPage = array(); + R::store( $i ); + asrt( R::count( 'page' ), 1 ); + } + + /** + * Test basic and complex common usage scenarios for + * relations and associations. + * + * @return void + */ + public function testScenarios() + { + list( $q1, $q2 ) = R::dispense( 'quote', 2 ); + list( $pic1, $pic2 ) = R::dispense( 'picture', 2 ); + list( $book, $book2, $book3 ) = R::dispense( 'book', 4 ); + list( $topic1, $topic2, $topic3, $topic4, $topic5 ) = R::dispense( 'topic', 5 ); + list( $page1, $page2, $page3, $page4, $page5, $page6, $page7 ) = R::dispense( 'page', 7 ); + $q1->text = 'lorem'; + $q2->text = 'ipsum'; + $book->title = 'abc'; + $book2->title = 'def'; + $book3->title = 'ghi'; + $page1->title = 'pagina1'; + $page2->title = 'pagina2'; + $page3->title = 'pagina3'; + $page4->title = 'pagina4'; + $page5->title = 'pagina5'; + $page6->title = 'cover1'; + $page7->title = 'cover2'; + $topic1->name = 'holiday'; + $topic2->name = 'cooking'; + $topic3->name = 'gardening'; + $topic4->name = 'computing'; + $topic5->name = 'christmas'; + // Add one page to the book + $book->ownPage[] = $page1; + $id = R::store( $book ); + asrt( count( $book->ownPage ), 1 ); + asrt( reset( $book->ownPage )->getMeta( 'type' ), 'page' ); + $book = R::load( 'book', $id ); + asrt( count( $book->ownPage ), 1 ); + asrt( reset( $book->ownPage )->getMeta( 'type' ), 'page' ); + // Performing an own addition + $book->ownPage[] = $page2; + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( count( $book->ownPage ), 2 ); + // Performing a deletion + $book = R::load( 'book', $id ); + unset( $book->ownPage[1] ); + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( count( $book->ownPage ), 1 ); + asrt( reset( $book->ownPage )->getMeta( 'type' ), 'page' ); + asrt( R::count( 'page' ), 2 ); //still exists + asrt( reset( $book->ownPage )->id, '2' ); + // Doing a change in one of the owned items + $book->ownPage[2]->title = 'page II'; + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( reset( $book->ownPage )->title, 'page II' ); + // Change by reference now... don't copy! + $refToPage2 = $book->ownPage[2]; + $refToPage2->title = 'page II b'; + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( reset( $book->ownPage )->title, 'page II b' ); + // Doing all actions combined + $book->ownPage[] = $page3; + R::store( $book ); + $book = R::load( 'book', $id ); + unset( $book->ownPage[2] ); + // And test custom key + $book->ownPage['customkey'] = $page4; + $book->ownPage[3]->title = "THIRD"; + R::store( $book ); + $book = R::load( 'book', $id ); + asrt( count( $book->ownPage ), 2 ); + $p4 = $book->ownPage[4]; + $p3 = $book->ownPage[3]; + asrt( $p4->title, 'pagina4' ); + asrt( $p3->title, 'THIRD' ); + // Test replacing an element + $book = R::load( 'book', $id ); + $book->ownPage[4] = $page5; + R::store( $book ); + $book = R::load( 'book', $id ); + asrt( count( $book->ownPage ), 2 ); + $p5 = $book->ownPage[5]; + asrt( $p5->title, 'pagina5' ); + // Other way around - single bean + asrt( $p5->book->title, 'abc' ); + asrt( R::load( 'page', 5 )->book->title, 'abc' ); + asrt( R::load( 'page', 3 )->book->title, 'abc' ); + // Add the other way around - single bean + $page1->id = 0; + $page1->book = $book2; + $page1 = R::load( 'page', R::store( $page1 ) ); + asrt( $page1->book->title, 'def' ); + $b2 = R::load( 'book', $id ); + asrt( count( $b2->ownPage ), 2 ); + // Remove the other way around - single bean + unset( $page1->book ); + R::store( $page1 ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 1 ); //does not work + $page1->book = NULL; + R::store( $page1 ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 0 ); //works + // Re-add the page + $b2->ownPage[] = $page1; + R::store( $b2 ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 1 ); + // Different, less elegant way to remove + $page1 = reset( $b2->ownPage ); + $page1->book_id = NULL; + R::store( $page1 ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 0 ); + // Re-add the page + $b2->ownPage[] = $page1; + R::store( $b2 ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 1 ); + // Another less elegant way to remove + $page1->book = NULL; + R::store( $page1 ); + $cols = R::getColumns( 'page' ); + asrt( isset( $cols['book'] ), FALSE ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 0 ); + // Re-add the page + $b2->ownPage[] = $page1; + R::store( $b2 ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 1 ); + // Another less elegant... just plain ugly... way to remove + $page1->book = FALSE; + R::store( $page1 ); + $cols = R::getColumns( 'page' ); + asrt( isset( $cols['book'] ), FALSE ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 0 ); + // Re-add the page + $b2->ownPage[] = $page1; + R::store( $b2 ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 1 ); + // You are not allowed to re-use the field for something else + foreach ( + array( + 1, -2.1, array(), + TRUE, 'NULL', new \stdClass, + 'just a string', array( 'a' => 1 ), 0 + ) as $value + ) { + try { + $page1->book = $value; + fail(); + } catch ( RedException $e ) { + pass(); + } + } + // Test fk, not allowed to set to 0 + $page1 = reset( $b2->ownPage ); + $page1->book_id = 0; + // Even uglier way, but still needs to work + $page1 = reset( $b2->ownPage ); + $page1->book_id = NULL; + R::store( $b2 ); + $b2 = R::load( 'book', $book2->id ); + asrt( count( $b2->ownPage ), 0 ); + // Test shared items + $book = R::load( 'book', $id ); + $book->sharedTopic[] = $topic1; + $id = R::store( $book ); + // Add an item + asrt( count( $book->sharedTopic ), 1 ); + asrt( reset( $book->sharedTopic )->name, 'holiday' ); + $book = R::load( 'book', $id ); + asrt( count( $book->sharedTopic ), 1 ); + asrt( reset( $book->sharedTopic )->name, 'holiday' ); + // Add another item + $book->sharedTopic[] = $topic2; + $id = R::store( $book ); + $tidx = R::store( R::dispense( 'topic' ) ); + $book = R::load( 'book', $id ); + asrt( count( $book->sharedTopic ), 2 ); + $t1 = $book->sharedTopic[1]; + $t2 = $book->sharedTopic[2]; + asrt( $t1->name, 'holiday' ); + asrt( $t2->name, 'cooking' ); + // Remove an item + unset( $book->sharedTopic[2] ); + asrt( count( $book->sharedTopic ), 1 ); + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( count( $book->sharedTopic ), 1 ); + asrt( reset( $book->sharedTopic )->name, 'holiday' ); + // Add and change + $book->sharedTopic[] = $topic3; + $book->sharedTopic[1]->name = 'tropics'; + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( count( $book->sharedTopic ), 2 ); + asrt( $book->sharedTopic[1]->name, 'tropics' ); + testids( $book->sharedTopic ); + R::trash( R::load( 'topic', $tidx ) ); + $id = R::store( $book ); + $book = R::load( 'book', $id ); + // Delete without save + unset( $book->sharedTopic[1] ); + $book = R::load( 'book', $id ); + asrt( count( $book->sharedTopic ), 2 ); + $book = R::load( 'book', $id ); + // Delete without init + asrt( ( R::count( 'topic' ) ), 3 ); + unset( $book->sharedTopic[1] ); + $id = R::store( $book ); + asrt( ( R::count( 'topic' ) ), 3 ); + asrt( count( $book->sharedTopic ), 1 ); + asrt( count( $book2->sharedTopic ), 0 ); + // Add same topic to other book + $book2->sharedTopic[] = $topic3; + asrt( count( $book2->sharedTopic ), 1 ); + $id2 = R::store( $book2 ); + asrt( count( $book2->sharedTopic ), 1 ); + $book2 = R::load( 'book', $id2 ); + asrt( count( $book2->sharedTopic ), 1 ); + // Get books for topic + asrt( $topic3->countShared('book'), 2 ); + $t3 = R::load( 'topic', $topic3->id ); + asrt( count( $t3->sharedBook ), 2 ); + // Nuke an own-array, replace entire array at once without getting first + $page2->id = 0; + $page2->title = 'yet another page 2'; + $page4->id = 0; + $page4->title = 'yet another page 4'; + $book = R::load( 'book', $id ); + $book->ownPage = array( $page2, $page4 ); + R::store( $book ); + $book = R::load( 'book', $id ); + asrt( count( $book->ownPage ), 2 ); + asrt( reset( $book->ownPage )->title, 'yet another page 2' ); + asrt( end( $book->ownPage )->title, 'yet another page 4' ); + testids( $book->ownPage ); + // Test with alias format + $book3->cover = $page6; + $idb3 = R::store( $book3 ); + $book3 = R::load( 'book', $idb3 ); + $justACover = $book3->fetchAs( 'page' )->cover; + asrt( ( $book3->cover instanceof OODBBean ), TRUE ); + asrt( $justACover->title, 'cover1' ); + // No page property + asrt( isset( $book3->page ), FALSE ); + // Test doubling and other side effects ... should not occur.. + $book3->sharedTopic = array( $topic1, $topic2 ); + $book3 = R::load( 'book', R::store( $book3 ) ); + $book3->sharedTopic = array(); + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( count( $book3->sharedTopic ), 0 ); + $book3->sharedTopic[] = $topic1; + $book3 = R::load( 'book', R::store( $book3 ) ); + // Added only one, not more? + asrt( count( $book3->sharedTopic ), 1 ); + asrt( intval( R::getCell( "select count(*) from book_topic where book_id = $idb3" ) ), 1 ); + // Add the same + $book3->sharedTopic[] = $topic1; + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( count( $book3->sharedTopic ), 1 ); + asrt( intval( R::getCell( "select count(*) from book_topic where book_id = $idb3" ) ), 1 ); + $book3->sharedTopic['differentkey'] = $topic1; + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( count( $book3->sharedTopic ), 1 ); + asrt( intval( R::getCell( "select count(*) from book_topic where book_id = $idb3" ) ), 1 ); + // Ugly assign, auto array generation + $book3->ownPage[] = $page1; + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( count( $book3->ownPage ), 1 ); + asrt( intval( R::getCell( "select count(*) from page where book_id = $idb3 " ) ), 1 ); + $book3 = R::load( 'book', $idb3 ); + $book3->ownPage = array(); + // No change until saved + asrt( intval( R::getCell( "select count(*) from page where book_id = $idb3 " ) ), 1 ); + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( intval( R::getCell( "select count(*) from page where book_id = $idb3 " ) ), 0 ); + asrt( count( $book3->ownPage ), 0 ); + $book3 = R::load( 'book', $idb3 ); + /** + * Why do I need to do this ---> why does trash() not set id -> 0? + * Because you unset() so trash is done on origin not bean + */ + $page1->id = 0; + $page2->id = 0; + $page3->id = 0; + $book3->ownPage[] = $page1; + $book3->ownPage[] = $page2; + $book3->ownPage[] = $page3; + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( intval( R::getCell( "select count(*) from page where book_id = $idb3 " ) ), 3 ); + asrt( count( $book3->ownPage ), 3 ); + unset( $book3->ownPage[$page2->id] ); + $book3->ownPage[] = $page3; + $book3->ownPage['try_to_trick_ya'] = $page3; + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( intval( R::getCell( "select count(*) from page where book_id = $idb3 " ) ), 2 ); + asrt( count( $book3->ownPage ), 2 ); + // Delete and re-add + $book3 = R::load( 'book', $idb3 ); + unset( $book3->ownPage[10] ); + $book3->ownPage[] = $page1; + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( count( $book3->ownPage ), 2 ); + $book3 = R::load( 'book', $idb3 ); + unset( $book3->sharedTopic[1] ); + $book3->sharedTopic[] = $topic1; + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( count( $book3->sharedTopic ), 1 ); + // Test performance + $logger = R::debug( true, 1 ); + $book = R::load( 'book', 1 ); + $book->sharedTopic = array(); + R::store( $book ); + // No more than 1 update + asrt( count( $logger->grep( 'UPDATE' ) ), 1 ); + $book = R::load( 'book', 1 ); + $logger->clear(); + print_r( $book->sharedTopic, 1 ); + // No more than 1 select + asrt( count( $logger->grep( 'SELECT' ) ), 1 ); + $logger->clear(); + $book->sharedTopic[] = $topic1; + $book->sharedTopic[] = $topic2; + asrt( count( $logger->grep( 'SELECT' ) ), 0 ); + R::store( $book ); + $book->sharedTopic[] = $topic3; + // Now do NOT clear all and then add one, just add the one + $logger->clear(); + R::store( $book ); + $book = R::load( 'book', 1 ); + asrt( count( $book->sharedTopic ), 3 ); + // No deletes + asrt( count( $logger->grep( "DELETE FROM" ) ), 0 ); + $book->sharedTopic['a'] = $topic3; + unset( $book->sharedTopic['a'] ); + R::store( $book ); + $book = R::load( 'book', 1 ); + asrt( count( $book->sharedTopic ), 3 ); + // No deletes + asrt( count( $logger->grep( "DELETE FROM" ) ), 0 ); + $book->ownPage = array(); + R::store( $book ); + asrt( count( $book->ownPage ), 0 ); + $book->ownPage[] = $page1; + $book->ownPage['a'] = $page2; + asrt( count( $book->ownPage ), 2 ); + R::store( $book ); + unset( $book->ownPage['a'] ); + asrt( count( $book->ownPage ), 2 ); + unset( $book->ownPage[11] ); + R::store( $book ); + $book = R::load( 'book', 1 ); + asrt( count( $book->ownPage ), 1 ); + $aPage = $book->ownPage[10]; + unset( $book->ownPage[10] ); + $aPage->title .= ' changed '; + $book->ownPage['anotherPage'] = $aPage; + $logger->clear(); + R::store( $book ); + $book = R::load( 'book', 1 ); + asrt( count( $book->ownPage ), 1 ); + $ap = reset( $book->ownPage ); + asrt( $ap->title, "pagina1 changed " ); + // Fix udiff instead of diff + $book3->ownPage = array( $page3, $page1 ); + $i = R::store( $book3 ); + $book3 = R::load( 'book', $i ); + asrt( intval( R::getCell( "select count(*) from page where book_id = $idb3 " ) ), 2 ); + asrt( count( $book3->ownPage ), 2 ); + $pic1->name = 'aaa'; + $pic2->name = 'bbb'; + R::store( $pic1 ); + R::store( $q1 ); + $book3->ownPicture[] = $pic1; + $book3->ownQuote[] = $q1; + $book3 = R::load( 'book', R::store( $book3 ) ); + // two own-arrays -->forgot array_merge + asrt( count( $book3->ownPicture ), 1 ); + asrt( count( $book3->ownQuote ), 1 ); + asrt( count( $book3->ownPage ), 2 ); + $book3 = R::load( 'book', R::store( $book3 ) ); + unset( $book3->ownPicture[1] ); + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( count( $book3->ownPicture ), 0 ); + asrt( count( $book3->ownQuote ), 1 ); + asrt( count( $book3->ownPage ), 2 ); + $book3 = R::load( 'book', R::store( $book3 ) ); + $NOTE = 0; + $quotes = R::dispense( 'quote', 10 ); + foreach ( $quotes as &$justSomeQuote ) { + $justSomeQuote->note = 'note' . ( ++$NOTE ); + } + $pictures = R::dispense( 'picture', 10 ); + foreach ( $pictures as &$justSomePic ) { + $justSomePic->note = 'note' . ( ++$NOTE ); + } + $topics = R::dispense( 'topic', 10 ); + foreach ( $topics as &$justSomeTopic ) { + $justSomeTopic->note = 'note' . ( ++$NOTE ); + } + for ( $j = 0; $j < 10; $j++ ) { + // Do several mutations + for ( $x = 0; $x < rand( 1, 20 ); $x++ ) { + modgr( $book3, $quotes, $pictures, $topics ); + } + $qbefore = count( $book3->ownQuote ); + $pbefore = count( $book3->ownPicture ); + $tbefore = count( $book3->sharedTopic ); + $qjson = json_encode( $book->ownQuote ); + $pjson = json_encode( $book->ownPicture ); + $tjson = json_encode( $book->sharedTopic ); + $book3 = R::load( 'book', R::store( $book3 ) ); + asrt( count( $book3->ownQuote ), $qbefore ); + asrt( count( $book3->ownPicture ), $pbefore ); + asrt( count( $book3->sharedTopic ), $tbefore ); + asrt( json_encode( $book->ownQuote ), $qjson ); + asrt( json_encode( $book->ownPicture ), $pjson ); + asrt( json_encode( $book->sharedTopic ), $tjson ); + testids( $book->ownQuote ); + testids( $book->ownPicture ); + testids( $book->sharedTopic ); + } + } + + /** + * Test parent bean relations. + * + * @return void + */ + public function testParentBean() + { + $village = R::dispense( 'village' ); + $village->name = 'village'; + $home = R::dispense( 'building' ); + $home->village = $village; + $id = R::store( $home ); + $home = R::load( 'building', $id ); + asrt( $home->village->name, 'village' ); + asrt( R::count( 'village' ), 1 ); + asrt( R::count( 'building' ), 1 ); + R::trash( $home ); + pass(); + asrt( R::count( 'village' ), 1 ); + asrt( R::count( 'building' ), 0 ); + } + + /** + * test N-M relations through intermediate beans + * + * @return void + */ + public function testNMRelationsIntermediate() + { + list( $mrA, $mrB, $mrC ) = R::dispense( 'person', 3 ); + list( $projA, $projB, $projC ) = R::dispense( 'project', 3 ); + $projA->title = 'A'; + $projB->title = 'B'; + $projC->title = 'C'; + $participant = R::dispense( 'participant' ); + $projA->link( 'participant', array( 'role' => 'manager' ) )->person = $mrA; + $projA->link( $participant->setAttr( 'role', 'developer' ) )->person = $mrB; + $projB->link( R::dispense( 'participant' )->setAttr( 'role', 'developer' ) )->person = $mrB; + $projB->link( 'participant', '{"role":"helpdesk"}' )->person = $mrC; + $projC->link( 'participant', '{"role":"sales"}' )->person = $mrC; + R::storeAll( array( $projA, $projB, $projC ) ); + $a = R::findOne( 'project', ' title = ? ', array( 'A' ) ); + $b = R::findOne( 'project', ' title = ? ', array( 'B' ) ); + $c = R::findOne( 'project', ' title = ? ', array( 'C' ) ); + asrt( count( $a->ownParticipant ), 2 ); + asrt( count( $b->ownParticipant ), 2 ); + asrt( count( $c->ownParticipant ), 1 ); + $managers = $developers = 0; + foreach ( $a->ownParticipant as $p ) { + if ( $p->role === 'manager' ) { + $managers++; + } + if ( $p->role === 'developer' ) { + $developers++; + } + } + $p = reset( $a->ownParticipant ); + asrt( $p->person->getMeta( 'type' ), 'person' ); + asrt( ( $p->person->id > 0 ), TRUE ); + asrt( $managers, 1 ); + asrt( $developers, 1 ); + asrt( (int) R::count( 'participant' ), 5 ); + asrt( (int) R::count( 'person' ), 3 ); + } + + /** + * test emulation of sharedList through intermediate beans + * + * @return void + */ + public function testSharedListIntermediate() + { + list( $v1, $v2, $v3 ) = R::dispense( 'village', 3 ); + list( $a1, $a2, $a3 ) = R::dispense( 'army', 3 ); + $a1->name = 'one'; + $a2->name = 'two'; + $a3->name = 'three'; + $v1->name = 'Ville 1'; + $v2->name = 'Ville 2'; + $v3->name = 'Ville 3'; + $v1->link( 'armyVillage' )->army = $a3; + $v2->link( 'army_village' )->army = $a2; + $v3->link( 'armyVillage' )->army = $a1; + $a2->link( 'army_village' )->village = $v1; + $id1 = R::store( $v1 ); + $id2 = R::store( $v2 ); + $id3 = R::store( $v3 ); + $village1 = R::load( 'village', $id1 ); + $village2 = R::load( 'village', $id2 ); + $village3 = R::load( 'village', $id3 ); + asrt( count( $village1->sharedArmy ), 2 ); + asrt( count( $village2->sharedArmy ), 1 ); + asrt( count( $village3->sharedArmy ), 1 ); + } + + /** + * test emulation via association renaming + * + * @return void + */ + public function testAssociationRenaming() + { + list( $p1, $p2, $p3 ) = R::dispense( 'painting', 3 ); + list( $m1, $m2, $m3 ) = R::dispense( 'museum', 3 ); + $p1->name = 'painting1'; + $p2->name = 'painting2'; + $p3->name = 'painting3'; + $m1->thename = 'a'; + $m2->thename = 'b'; + $m3->thename = 'c'; + R::renameAssociation( 'museum_painting', 'exhibited' ); + // Also test array syntax + R::renameAssociation( array( 'museum_museum' => 'center' ) ); + $m1->link( 'center', array( 'name' => 'History Center' ) )->museum2 = $m2; + $m1->link( 'exhibited', '{"from":"2014-02-01","til":"2014-07-02"}' )->painting = $p3; + $m2->link( 'exhibited', '{"from":"2014-07-03","til":"2014-10-02"}' )->painting = $p3; + $m3->link( 'exhibited', '{"from":"2014-02-01","til":"2014-07-02"}' )->painting = $p1; + $m2->link( 'exhibited', '{"from":"2014-02-01","til":"2014-07-02"}' )->painting = $p2; + R::storeAll( array( $m1, $m2, $m3 ) ); + list( $m1, $m2, $m3 ) = array_values( R::findAll( 'museum', ' ORDER BY thename ASC' ) ); + asrt( count( $m1->sharedMuseum ), 1 ); + asrt( count( $m1->sharedPainting ), 1 ); + asrt( count( $m2->sharedPainting ), 2 ); + asrt( count( $m3->sharedPainting ), 1 ); + $p3 = reset( $m1->sharedPainting ); + asrt( count( $p3->ownExhibited ), 2 ); + asrt( count( $m2->ownExhibited ), 2 ); + R::storeAll( array( $m1, $m2, $m3 ) ); + list( $m1, $m2, $m3 ) = array_values( R::findAll( 'museum', ' ORDER BY thename ASC' ) ); + asrt( count( $m1->sharedPainting ), 1 ); + asrt( count( $m2->sharedPainting ), 2 ); + asrt( count( $m3->sharedPainting ), 1 ); + $p3 = reset( $m1->sharedPainting ); + asrt( count( $p3->ownExhibited ), 2 ); + $paintings = $m2->sharedPainting; + foreach ( $paintings as $painting ) { + if ( $painting->name === 'painting2' ) { + pass(); + $paintingX = $painting; + } + } + unset( $m2->sharedPainting[$paintingX->id] ); + R::store( $m2 ); + $m2 = R::load( 'museum', $m2->id ); + asrt( count( $m2->sharedPainting ), 1 ); + $left = reset( $m2->sharedPainting ); + asrt( $left->name, 'painting3' ); + asrt( count( $m2->ownExhibited ), 1 ); + $exhibition = reset( $m2->ownExhibited ); + asrt( $exhibition->from, '2014-07-03' ); + asrt( $exhibition->til, '2014-10-02' ); + } + + /** + * Test don't try to store other things in shared list. + * + * @return void + */ + public function testDontTryToStoreOtherThingsInSharedList() { + + $book = R::dispense( 'book' ); + $book->sharedPage[] = 'nonsense'; + try { + R::store( $book ); + fail(); + } catch( RedException $exception) { + pass(); + } + $book->sharedPageList = R::dispense( 'page', 2 ); + R::store( $book ); + $book->sharedPageList; + R::trash( $book ); + asrt( R::count('page'), 2 ); + } + + /** + * Test whether magic array interface functions like isset() and + * unset work correctly with the x-own-list and the List-suffix. + * + * Array functions do not reveal x-own-lists and list-alias because + * you dont want duplicate entries in foreach-loops. + * Also offers a slight performance improvement for array access. + * + * @return void + */ + public function testWhetherIssetWorksWithXList() + { + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + asrt( isset( $book->xownPageList ), FALSE ); + asrt( isset( $book->ownPageList ), FALSE ); + asrt( isset( $book->xownPage ), FALSE ); + asrt( isset( $book->ownPage ), FALSE ); + $book->xownPageList[] = $page; + asrt( isset( $book->xownPageList ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + asrt( isset( $book->xownPage ), TRUE ); + asrt( isset( $book->ownPage ), TRUE ); + //Test array access + asrt( isset( $book['xownPageList'] ), TRUE ); + asrt( isset( $book['ownPageList'] ), TRUE ); + asrt( isset( $book['xownPage'] ), TRUE ); + asrt( isset( $book['ownPage'] ), TRUE ); + R::store( $book ); + $book = $book->fresh(); + asrt( isset( $book->xownPageList ), FALSE ); + asrt( isset( $book->ownPageList ), FALSE ); + asrt( isset( $book->xownPage ), FALSE ); + asrt( isset( $book->ownPage ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['ownPage'] ), FALSE ); + $book->xownPageList; + asrt( isset( $book->xownPageList ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + asrt( isset( $book->xownPage ), TRUE ); + asrt( isset( $book->ownPage ), TRUE ); + asrt( isset( $book['xownPageList'] ), TRUE ); + asrt( isset( $book['ownPageList'] ), TRUE ); + asrt( isset( $book['xownPage'] ), TRUE ); + asrt( isset( $book['ownPage'] ), TRUE ); + $book = $book->fresh(); + asrt( isset( $book->xownPageList ), FALSE ); + asrt( isset( $book->ownPageList ), FALSE ); + asrt( isset( $book->xownPage ), FALSE ); + asrt( isset( $book->ownPage ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['ownPage'] ), FALSE ); + $book->noLoad()->xownPageList; + asrt( isset( $book->xownPageList ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + //but empty + asrt( count( $book->ownPageList ), 0 ); + asrt( count( $book->xownPageList ), 0 ); + asrt( count( $book->ownPage ), 0 ); + asrt( count( $book->xownPage ), 0 ); + $book->xownPageList[] = $page; + asrt( isset( $book->xownPageList ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + asrt( isset( $book->xownPage ), TRUE ); + asrt( isset( $book->ownPage ), TRUE ); + asrt( isset( $book['xownPageList'] ), TRUE ); + asrt( isset( $book['ownPageList'] ), TRUE ); + asrt( isset( $book['xownPage'] ), TRUE ); + asrt( isset( $book['ownPage'] ), TRUE ); + unset( $book->xownPageList ); + asrt( isset( $book->xownPageList ), FALSE ); + asrt( isset( $book->ownPageList ), FALSE ); + asrt( isset( $book->xownPage ), FALSE ); + asrt( isset( $book->ownPage ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['ownPage'] ), FALSE ); + $book->xownPageList[] = $page; + asrt( isset( $book->xownPageList ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + asrt( isset( $book->xownPage ), TRUE ); + asrt( isset( $book->ownPage ), TRUE ); + asrt( isset( $book['xownPageList'] ), TRUE ); + asrt( isset( $book['ownPageList'] ), TRUE ); + asrt( isset( $book['xownPage'] ), TRUE ); + asrt( isset( $book['ownPage'] ), TRUE ); + unset( $book->xownPage ); + asrt( isset( $book->xownPageList ), FALSE ); + asrt( isset( $book->ownPageList ), FALSE ); + asrt( isset( $book->xownPage ), FALSE ); + asrt( isset( $book->ownPage ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['ownPage'] ), FALSE ); + $book = $book->fresh(); + asrt( isset( $book->xownPageList ), FALSE ); + asrt( isset( $book->ownPageList ), FALSE ); + asrt( isset( $book->xownPage ), FALSE ); + asrt( isset( $book->ownPage ), FALSE ); + asrt( isset( $book['xownPageList'] ), FALSE ); + asrt( isset( $book['ownPageList'] ), FALSE ); + asrt( isset( $book['xownPage'] ), FALSE ); + asrt( isset( $book['ownPage'] ), FALSE ); + $book->ownPageList; + asrt( isset( $book->xownPageList ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + asrt( isset( $book->xownPage ), TRUE ); + asrt( isset( $book->ownPage ), TRUE ); + asrt( isset( $book['xownPageList'] ), TRUE ); + asrt( isset( $book['ownPageList'] ), TRUE ); + asrt( isset( $book['xownPage'] ), TRUE ); + asrt( isset( $book['ownPage'] ), TRUE ); + } + + /** + * Test whether you can still set items starting with 'xown' or + * 'own' not followed by an uppercase character. + * + * @return void + */ + public function testConfusionWithXOwnList() + { + $book = R::dispense( 'book' ); + $book->xownitem = 1; + asrt( isset( $book->xownitem ), TRUE ); + asrt( (int) $book->xownitem, 1 ); + asrt( isset( $book->xownItem ), FALSE ); + asrt( isset( $book->xownItemList ), FALSE ); + $book->ownitem = 1; + asrt( isset( $book->ownitem ), TRUE ); + asrt( (int) $book->ownitem, 1 ); + asrt( isset( $book->ownItemList ), FALSE ); + R::store( $book ); + $book = $book->fresh(); + asrt( isset( $book->xownitem ), TRUE ); + asrt( (int) $book->xownitem, 1 ); + asrt( isset( $book->xownItem ), FALSE ); + asrt( isset( $book->xownItemList ), FALSE ); + asrt( isset( $book->ownitem ), TRUE ); + asrt( (int) $book->ownitem, 1 ); + asrt( isset( $book->ownItemList ), FALSE ); + } + + /** + * Test whether we can determine the mode of a list. + * + * @return void + */ + public function testModeCheckerOfLists() + { + foreach( array( 'ownPage', 'xownPage', 'ownPageList', 'xownPageList' ) as $listName ) { + $book = R::dispense( 'book' ); + asrt( $book->isListInExclusiveMode( $listName ), FALSE ); + $book->ownPageList[] = R::dispense( 'page' ); + asrt( $book->isListInExclusiveMode( $listName ), FALSE ); + $book = R::dispense( 'book' ); + asrt( $book->isListInExclusiveMode( $listName ), FALSE ); + $book->xownPageList[] = R::dispense( 'page' ); + asrt( $book->isListInExclusiveMode( $listName ), TRUE ); + $book = R::dispense( 'book' ); + asrt( $book->isListInExclusiveMode( $listName ), FALSE ); + $book->ownPage[] = R::dispense( 'page' ); + asrt( $book->isListInExclusiveMode( $listName ), FALSE ); + $book = R::dispense( 'book' ); + asrt( $book->isListInExclusiveMode( $listName ), FALSE ); + $book->xownPage[] = R::dispense( 'page' ); + asrt( $book->isListInExclusiveMode( $listName ), TRUE ); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Tags.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Tags.php new file mode 100644 index 000000000..32e375434 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Tags.php @@ -0,0 +1,171 @@ +title = 'Frankenstein'; + $m2->title = 'Fall of the House Usher'; + $m3->title = 'Sleepy Hollow'; + R::tag($m1, 'horror,gothic'); + R::tag($m2, 'horror,gothic,short'); + R::tag($m3, 'horror,legend'); + asrt( count( R::tagged( 'movie', 'horror' ) ), 3); + asrt( count( R::tagged( 'movie', 'horror', ' LIMIT 2' ) ), 2); + asrt( count( R::tagged( 'movie', 'horror', ' LIMIT ?', array( 2 ) ) ), 2); + asrt( count( R::tagged( 'movie', 'horror', ' ORDER BY movie.title DESC LIMIT ?', array( 2 ) ) ), 2); + asrt( count( R::tagged( 'movie', 'horror,gothic', ' ORDER BY movie.title DESC LIMIT ?', array( 1 ) ) ), 1); + asrt( count( R::tagged( 'movie', 'horror,gothic') ), 3 ); + asrt( count( R::taggedAll( 'movie', 'horror,gothic') ), 2 ); + asrt( count( R::tagged( 'movie', 'horror,gothic', ' LIMIT ? ', array( 2 ) ) ), 2 ); + asrt( count( R::taggedAll( 'movie', 'horror,gothic', ' LIMIT ? ', array( 2 ) ) ), 2 ); + asrt( count( R::tagged( 'movie', 'horror,gothic', ' LIMIT ? ', array( 1 ) ) ), 1 ); + asrt( count( R::taggedAll( 'movie', 'horror,gothic', ' LIMIT ? ', array( 1 ) ) ), 1 ); + asrt( count( R::tagged( 'movie', 'horror,legend', ' LIMIT ? ', array( 1 ) ) ), 1 ); + asrt( count( R::taggedAll( 'movie', 'horror,legend', ' LIMIT ? ', array( 1 ) ) ), 1 ); + asrt( count( R::tagged( 'movie', 'gothic,legend', ' LIMIT ? ', array( 1 ) ) ), 1 ); + asrt( count( R::taggedAll( 'movie', 'gothic,legend', ' LIMIT ? ', array( 1 ) ) ), 0 ); + asrt( count( R::tagged( 'movie', 'romance', ' LIMIT ? ', array( 1 ) ) ), 0 ); + asrt( count( R::taggedAll( 'movie', 'romance', ' LIMIT ? ', array( 1 ) ) ), 0 ); + asrt( count( R::tagged( 'movie', 'romance,xmas', ' LIMIT ? ', array( 1 ) ) ), 0 ); + asrt( count( R::taggedAll( 'movie', 'romance,xmas', ' LIMIT ? ', array( 1 ) ) ), 0 ); + asrt( count( R::tagged( 'movie', 'gothic,short', ' LIMIT ? ', array( 4 ) ) ), 2 ); + asrt( count( R::taggedAll( 'movie', 'gothic,short', ' LIMIT ? ', array( 4 ) ) ), 1 ); + asrt( count( R::tagged( 'movie', 'gothic,short', ' LIMIT 4 ' ) ), 2 ); + asrt( count( R::taggedAll( 'movie', 'gothic,short', ' LIMIT 4 ' ) ), 1 ); + asrt( count( R::tagged( 'movie', 'gothic,short', ' ORDER BY movie.id DESC LIMIT 4 ' ) ), 2 ); + asrt( count( R::taggedAll( 'movie', 'gothic,short', ' ORDER BY movie.id DESC LIMIT 4 ' ) ), 1 ); + asrt( count( R::tagged( 'movie', 'short', ' LIMIT ? ', array( 4 ) ) ), 1 ); + asrt( count( R::taggedAll( 'movie', 'short', ' LIMIT ? ', array( 4 ) ) ), 1 ); + asrt( count( R::tagged( 'movie', '', ' LIMIT ? ', array( 4 ) ) ), 0 ); + asrt( count( R::taggedAll( 'movie', '', ' LIMIT ? ', array( 4 ) ) ), 0 ); + asrt( count( R::tagged( 'movie', '', ' LIMIT 4 ' ) ), 0 ); + asrt( count( R::taggedAll( 'movie', '', ' LIMIT 4 ' ) ), 0 ); + asrt( count( R::tagged( 'movie', '', '' ) ), 0 ); + asrt( count( R::taggedAll( 'movie', '', '' ) ), 0 ); + asrt( count( R::tagged( 'movie', '' ) ), 0 ); + asrt( count( R::taggedAll( 'movie', '' ) ), 0 ); + } + + /** + * Some basic tests. + * + * @return void + */ + public function testTags() + { + list( $c, $d, $e, $f ) = R::dispense( 'coffee', 4 ); + R::tag( $c, 'strong,black' ); + R::tag( $d, 'black' ); + R::tag( $e, 'strong,sweet' ); + R::tag( $f, 'black,strong' ); + asrt( count( R::taggedAll( 'coffee', 'strong,sweet' ) ), 1 ); + asrt( count( R::taggedAll( 'coffee', 'strong' ) ), 3 ); + asrt( count( R::taggedAll( 'coffee', '' ) ), 0 ); + asrt( count( R::taggedAll( 'coffee', 'sweet' ) ), 1 ); + asrt( count( R::taggedAll( 'coffee', 'sweet,strong' ) ), 1 ); + asrt( count( R::taggedAll( 'coffee', 'black,strong' ) ), 2 ); + asrt( count( R::taggedAll( 'coffee', array( 'black', 'strong' ) ) ), 2 ); + asrt( count( R::taggedAll( 'coffee', 'salty' ) ), 0 ); + $blog = R::dispense( 'blog' ); + $blog->title = 'testing'; + $blog->blog = 'tesing'; + R::store( $blog ); + $blogpost = ( R::load( "blog", 1 ) ); + $post = R::dispense( "post" ); + $post->message = "hello"; + R::tag( $post, "lousy,smart" ); + asrt( implode( ',', R::tag( $post ) ), "lousy,smart" ); + R::tag( $post, "clever,smart" ); + $tagz = implode( ',', R::tag( $post ) ); + asrt( ( $tagz == "smart,clever" || $tagz == "clever,smart" ), TRUE ); + R::tag( $blog, array( "smart", "interesting" ) ); + asrt( implode( ',', R::tag( $blog ) ), "smart,interesting" ); + try { + R::tag( $blog, array( "smart", "interesting", "lousy!" ) ); + pass(); + } catch ( RedException $e ) { + fail(); + } + asrt( implode( ',', R::tag( $blog ) ), "smart,interesting,lousy!" ); + R::untag( $blog, array( "smart", "interesting" ) ); + asrt( implode( ",", R::tag( $blog ) ), "lousy!" ); + asrt( R::hasTag( $blog, array( "lousy!" ) ), TRUE ); + asrt( R::hasTag( $blog, array( "lousy!", "smart" ) ), TRUE ); + asrt( R::hasTag( $blog, array( "lousy!", "smart" ), TRUE ), FALSE ); + R::tag( $blog, FALSE ); + asrt( count( R::tag( $blog ) ), 0 ); + R::tag( $blog, array( "funny", "comic" ) ); + asrt( count( R::tag( $blog ) ), 2 ); + R::addTags( $blog, array( "halloween" ) ); + asrt( count( R::tag( $blog ) ), 3 ); + asrt( R::hasTag( $blog, array( "funny", "commic", "halloween" ), TRUE ), FALSE ); + R::unTag( $blog, "funny" ); + R::addTags( $blog, "horror" ); + asrt( count( R::tag( $blog ) ), 3 ); + asrt( R::hasTag( $blog, array( "horror", "commic", "halloween" ), TRUE ), FALSE ); + //no double tags + R::addTags( $blog, "horror" ); + asrt( R::hasTag( $blog, array( "horror", "commic", "halloween" ), TRUE ), FALSE ); + asrt( R::hasTag( $blog, "horror,commic,halloween", TRUE ), FALSE ); + asrt( count( R::tag( $blog ) ), 3 ); + testpack( "fetch tagged items" ); + } + + /** + * Fetching tagged items. + * + * @return void + */ + public function fetchTaggedItems() + { + $b = R::dispense( "book" ); + $b->title = 'horror'; + R::store( $b ); + $c = R::dispense( "book" ); + $c->title = 'creepy'; + R::store( $c ); + $d = R::dispense( "book" ); + $d->title = "chicklit"; + R::store( $d ); + R::tag( $b, "horror,classic" ); + R::tag( $d, "women,classic" ); + R::tag( $c, "horror" ); + $x = R::tagged( "book", "classic" ); + asrt( count( $x ), 2 ); + $x = R::tagged( "book", "classic,horror" ); + asrt( count( $x ), 3 ); + $x = R::tagged( "book", array( "classic", "horror" ) ); + asrt( count( $x ), 3 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Threeway.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Threeway.php new file mode 100644 index 000000000..d2fc1d452 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Threeway.php @@ -0,0 +1,129 @@ +sharedRole[] = $role; + R::store( $person ); + $person->link( 'person_role', array( + 'unit' => R::dispense('unit') + ))->role = $role; + //Can we add a duplicate role now? - No because we started with a simple N-M table + //and unique constraint has been applied accordingly, manually change database. + asrt( R::count( 'person_role' ), 1 ); + R::nuke(); + $person = R::dispense( 'person' ); + $role = R::dispense( 'role' ); + $person->via('participant')->sharedRole[] = $role; + R::store( $person ); + $person->link( 'participant', array( + 'unit' => R::dispense('unit') + ))->role = $role; + //Can we add a duplicate role now? - No because we started with a simple N-M table + //and unique constraint has been applied accordingly, manually change database. + asrt( R::count( 'participant' ), 1 ); + R::nuke(); + $participant = R::dispense( 'participant' ); + $person = R::dispense( 'person' ); + $role = R::dispense( 'role' ); + $unit = R::dispense( 'unit' ); + $participant->person = $person; + $participant->role = $role; + $participant->unit = $unit; + R::store( $participant ); + $person->link( 'participant', array( + 'unit' => R::dispense('unit') + ))->role = $role; + R::store( $person ); + //Can we add a duplicate role now? + asrt( R::count( 'participant' ), 2 ); + AQueryWriter::clearRenames(); + } + + /** + * Test whether a duplicate bean in the list isnt saved. + * This was an issue with Postgres while testing the threeway tables. + * Postgres returned the ID as a string while other drivers returned + * a numeric value causing different outcome in array_diff when + * calculating the shared additions. + * + * @return void + */ + public function testIssueWithDriverReturnID() + { + AQueryWriter::clearRenames(); + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->sharedPageList[] = $page; + R::store( $book ); + asrt( R::count( 'page' ), 1 ); + $book = $book->fresh(); + $book->sharedPageList[] = $page; + R::store( $book ); + //don't save the duplicate bean! + asrt( R::count( 'page' ), 1 ); + $book = $book->fresh(); + $page->item = 2; //even if we change a property ? + $book->sharedPageList[] = $page; + R::store( $book ); + foreach( $book->sharedPageList as $listItem) { + asrt( is_string( $listItem->id ), TRUE ); + } + //same test but for own-list + R::nuke(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->ownPageList[] = $page; + R::store( $book ); + asrt( R::count( 'page' ), 1 ); + $book = $book->fresh(); + $book->ownPageList[] = $page; + R::store( $book ); + //don't save the duplicate bean! + asrt( R::count( 'page' ), 1 ); + $book = $book->fresh(); + $book->ownPageList[] = $page; + $page->item = 3; + R::store( $book ); + //don't save the duplicate bean! + asrt( R::count( 'page' ), 1 ); + foreach( $book->ownPageList as $listItem) { + asrt( is_string( $listItem->id ), TRUE ); + } + AQueryWriter::clearRenames(); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Traverse.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Traverse.php new file mode 100644 index 000000000..3ce6570be --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Traverse.php @@ -0,0 +1,224 @@ +title = 'Book ' . ( $i++ ); + } + $books[5]->marked = TRUE; + $shelf = R::dispense( 'shelf' ); + $shelf->ownBook = $books; + $found = NULL; + $shelf->traverse('ownBookList', function( $book ) use ( &$found ) { + if ( $book->marked ) $found = $book; + }); + asrt( ( $found->marked == TRUE ), TRUE ); + asrt( $found->title, 'Book 6' ); + } + + /** + * Tests basic traversal. + * + * @return void + */ + public function testBasicTraversal() + { + R::nuke(); + $pageA = R::dispense( 'page' )->setAttr( 'title', 'a' ); + $pageB = R::dispense( 'page' )->setAttr( 'title', 'b' ); + $pageC = R::dispense( 'page' )->setAttr( 'title', 'c' ); + $pageD = R::dispense( 'page' )->setAttr( 'title', 'd' ); + $pageE = R::dispense( 'page' )->setAttr( 'title', 'e' ); + $pageF = R::dispense( 'page' )->setAttr( 'title', 'f' ); + $pageG = R::dispense( 'page' )->setAttr( 'title', 'g' ); + $pageH = R::dispense( 'page' )->setAttr( 'title', 'h' ); + $pageA->ownPage = array( $pageB, $pageC ); + $pageB->ownPage = array( $pageD ); + $pageC->ownPage = array( $pageE, $pageF ); + $pageD->ownPage = array( $pageG ); + $pageF->ownPage = array( $pageH ); + R::store( $pageA ); + $pageA = $pageA->fresh(); + //also tests non-existant column handling by count(). + asrt( R::count( 'page', ' price = ? ', array( '5' ) ), 0); + asrt( R::count( 'tag', ' title = ? ', array( 'new' ) ), 0); + $pageA->traverse( 'ownPageList', function( $bean ) { + $bean->price = 5; + }); + R::store( $pageA ); + asrt( R::count( 'page', ' price = ? ', array( '5' ) ), 7); + } + + /** + * Test traversing paths, ancestry. + * + * @return void + */ + public function testTraversePaths() + { + R::nuke(); + $pageA = R::dispense( 'page' )->setAttr( 'title', 'a' ); + $pageB = R::dispense( 'page' )->setAttr( 'title', 'b' ); + $pageC = R::dispense( 'page' )->setAttr( 'title', 'c' ); + $pageD = R::dispense( 'page' )->setAttr( 'title', 'd' ); + $pageE = R::dispense( 'page' )->setAttr( 'title', 'e' ); + $pageF = R::dispense( 'page' )->setAttr( 'title', 'f' ); + $pageG = R::dispense( 'page' )->setAttr( 'title', 'g' ); + $pageH = R::dispense( 'page' )->setAttr( 'title', 'h' ); + $pageA->ownPage = array( $pageB, $pageC ); + $pageB->ownPage = array( $pageD ); + $pageC->ownPage = array( $pageE, $pageF ); + $pageD->ownPage = array( $pageG ); + $pageF->ownPage = array( $pageH ); + R::store( $pageA ); + $parents = array(); + $pageF->traverse( 'page', function( $page ) use ( &$parents ) { + $parents[] = $page->title; + } ); + asrt( implode( ',', $parents ), 'c,a' ); + $parents = array(); + $pageH->traverse( 'page', function( $page ) use ( &$parents ) { + $parents[] = $page->title; + } ); + asrt( implode( ',', $parents ), 'f,c,a' ); + $parents = array(); + $pageG->traverse( 'page', function( $page ) use ( &$parents ) { + $parents[] = $page->title; + } ); + asrt( implode( ',', $parents ), 'd,b,a' ); + $path = array(); + $pageA->traverse( 'ownPageList', function( $page ) use ( &$path ) { + $path[] = $page->title; + } ); + asrt( implode( ',', $path ), 'b,d,g,c,e,f,h' ); + $path = array(); + $pageC->traverse( 'ownPageList', function( $page ) use ( &$path ) { + $path[] = $page->title; + } ); + asrt( implode( ',', $path ), 'e,f,h' ); + $path = array(); + $pageA->traverse( 'ownPageList', function( $page ) use ( &$path ) { + $path[] = $page->title; + }, 2 ); + asrt( implode( ',', $path ), 'b,d,c,e,f' ); + } + + /** + * Test traversal with embedded SQL snippets. + * + * @return void + */ + public function testTraversalWithSQL() + { + $tasks = R::dispense('task', 10); + foreach( $tasks as $key => $task ) { + $task->descr = 't'.$key; + } + $tasks[0]->ownTask = array( $tasks[1], $tasks[9], $tasks[7] ); + $tasks[1]->ownTask = array( $tasks[5] ); + $tasks[9]->ownTask = array( $tasks[3], $tasks[8] ); + $tasks[2]->ownTask = array( $tasks[4] ); + $tasks[7]->ownTask = array( $tasks[6] ); + R::storeAll( $tasks ); + $task = R::load('task', $tasks[0]->id); + $todo = array(); + $task->with(' ORDER BY descr ASC ')->traverse('ownTaskList', function( $t ) use ( &$todo ) { + $todo[] = $t->descr; + } ); + asrt( implode( ',', $todo ), 't1,t5,t7,t6,t9,t3,t8' ); + $task = R::load( 'task', $tasks[0]->id ); + $todo = array(); + $task->withCondition( ' ( descr = ? OR descr = ? ) ', array( 't7','t6' ) ) + ->traverse( 'ownTaskList', function( $task ) use( &$todo ){ + $todo[] = $task->descr; + } ); + asrt( implode( ',', $todo ), 't7,t6' ); + } + + /** + * Test traversal with aliases. + * + * @return void + */ + public function testTraversalWithAlias() + { + R::nuke(); + $book = R::dispense( 'book' ); + $cats = R::dispense( 'category', 3 ); + $cats[0]->gname = 'SF'; + $cats[1]->gname = 'Fantasy'; + $cats[2]->gname = 'Horror'; + $book->genre = $cats[0]; + $book->name = 'Space Story'; + $cats[0]->genre = $cats[1]; + $cats[2]->genre = $cats[1]; + R::store( $book ); + $book2 = R::dispense( 'book' ); + $book2->genre = $cats[2]; + $book2->name = 'Ghost Story'; + R::store( $book2 ); + $fantasy = R::load( 'category', $cats[1]->id ); + $cats = array(); + $book = $book->fresh(); + $book->fetchAs( 'category' )->traverse( 'genre', function( $cat ) use ( &$cats ) { + $cats[] = $cat->gname; + } ); + asrt( implode( ',', $cats ), 'SF,Fantasy' ); + $catList = array(); + $fantasy->alias( 'genre' ) + ->with( ' ORDER BY gname ASC ' ) + ->traverse( 'ownCategory', function( $cat ) use ( &$catList ) { + $catList[] = $cat->gname; + } ); + asrt( implode( ',', $catList ), 'Horror,SF' ); + } + + /** + * Traverse can only work with own-lists, otherwise infinite loops. + * + * @return void + */ + public function testSharedTraversal() + { + $friend = R::dispense( 'friend' ); + try { + $friend->traverse( 'sharedFriend', function( $friend ){ } ); + fail(); + } catch( RedException $e ) { + pass(); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Typechecking.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Typechecking.php new file mode 100644 index 000000000..ae3dc3192 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Typechecking.php @@ -0,0 +1,151 @@ + STRING + * NULL -> NULL + * + * @note Why not simply return bean->id in store()? Because not every driver returns the same type: + * databases without insert_id support require a separate query or a suffix returning STRINGS, not INTEGERS. + * + * @note Why not preserve types? I.e. I store integer, why do I get back a string? + * Answer: types are handled different across database platforms, would cause overhead to inspect every value for type, + * also PHP is a dynamically typed language so types should not matter that much. Another reason: due to the nature + * of RB columns in the database might change (INT -> STRING) this would cause return types to change as well which would + * cause 'cascading errors', i.e. a column gets widened and suddenly your code would break. + * + * @note Unfortunately the 32/64-bit issue cannot be tested fully. Return-strategy store() is probably the safest + * solution. + * + * @return void + */ + public function testTypes() + { + testpack( 'Beans can only contain STRING and NULL after reload' ); + R::nuke(); + $bean = R::dispense( 'bean' ); + $bean->number = 123; + $bean->float = 12.3; + $bean->bool = false; + $bean->bool2 = true; + $bean->text = 'abc'; + $bean->null = null; + $bean->datetime = new\DateTime( 'NOW', new\DateTimeZone( 'Europe/Amsterdam' ) ); + $id = R::store( $bean ); + asrt( is_int( $id ), TRUE ); + asrt( is_float( $bean->float ), TRUE ); + asrt( is_integer( $bean->number ), TRUE ); + asrt( is_string( $bean->bool ), TRUE ); + asrt( is_string( $bean->bool2 ), TRUE ); + asrt( is_string( $bean->datetime ), TRUE ); + asrt( is_string( $bean->text ), TRUE ); + asrt( is_null( $bean->null ), TRUE ); + $bean = R::load('bean', $id ); + asrt( is_string( $bean->id ), TRUE ); + asrt( is_string( $bean->float ), TRUE ); + asrt( is_string( $bean->number ), TRUE ); + asrt( is_string( $bean->bool ), TRUE ); + asrt( is_string( $bean->bool2 ), TRUE ); + asrt( is_string( $bean->datetime ), TRUE ); + asrt( is_string( $bean->text ), TRUE ); + asrt( is_null( $bean->null ), TRUE ); + asrt( $bean->bool, '0' ); + asrt( $bean->bool2, '1' ); + } + + /** + * Test bean type checking. + * + * @return void + */ + public function testBeanTypeChecking() + { + $redbean = R::getRedBean(); + $bean = $redbean->dispense( "page" ); + // Set some illegal values in the bean; this should trigger Security exceptions. + // Arrays are not allowed. + $bean->name = array( "1" ); + try { + $redbean->store( $bean ); + fail(); + } catch ( RedException $e ) { + pass(); + } + try { + $redbean->check( $bean ); + fail(); + } catch ( RedException $e ) { + pass(); + } + $bean->name = new OODBBean; + try { + $redbean->check( $bean ); + fail(); + } catch ( RedException $e ) { + pass(); + } + // Property names should be alphanumeric + $prop = "."; + $bean->$prop = 1; + try { + $redbean->store( $bean ); + fail(); + } catch ( RedException $e ) { + pass(); + } + try { + $redbean->check( $bean ); + fail(); + } catch ( RedException $e ) { + pass(); + } + // Really... + $prop = "-"; + $bean->$prop = 1; + try { + $redbean->store( $bean ); + fail(); + } catch ( RedException $e ) { + pass(); + } + try { + $redbean->check( $bean ); + fail(); + } catch ( RedException $e ) { + pass(); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Update.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Update.php new file mode 100644 index 000000000..dae0a9257 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Update.php @@ -0,0 +1,403 @@ + array( + 'book' => array( 'title' => ' LOWER(book.title) '), + ), + QueryWriter::C_SQLFILTER_WRITE => array( + 'book' => array( 'title' => ' UPPER(?) '), + ), + )); + + $book = R::dispense( 'book' ); + $book->title = 'story'; + R::store( $book ); + asrt( R::getCell( 'SELECT title FROM book WHERE id = ?', array( $book->id ) ), 'STORY' ); + $book = $book->fresh(); + asrt( $book->title, 'story' ); + $library = R::dispense( 'library' ); + $library->sharedBookList[] = $book; + R::store( $library ); + $library = $library->fresh(); + $books = $library->sharedBookList; + $book = reset( $books ); + asrt( $book->title, 'story' ); + $otherBook = R::dispense('book'); + $otherBook->sharedBook[] = $book; + R::store( $otherBook ); + $otherBook = $otherBook->fresh(); + $books = $otherBook->sharedBookList; + $book = reset( $books ); + asrt( $book->title, 'story' ); + $links = $book->ownBookBookList; + $link = reset( $links ); + $link->shelf = 'x13'; + AQueryWriter::setSQLFilters(array( + QueryWriter::C_SQLFILTER_READ => array( + 'book' => array( 'title' => ' LOWER(book.title) '), + 'book_book' => array( 'shelf' => ' LOWER(book_book.shelf) '), + ), + QueryWriter::C_SQLFILTER_WRITE => array( + 'book' => array( 'title' => ' UPPER(?) '), + 'book_book' => array( 'shelf' => ' UPPER(?) ') + ), + )); + R::store( $link ); + asrt( R::getCell( 'SELECT shelf FROM book_book WHERE id = ?', array( $link->id ) ), 'X13' ); + $otherBook = $otherBook->fresh(); + unset($book->sharedBookList[$otherBook->id]); + R::store( $book ); + AQueryWriter::setSQLFilters(array()); + } + + /** + * Test unsetting properties. + * + * @return void + */ + public function testUnsetUpdate() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book->name = 'x'; + $book->price = 40; + R::store( $book ); + $book = $book->fresh(); + $book->name = 'y'; + unset( $book->name ); + R::store( $book ); + $book = $book->fresh(); + asrt( $book->name, 'x' ); + asrt( (int) $book->price, 40 ); + $book->price = 30; + R::store( $book ); + $book = $book->fresh(); + asrt( $book->name, 'x' ); + asrt( (int) $book->price, 30 ); + $book->price = 20; + unset( $book->price ); + $book->name = 'y'; + R::store( $book ); + $book = $book->fresh(); + asrt( $book->name, 'y' ); + asrt( (int) $book->price, 30 ); + } + + /** + * Tests whether we can update or unset a parent bean + * with an alias without having to use fetchAs and + * without loading the aliased bean causing table-not-found + * errors. + */ + public function testUpdatingParentBeansWithAliases() + { + testpack( 'Test updating parent beans with aliases' ); + R::nuke(); + $trans = R::dispense( 'transaction' ); + $seller = R::dispense( 'user' ); + $trans->seller = $seller; + $id = R::store( $trans ); + R::freeze( TRUE ); + $trans = R::load( 'transaction', $id ); + //should not try to load seller, should not require fetchAs(). + try { + $trans->seller = R::dispense( 'user' ); + pass(); + } catch( Exception $e ) { + fail(); + } + $trans = R::load( 'transaction', $id ); + //same for unset... + try { + unset( $trans->seller ); + pass(); + } catch ( Exception $e ) { + fail(); + } + R::freeze( FALSE ); + $account = R::dispense( 'user' ); + asrt( count( $account->alias( 'seller' )->ownTransaction ), 0 ); + $account->alias( 'seller' )->ownTransaction = R::dispense( 'transaction', 10 ); + $account->alias( 'boo' ); //try to trick me... + $id = R::store( $account ); + R::freeze( true ); + $account = R::load( 'user', $id ); + asrt( count( $account->alias( 'seller' )->ownTransaction ), 10 ); + //you cannot unset a list + unset( $account->alias( 'seller' )->ownTransaction ); + $id = R::store( $account ); + $account = R::load( 'user', $id ); + asrt( count( $account->alias( 'seller' )->ownTransaction ), 10 ); + $account->alias( 'seller' )->ownTransaction = array(); + $id = R::store( $account ); + $account = R::load( 'user', $id ); + asrt(count($account->alias( 'seller' )->ownTransaction), 0 ); + asrt(count($account->ownTransaction), 0 ); + R::freeze( FALSE ); + //but also make sure we don't cause extra column issue #335 + R::nuke(); + $building = R::dispense('building'); + $village = R::dispense('village'); + $building->village = $village; + R::store($building); + $building = $building->fresh(); + $building->village = NULL; + R::store($building); + $building = $building->fresh(); + $columns = R::inspect('building'); + asrt( isset( $columns['village'] ), FALSE ); + asrt( isset( $building->village ), FALSE ); + R::nuke(); + $building = R::dispense('building'); + $village = R::dispense('village'); + $building->village = $village; + R::store($building); + $building = $building->fresh(); + unset($building->village); + R::store($building); + $building = $building->fresh(); + $columns = R::inspect('building'); + asrt( isset( $columns['village'] ), FALSE ); + asrt( isset( $building->village ), FALSE ); + $building = R::dispense('building'); + $village = R::dispense('village'); + $building->village = $village; + R::store($building); + $building = $building->fresh(); + $building->village = FALSE; + R::store($building); + $building = $building->fresh(); + $columns = R::inspect('building'); + asrt( isset( $columns['village'] ), FALSE ); + asrt( isset( $building->village ), FALSE ); + } + + /** + * All kinds of tests for basic CRUD. + * + * Does the data survive? + * + * @return void + */ + public function testUpdatingBeans() + { + testpack( 'Test basic support UUID/override ID default value' ); + $bean = R::dispense( 'bean' ); + R::store( $bean ); + if ($this->currentlyActiveDriverID === 'mysql') { + //otherwise UTF8 causes index overflow in mysql: SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes + R::exec('alter table bean modify column id char(3);'); + } else { + R::getWriter()->widenColumn( 'bean', 'id', R::getWriter()->scanType( 'abc' ) ); + } + $bean->id = 'abc'; + R::store( $bean ); + asrt( $bean->id, 'abc' ); + testpack( 'Test Update' ); + try { + R::store( array() ); + fail(); + } catch ( RedException $e ) { + pass(); + } + $toolbox = R::getToolBox(); + $adapter = $toolbox->getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + $page = $redbean->dispense( "page" ); + $page->name = "old name"; + $id = $redbean->store( $page ); + asrt( $page->getMeta( 'tainted' ), FALSE ); + $page->setAttr( 'name', "new name" ); + asrt( $page->getMeta( 'tainted' ), TRUE ); + $id = $redbean->store( $page ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + // Null should == NULL after saving + $page->rating = NULL; + $newid = $redbean->store( $page ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( ( $page->rating === NULL ), TRUE ); + asrt( !$page->rating, TRUE ); + $page->rating = FALSE; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( (bool) $page->rating, FALSE ); + asrt( ( $page->rating == FALSE ), TRUE ); + asrt( !$page->rating, TRUE ); + $page->rating = TRUE; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( (bool) $page->rating, TRUE ); + asrt( ( $page->rating == TRUE ), TRUE ); + asrt( ( $page->rating == TRUE ), TRUE ); + $page->rating = NULL; + R::store( $page ); + $page = R::load( 'page', $page->id ); + asrt( $page->rating, NULL ); + $page->rating = '1'; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( $page->rating, "1" ); + $page->rating = "0"; + $newid = $redbean->store( $page ); + asrt( $page->rating, "0" ); + $page->rating = 0; + $newid = $redbean->store( $page ); + asrt( $page->rating, 0 ); + $page->rating = "0"; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( !$page->rating, TRUE ); + asrt( ( $page->rating == 0 ), TRUE ); + asrt( ( $page->rating == FALSE ), TRUE ); + $page->rating = 5; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( strval( $page->rating ), "5" ); + $page->rating = 300; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( strval( $page->rating ), "300" ); + $page->rating = -2; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( strval( $page->rating ), "-2" ); + $page->rating = 2.5; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( ( $page->rating == 2.5 ), TRUE ); + $page->rating = -3.3; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( ( $page->rating == -3.3 ), TRUE ); + $page->rating = "good"; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( $page->rating, "good" ); + $longtext = str_repeat( 'great! because..', 100 ); + $page->rating = $longtext; + $newid = $redbean->store( $page ); + asrt( $newid, $id ); + $page = $redbean->load( "page", $id ); + asrt( $page->name, "new name" ); + asrt( $page->rating, $longtext ); + // Test leading zeros + $numAsString = "0001"; + $page->numasstring = $numAsString; + $redbean->store( $page ); + $page = $redbean->load( "page", $id ); + asrt( $page->numasstring, "0001" ); + $page->numnotstring = "0.123"; + $redbean->store( $page ); + $page = $redbean->load( "page", $id ); + asrt( $page->numnotstring == 0.123, TRUE ); + $page->numasstring2 = "00.123"; + $redbean->store( $page ); + $page = $redbean->load( "page", $id ); + asrt( $page->numasstring2, "00.123" ); + try { + $redbean->trash( array() ); + fail(); + } catch ( RedException $e ) { + pass(); + } + $redbean->trash( $page ); + asrt( (int) $pdo->GetCell( "SELECT count(*) FROM page" ), 0 ); + } + + /** + * Tests whether empty strings are preserved as such. + * + * @return void + */ + public function testEmptyStringShouldNotBeStoredAsInteger() + { + R::nuke(); + $bean = R::dispense('bean'); + $bean->str = ''; + R::store($bean); + $bean = $bean->fresh(); + asrt( ( $bean->str === '' ), TRUE); + } + + /** + * Test handling of infinity values. + * + * @return void + */ + public function testStoringInf() + { + R::nuke(); + $bean = R::dispense( 'bean' ); + $bean->inf = INF; + R::store( $bean ); + $bean = $bean->fresh(); + asrt( ( $bean->inf === 'INF' ), TRUE ); + asrt( ( $bean->inf == 'INF' ), TRUE ); + $bean->modifyme = 'yes'; + R::store( $bean ); + $bean = $bean->fresh(); + asrt( ( $bean->inf === 'INF' ), TRUE ); + asrt( ( $bean->inf == 'INF' ), TRUE ); + $bean->modifyme = 'yes'; + } +} + diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Utf8.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Utf8.php new file mode 100644 index 000000000..569bf7183 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Utf8.php @@ -0,0 +1,41 @@ +bla = $str; + + R::store( $bean ); + $bean = R::load( 'bean', $bean->id ); + asrt( $bean->bla, $str ); + + pass(); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Via.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Via.php new file mode 100644 index 000000000..73fbc68c8 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Via.php @@ -0,0 +1,330 @@ +sharedPersonList[] = $fooPerson; + R::store($mediaBean); + asrt( count( $mediaBean->sharedPersonList ), 1 ); + $person = R::findOne('person'); + $person->via('relation')->sharedMarriageList[] = R::dispense('marriage'); + //this second one caused the via property to not get cleared + $person->via('relation')->sharedMarriageList; + asrt( count( $person->sharedMediaList ), 1 ); + //also found this scenario, non-existing property + $book = R::dispense('book'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('garbage')->nothing; + asrt( count( $book->sharedPageList ), 1 ); + //yet another + $book = R::dispense('magazine'); + $book->ownAdList[] = R::dispense('ad'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('garbage')->ownAdList; + asrt( count( $book->sharedPageList ), 1 ); + $book = R::dispense('folder'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('garbage')->sharedItemList[] = R::dispense('item'); + asrt( count( $book->sharedPageList ), 1 ); + $book = R::dispense('folder2'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('garbage')->sharedItemList[] = R::dispense('item'); + $book->via('garbage')->sharedItemList[] = R::dispense('item'); + asrt( count( $book->sharedPageList ), 1 ); + $book = R::dispense('folder3'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('garbage')->item = R::dispense('item'); + asrt( count( $book->sharedPageList ), 1 ); + $book = R::dispense('folder3'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('garbage')->item = 'test'; + asrt( count( $book->sharedPageList ), 1 ); + //yet another + $book = R::dispense('leaflet'); + $book->title = 'leaflet'; + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('garbage')->title; + asrt( count( $book->sharedPageList ), 1 ); + //yet another + $book = R::dispense('paper'); + $book->author = R::dispense('author'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('garbage')->author; + asrt( count( $book->sharedPageList ), 1 ); + $book = R::dispense('paper2'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('garbage')->author; + asrt( count( $book->sharedPageList ), 1 ); + //yet another one + $book = R::dispense('archive'); + $book->sharedItem[] = R::dispense('item'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + unset( $book->via('garbage')->sharedItem ); + asrt( count( $book->sharedPageList ), 1 ); + //theoretic cases + $book = R::dispense('guide'); + $book->sharedItem[] = R::dispense('item'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('relation')->countShared('item'); + $book->via('relation')->countShared('item'); + asrt( count( $book->sharedPageList ), 1 ); + $book = R::dispense('catalogue'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('relation')->countShared('item'); + $book->via('relation')->countShared('item'); + asrt( count( $book->sharedPageList ), 1 ); + $book = R::dispense('tabloid'); + $book->ownItemList[] = R::dispense('item'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('relation')->countOwn('item'); + $book->via('relation')->countOwn('item'); + asrt( count( $book->sharedPageList ), 1 ); + $book = R::dispense('booklet'); + $book->ownItemList[] = R::dispense('item'); + $book->sharedPage[] = R::dispense('page'); + R::store($book); + $book = $book->fresh(); + $book->via('relation')->countOwn('item'); + $book->via('relation')->countOwn('item'); + asrt( count( $book->sharedPageList ), 1 ); + AQueryWriter::clearRenames(); + } + + /** + * Via specific tests. + * + * @return void + */ + public function testViaAndSQL() + { + R::nuke(); + list($p1, $p2) = R::dispense('participant', 2); + list($e1, $e2) = R::dispense('employee', 2); + list($x1, $x2) = R::dispense('project', 2); + $e1->name = 'Anna'; + $e2->name = 'John'; + $p1->project = $x1; + $p1->employee = $e1; + $p1->arole = 'designer'; + $p2->project = $x1; + $p2->employee = $e2; + $p2->arole = 'coder'; + R::storeAll(array( $p1, $p2 )); + $project = R::load('project', $x1->id); + $designers = $project + ->withCondition(' participant.arole = ? ', array( 'designer' ) ) + ->via( 'participant' ) + ->sharedEmployeeList; + $anna = reset( $designers ); + asrt(count($designers), 1); + asrt($anna->name, 'Anna'); + $coders = $project + ->withCondition(' participant.arole = ? ', array( 'coder' ) ) + ->via( 'participant' ) + ->sharedEmployeeList; + $john = reset( $coders ); + asrt(count($coders), 1); + asrt($john->name, 'John'); + } + + /** + * Test Via and Link together. + * + * @return void + */ + public function testViaAndLink() + { + R::nuke(); + list( $John, $Anna, $Celine ) = R::dispense( 'employee', 3 ); + $John->badge = 'John'; + $Anna->badge = 'Anna'; + $Celine->badge = 'Celine'; + $project = R::dispense( 'project' ); + $project->name = 'x'; + $project2 = R::dispense( 'project' ); + $project2->name = 'y'; + $John->link( 'participant', array( + 'arole' => 'designer' + ) )->project = $project; + $Anna->link( 'participant', array( + 'arole' => 'developer' + ) )->project = $project; + $Celine->link( 'participant', array( + 'arole' => 'sales' + ) )->project = $project2; + $Anna->link('participant', array( + 'arole' => 'lead' + ) )->project = $project2; + R::storeAll( array( $project, $project2, $John, $Anna, $Celine ) ); + $employees = $project + ->with(' ORDER BY badge ASC ') + ->via( 'participant' ) + ->sharedEmployee; + asrt( is_array( $employees ), TRUE ); + asrt( count( $employees ), 2 ); + $badges = array(); + foreach( $employees as $employee ) { + $badges[] = $employee->badge; + } + asrt( implode( ',', $badges ), 'Anna,John' ); + $employees = $project2 + ->with(' ORDER BY badge ASC ') + ->via( 'participant' ) + ->sharedEmployee; + asrt( is_array( $employees ), TRUE ); + asrt( count( $employees ), 2 ); + $badges = array(); + foreach( $employees as $employee ) { + $badges[] = $employee->badge; + } + asrt( implode( ',', $badges ), 'Anna,Celine' ); + $projects = $John->sharedProject; + asrt( is_array( $projects ), TRUE ); + asrt( count( $projects ), 1 ); + $projectList = array(); + foreach( $projects as $project ) { + $projectList[] = $project->name; + } + sort( $projectList ); + asrt( implode( ',', $projectList ), 'x' ); + $projects = $Anna->sharedProject; + asrt( is_array( $projects ), TRUE ); + asrt( count( $projects ), 2 ); + $projectList = array(); + foreach( $projects as $project ) { + $projectList[] = $project->name; + } + sort( $projectList ); + asrt( implode( ',', $projectList ), 'x,y' ); + $projects = $Anna->via( 'participant' )->sharedProject; + asrt( is_array( $projects ), TRUE ); + asrt( count( $projects ), 2 ); + $projectList = array(); + foreach( $projects as $project ) { + $projectList[] = $project->name; + } + sort( $projectList ); + asrt( implode( ',', $projectList ), 'x,y' ); + $projects = $Celine->via( 'participant' )->sharedProject; + asrt( is_array( $projects ), TRUE ); + asrt( count( $projects ), 1 ); + $projectList = array(); + foreach( $projects as $project ) { + $projectList[] = $project->name; + } + sort( $projectList ); + asrt( implode( ',', $projectList ), 'y' ); + $roles = $Anna->ownParticipant; + asrt( is_array( $roles ), TRUE ); + asrt( count( $roles ), 2 ); + $roleList = array(); + foreach( $roles as $role ) { + $roleList[] = $role->arole; + } + sort( $roleList ); + asrt( implode( ',', $roleList ), 'developer,lead' ); + $project2->sharedEmployee[] = $John; + R::store( $project2 ); + $projects = $John->sharedProject; + asrt( is_array( $projects ), TRUE ); + asrt( count( $projects ), 2 ); + $projectList = array(); + foreach( $projects as $project ) { + $projectList[] = $project->name; + } + sort( $projectList ); + asrt( implode( ',', $projectList ), 'x,y' ); + $projects = $John->via( 'participant' )->sharedProject; + asrt( is_array( $projects ), TRUE ); + asrt( count( $projects ), 2 ); + $projectList = array(); + foreach( $projects as $project ) { + $projectList[] = $project->name; + } + sort( $projectList ); + asrt( implode( ',', $projectList ), 'x,y' ); + } + + /** + * Test effect of via on shared list removal of beans. + * + * @return void + */ + public function testViaAndRemove() + { + R::nuke(); + $project = R::dispense( 'project' ); + $employees = R::dispense( 'employee', 2); + $project->via( 'partcipant' )->sharedEmployeeList = $employees; + R::store( $project ); + asrt( R::count('employee'), 2 ); + asrt( R::count('participant'), 2 ); + $project = $project->fresh(); + $project->sharedEmployee = array(); + R::store( $project ); + asrt( R::count( 'employee' ), 2 ); + asrt( R::count( 'participant' ), 0 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/With.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/With.php new file mode 100644 index 000000000..01bf47f55 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/With.php @@ -0,0 +1,581 @@ + 'book', + 'title' => 'Book of Lorem Ipsum', + 'ownPage' => array( + array( + '_type' => 'page', + 'content' => 'Lorem Ipsum', + ) + ), + 'sharedTag' => array( + array( + '_type' => 'tag', + 'label' => 'testing' + ) + ) + ) ); + R::store( $book ); + $book = $book->fresh(); + asrt( R::count( 'book' ), 1 ); + asrt( count( $book->ownPage ), 1 ); + //now try with no-load + $book = $book->fresh(); + asrt( count( $book->noLoad()->ownPage ), 0 ); + asrt( count( $book->noLoad()->sharedTag ), 0 ); + //now try to add with no-load + $book = $book->fresh(); + $book->noLoad()->xownPageList[] = R::dispense( 'page' ); + $book->noLoad()->sharedTagList[] = R::dispense( 'tag' ); + R::store( $book ); + $book = $book->fresh(); + asrt( count( $book->ownPage ), 2 ); + asrt( count( $book->sharedTagList ), 2 ); + //no-load overrides with and withCondition + $book = $book->fresh(); + asrt( count( $book->with(' invalid sql ')->noLoad()->ownPage ), 0 ); + asrt( count( $book->withCondition(' invalid sql ')->noLoad()->sharedTag ), 0 ); + //no-load overrides all and alias + $book = $book->fresh(); + asrt( count( $book->all()->noLoad()->ownPage ), 0 ); + asrt( count( $book->alias('nothing')->noLoad()->sharedTag ), 0 ); + //no-load gets cleared + $book = $book->fresh(); + asrt( count( $book->ownPage ), 2 ); + asrt( count( $book->sharedTagList ), 2 ); + //We cant clear with no-load accidentally? + $book = $book->fresh(); + $book->noLoad()->ownPage = array(); + $book->noLoad()->sharedTagList = array(); + R::store( $book ); + asrt( count( $book->ownPage ), 2 ); + asrt( count( $book->sharedTagList ), 2 ); + //No-load does not have effect if list is already cached + $book = $book->fresh(); + $book->ownPage; + $book->sharedTag; + asrt( count( $book->ownPage ), 2 ); + asrt( count( $book->sharedTagList ), 2 ); + } + + /** + * Test all(). + * + * @return void + */ + public function testAll() + { + $book = R::dispense( 'book' ); + $book->ownPage = R::dispense( 'page', 10 ); + R::store( $book ); + asrt( count( $book->with( ' LIMIT 3 ' )->ownPage ), 3 ); + asrt( count( $book->ownPage ), 3 ); + asrt( count( $book->all()->ownPage ), 10 ); + asrt( count( $book->ownPage ), 10 ); + R::nuke(); + asrt( count( $book->ownPage ), 10 ); + asrt( count( $book->all()->ownPage ), 0 ); + } + + /** + * Test embedded SQL snippets using with and withCondition. + * + * @return void + */ + public function testEmbeddedSQL() + { + list( $page1, $page2, $page3 ) = R::dispense( 'page', 3 ); + list( $ad1, $ad2, $ad3 ) = R::dispense( 'ad', 3 ); + $ad2->name = 'shampoo'; + $page3->name = 'homepage'; + $page1->sharedAd = array( $ad1, $ad3 ); + $page2->sharedAd = array( $ad2, $ad3 ); + $page3->sharedAd = array( $ad3, $ad2, $ad1 ); + R::storeAll( array( $page1, $page2, $page3 ) ); + $page1 = R::load( 'page', $page1->id ); + asrt( 1, count( $page1->with( ' LIMIT 1 ' )->sharedAd ) ); + $page2 = R::load( 'page', $page2->id ); + $adsOnPage2 = $page2->withCondition( ' `name` = ? ', array( 'shampoo' ) )->sharedAd; + asrt( 1, count( $adsOnPage2 ) ); + $ad = reset( $adsOnPage2 ); + asrt( $ad->name, 'shampoo' ); + $ad = R::load( 'ad', $ad->id ); + asrt( count( $ad->sharedPage ), 2 ); + $ad = R::load( 'ad', $ad->id ); + $homepage = reset( $ad->withCondition( ' `name` LIKE ? AND page.id > 0 ORDER BY id DESC ', array( '%ome%' ) )->sharedPage ); + asrt( $homepage->name, 'homepage' ); + } + + /** + * More variations... + * + * @return void + */ + public function testEmbeddedSQLPart2() + { + list( $book1, $book2, $book3 ) = R::dispense( 'book', 3 ); + $book1->position = 1; + $book2->position = 2; + $book3->position = 3; + $shelf = R::dispense( 'shelf' ); + $shelf->ownBook = array( $book1, $book2, $book3 ); + $id = R::store( $shelf ); + $shelf = R::load( 'shelf', $id ); + $books = $shelf->with( ' ORDER BY position ASC ' )->ownBook; + $book1 = array_shift( $books ); + asrt( (int) $book1->position, 1 ); + $book2 = array_shift( $books ); + asrt( (int) $book2->position, 2 ); + $book3 = array_shift( $books ); + asrt( (int) $book3->position, 3 ); + $books = $shelf->with( ' ORDER BY position DESC ' )->ownBook; + $book1 = array_shift( $books ); + asrt( (int) $book1->position, 3 ); + $book2 = array_shift( $books ); + asrt( (int) $book2->position, 2 ); + $book3 = array_shift( $books ); + asrt( (int) $book3->position, 1 ); + $shelf = R::load( 'shelf', $id ); + $books = $shelf->with( ' AND position > 2 ' )->ownBook; + asrt( count( $books ), 1 ); + $shelf = R::load( 'shelf', $id ); + $books = $shelf->with( ' AND position < ? ', array( 3 ) )->ownBook; + asrt( count( $books ), 2 ); + $shelf = R::load( 'shelf', $id ); + $books = $shelf->with( ' AND position = 1 ' )->ownBook; + asrt( count( $books ), 1 ); + $shelf = R::load( 'shelf', $id ); + $books = $shelf->withCondition( ' position > -1 ' )->ownBook; + asrt( count( $books ), 3 ); + // With-condition should not affect storing + $shelf = R::load( 'shelf', $id ); + $books = $shelf->with( ' AND position = 1 ' )->ownBook; + asrt( count( $books ), 1 ); + asrt( count( $shelf->ownBook ), 1 ); + $book = reset( $shelf->ownBook ); + $book->title = 'Trees and other Poems'; + R::store( $shelf ); + $books = $shelf->withCondition( ' position > -1 ' )->ownBook; + asrt( count( $books ), 3 ); + asrt( count( $shelf->ownBook ), 3 ); + $shelf = R::load( 'shelf', $id ); + $books = $shelf->with( ' AND position = 1 ' )->ownBook; + // Also with trashing -- just trash one! + $shelf->ownBook = array(); + R::store( $shelf ); + $books = $shelf->withCondition( ' position > -1 ' )->ownBook; + asrt( count( $books ), 2 ); + // With should cause a reload of a list + $shelf = R::load( 'shelf', $id ); + $books = $shelf->with( ' AND position = 2 ' )->ownBook; + asrt( count( $books ), 1 ); + $books = $shelf->withCondition( ' position > -1 ' )->ownBook; + asrt( count( $books ), 2 ); + $book = reset( $books ); + $book->title = 'Venetian Music'; + // Should not affect storage (fact that we used with twice, unsetting prop) + R::store( $shelf ); + $shelf = R::load( 'shelf', $id ); + asrt( count( $shelf->ownBook ), 2 ); + // Alias + list( $game1, $game2, $game3 ) = R::dispense( 'game', 3 ); + list( $t1, $t2, $t3 ) = R::dispense( 'team', 3 ); + $t1->name = 'Bats'; + $t2->name = 'Tigers'; + $t3->name = 'Eagles'; + $game1->name = 'a'; + $game1->team1 = $t1; + $game1->team2 = $t2; + $game2->name = 'b'; + $game2->team1 = $t1; + $game2->team2 = $t3; + $game3->name = 'c'; + $game3->team1 = $t2; + $game3->team2 = $t3; + R::storeAll( array( $game1, $game2, $game3 ) ); + $team1 = R::load( 'team', $t1->id ); + $team2 = R::load( 'team', $t2->id ); + $team3 = R::load( 'team', $t3->id ); + asrt( count( $team1->alias( 'team1' )->ownGame ), 2 ); + asrt( count( $team2->alias( 'team1' )->ownGame ), 1 ); + $team1 = R::load( 'team', $t1->id ); + $team2 = R::load( 'team', $t2->id ); + asrt( count( $team1->alias( 'team2' )->ownGame ), 0 ); + asrt( count( $team2->alias( 'team2' )->ownGame ), 1 ); + asrt( count( $team3->alias( 'team1' )->ownGame ), 0 ); + $team3 = R::load( 'team', $t3->id ); + asrt( count( $team3->alias( 'team2' )->ownGame ), 2 ); + $team1 = R::load( 'team', $t1->id ); + $games = $team1->alias( 'team1' )->ownGame; + $game4 = R::dispense( 'game' ); + $game4->name = 'd'; + $game4->team2 = $t3; + $team1->alias( 'team1' )->ownGame[] = $game4; + R::store( $team1 ); + $team1 = R::load( 'team', $t1->id ); + asrt( count( $team1->alias( 'team1' )->ownGame ), 3 ); + foreach ( $team1->ownGame as $g ) { + if ( $g->name == 'a' ) $game = $g; + } + $game->name = 'match'; + R::store( $team1 ); + $team1 = R::load( 'team', $t1->id ); + asrt( count( $team1->alias( 'team1' )->ownGame ), 3 ); + $found = 0; + foreach ( $team1->ownGame as $g ) { + if ( $g->name == 'match' ) $found = 1; + } + if ( $found ) pass(); + $team1->ownGame = array(); + R::store( $team1 ); + $team1 = R::load( 'team', $t1->id ); + asrt( count( $team1->alias( 'team1' )->ownGame ), 0 ); + $team1->ownBook[] = $book1; + R::store( $team1 ); + $team1 = R::load( 'team', $t1->id ); + asrt( count( $team1->alias( 'team1' )->ownGame ), 0 ); + asrt( count( $team1->ownBook ), 1 ); + } + + /** + * Test when to reload and when to NOT reload beans. + * Use UNSET to reload a parent bean. Use UNSET or + * a modifier (with, withCondition, all) to reload a list. + * Use noLoad() to obtain an empty list - does not reload + * but sets an empty array. + * + * @return void + */ + public function testWhenToReload() + { + $book = R::dispense( 'book' ); + $book->ownPage = R::dispense( 'page', 3 ); + $book->author = R::dispense( 'author' ); + $book->coauthor = R::dispense( 'author' ); + R::store( $book ); + $book = $book->fresh(); + $firstPage = reset( $book->ownPage ); + $id = $firstPage->id; + $book->ownPage[ $id ]->title = 'a'; + //Do not reload an own list after manipulations + asrt( $book->ownPage[ $id ]->title, 'a' ); //dont reload! + $book->ownPage[] = R::dispense( 'page' ); //dont reload! + asrt( $book->ownPage[ $id ]->title, 'a' ); //dont reload! + asrt( $book->ownPageList[ $id ]->title, 'a' ); //dont reload! + asrt( $book->xownPageList[ $id ]->title, 'a' ); //dont reload! + asrt( $book->xownPage[ $id ]->title, 'a' ); //dont reload! + asrt( count( $book->ownPageList ), 4 ); + //now trigger reload + unset( $book->ownPageList ); + asrt( count( $book->ownPageList ), 3 ); + $book->ownPage[] = R::dispense( 'page' ); + asrt( count( $book->ownPageList ), 4 ); + //now trigger reload + unset( $book->xownPageList ); + asrt( count( $book->ownPageList ), 3 ); + $book->ownPage[] = R::dispense( 'page' ); + asrt( count( $book->ownPageList ), 4 ); + //now trigger reload + unset( $book->xownPage ); + asrt( count( $book->ownPageList ), 3 ); + $book->ownPage[] = R::dispense( 'page' ); + asrt( count( $book->ownPageList ), 4 ); + //now trigger reload + unset( $book->ownPage ); + asrt( count( $book->ownPageList ), 3 ); + $book->ownPage[] = R::dispense( 'page' ); + asrt( count( $book->ownPageList ), 4 ); + //now trigger reload + $book->all()->ownPage; + asrt( count( $book->ownPageList ), 3 ); + $book->ownPage[] = R::dispense( 'page' ); + asrt( count( $book->ownPageList ), 4 ); + //now trigger reload + $book->all()->xownPage; + asrt( count( $book->ownPageList ), 3 ); + $book->ownPage[] = R::dispense( 'page' ); + asrt( count( $book->ownPageList ), 4 ); + //now trigger reload + $book->all()->ownPageList; + asrt( count( $book->ownPageList ), 3 ); + $book->ownPage[] = R::dispense( 'page' ); + asrt( count( $book->ownPageList ), 4 ); + //now trigger reload + $book->all()->xownPageList; + asrt( count( $book->ownPageList ), 3 ); + $book->ownPage[] = R::dispense( 'page' ); + asrt( count( $book->ownPageList ), 4 ); + //Do not reload an own list if told to not reload using noLoad() + $book->noLoad()->with(' LIMIT 1 ')->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + $book->noLoad()->all()->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + $book->noLoad()->alias('magazine')->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + $book->noLoad()->withCondition('')->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + //even if modifiers proceed noLoad() + $book->with(' LIMIT 1 ')->noLoad()->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + $book->all()->noLoad()->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + $book->alias('magazine')->noLoad()->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + $book->withCondition('')->noLoad()->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + //even in combinations + $book->all()->with(' LIMIT 1 ')->noLoad()->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + $book->alias('magazine')->all()->noLoad()->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + $book->alias('magazine')->with('LIMIT 1')->noLoad()->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + $book->alias('magazine')->withCondition('')->noLoad()->ownPage; //dont reload! + asrt( count( $book->xownPage ), 0); //dont reload! + //now test shared list + $book->sharedTag = R::dispense( 'tag', 16 ); + asrt( count( $book->sharedTag ), 16 ); + $book->sharedTag[] = R::dispense( 'tag' ); + asrt( count( $book->sharedTag ), 17 ); //dont reload after adding + $last = end( $book->sharedTagList ); + $id = $last->id; + $book->sharedTag[ $id ]->title = 'b'; + asrt( count( $book->sharedTag ), 17 ); //dont reload after manipulation + unset( $book->sharedTagList[ $id ] ); + asrt( count( $book->sharedTag ), 16 ); //dont reload after manipulation + //now trigger reload + unset( $book->sharedTagList ); + asrt( count( $book->sharedTag ), 0 ); + $book->sharedTag = R::dispense( 'tag', 16 ); + asrt( count( $book->sharedTag ), 16 ); + //now trigger reload + unset( $book->sharedTag ); + asrt( count( $book->sharedTag ), 0 ); + $book->sharedTag = R::dispense( 'tag', 16 ); + asrt( count( $book->sharedTag ), 16 ); + //now trigger reload + $book->all()->sharedTag; + asrt( count( $book->sharedTag ), 0 ); + $book->sharedTag = R::dispense( 'tag', 16 ); + asrt( count( $book->sharedTag ), 16 ); + //now trigger reload + $book->all()->sharedTagList; + asrt( count( $book->sharedTag ), 0 ); + $book->sharedTag = R::dispense( 'tag', 16 ); + asrt( count( $book->sharedTag ), 16 ); + //Do not reload a sharedTag list if told to not reload using noLoad() + $book->noLoad()->with(' LIMIT 1 ')->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + $book->noLoad()->all()->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + $book->noLoad()->alias('magazine')->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + $book->noLoad()->withCondition('')->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + //even if modifiers proceed noLoad() + $book->with(' LIMIT 1 ')->noLoad()->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + $book->all()->noLoad()->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + $book->alias('magazine')->noLoad()->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + $book->withCondition('')->noLoad()->ownPage; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + //even in combinations + $book->all()->with(' LIMIT 1 ')->noLoad()->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + $book->alias('magazine')->all()->noLoad()->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + $book->alias('magazine')->with('LIMIT 1')->noLoad()->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + $book->alias('magazine')->withCondition('')->noLoad()->sharedTag; //dont reload! + asrt( count( $book->sharedTag ), 0); //dont reload! + //test do not reload parent bean + $book->author->name = 'me'; + asrt( $book->author->name, 'me' ); + $book->fetchAs('author')->coauthor; + asrt( $book->author->name, 'me' ); + $book->fetchAs('author')->author; + asrt( $book->author->name, 'me' ); + $book->with(' LIMIT 1 ')->author; + asrt( $book->author->name, 'me' ); + $book->withCondition('')->author; + asrt( $book->author->name, 'me' ); + $book->all()->author; + asrt( $book->author->name, 'me' ); + $book->noLoad()->author; + asrt( $book->author->name, 'me' ); + $book->noLoad()->all()->author; + asrt( $book->author->name, 'me' ); + $book->with('LIMIT 1')->noLoad()->all()->author; + asrt( $book->author->name, 'me' ); + //now trigger reload + unset( $book->author ); + asrt( $book->author->name, NULL ); + $book->author->name = 'me'; + asrt( $book->author->name, 'me' ); + } + + /** + * Tests whether modifiers are cleared after reading or + * writing a bean property. + * + * @return void + */ + public function testClearanceOfModFlags() + { + //test base condition, retrieving list or parent should not set flags + $book = R::dispense( 'book' ); + asrt( $book->getModFlags(), '' ); + $book->ownPage = R::dispense( 'page', 2 ); + asrt( $book->getModFlags(), '' ); + $book->xownPage = R::dispense( 'page', 2 ); + asrt( $book->getModFlags(), '' ); + $book->ownPageList = R::dispense( 'page', 2 ); + asrt( $book->getModFlags(), '' ); + $book->xownPageList = R::dispense( 'page', 2 ); + asrt( $book->getModFlags(), '' ); + $book->ownPage[] = R::dispense( 'page', 1 ); + asrt( $book->getModFlags(), '' ); + $book->xownPage[] = R::dispense( 'page', 1 ); + asrt( $book->getModFlags(), '' ); + $book->ownPageList[] = R::dispense( 'page', 1 ); + asrt( $book->getModFlags(), '' ); + $book->xownPageList[] = R::dispense( 'page', 1 ); + asrt( $book->getModFlags(), '' ); + $book->sharedPage = R::dispense( 'page', 2 ); + asrt( $book->getModFlags(), '' ); + $book->sharedPageList = R::dispense( 'page', 2 ); + asrt( $book->getModFlags(), '' ); + $book->sharedPage[] = R::dispense( 'page', 1 ); + asrt( $book->getModFlags(), '' ); + $book->sharedPageList[] = R::dispense( 'page', 1 ); + asrt( $book->getModFlags(), '' ); + $book->author = R::dispense( 'author' ); + asrt( $book->getModFlags(), '' ); + $book->title = 'title'; + //Test whether appropriate flags are set and whether they are cleared after + //accessing a property. + $modifiers = array('with'=>'w', 'withCondition'=>'w', 'alias'=>'a', 'fetchAs'=>'f', 'all'=>'r', 'noLoad'=>'n'); + $properties = array('ownPage', 'ownPageList', 'xownPage', 'xownPageList', 'sharedPage', 'sharedPageList', 'author', 'title'); + foreach( $modifiers as $modifier => $flag ) { + foreach( $properties as $property ) { + $book = R::dispense( 'book' ); + $book->$modifier('something'); + $flags = $book->getModFlags(); + $expect = $flag; + asrt( $flags, $expect ); + $book->$property; + $flags = $book->getModFlags(); + asrt( $flags, '' ); + } + } + //now test combinations and also test whether we can + //clear modifiers manually using the clearModifiers() method. + foreach( $modifiers as $modifier => $flag ) { + foreach( $modifiers as $modifier2 => $flag2 ) { + foreach( $properties as $property ) { + $book = R::dispense( 'book' ); + $book->$modifier( 'something' )->$modifier2( 'something' ); + $flags = $book->getModFlags(); + $expect = array($flag, $flag2); + $expect = array_unique( $expect ); + sort( $expect ); + $expect = implode( '', $expect ); + asrt( $flags, $expect ); + $book->$modifier( 'something' )->$modifier2( 'something' )->clearModifiers(); + $flags = $book->getModFlags(); + asrt( $flags, '' ); + $book->$modifier( 'something' )->$modifier2( 'something' )->clearModifiers(); + $book->$property; + $flags = $book->getModFlags(); + asrt( $flags, '' ); + } + } + } + $book = R::dispense( 'book' ); + $book->ownPage = R::dispense( 'page', 2 ); + $book->sharedPage = R::dispense( 'page', 2 ); + R::store( $book ); + $book = R::dispense( 'book' ); + $book->alias('magazine')->ownPage = R::dispense( 'page', 2 ); + R::store( $book ); + //test modifier with countOwn and countShared methods + foreach( $modifiers as $modifier => $flag ) { + $book = R::dispense( 'book' ); + if ($modifier === 'withCondition') $book->$modifier( ' 1 ' ); + elseif ($modifier === 'with') $book->$modifier( ' LIMIT 1 ' ); + elseif ($modifier === 'alias') $book->$modifier('magazine'); + else $book->$modifier('something'); + $flags = $book->getModFlags(); + $expect = $flag; + asrt( $flags, $expect ); + $book->countOwn('page'); + $flags = $book->getModFlags(); + asrt( $flags, '' ); + if ($modifier === 'withCondition') $book->$modifier( ' 1 ' ); + elseif ($modifier === 'with') $book->$modifier( ' LIMIT 1 ' ); + elseif ($modifier === 'alias') $book->$modifier('magazine'); + else $book->$modifier('something'); + $flags = $book->getModFlags(); + $expect = $flag; + asrt( $flags, $expect ); + $book->countShared('page'); + $flags = $book->getModFlags(); + asrt( $flags, '' ); + if ($modifier === 'withCondition') $book->$modifier( ' 1 ' ); + elseif ($modifier === 'with') $book->$modifier( ' LIMIT 1 ' ); + elseif ($modifier === 'alias') $book->$modifier('magazine'); + else $book->$modifier('something'); + $flags = $book->getModFlags(); + $expect = $flag; + asrt( $flags, $expect ); + unset( $book->author ); + $flags = $book->getModFlags(); + asrt( $flags, '' ); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Writecache.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Writecache.php new file mode 100644 index 000000000..1a0ecce5f --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Writecache.php @@ -0,0 +1,394 @@ +prop = 1; + R::store( $bean ); + $writer->flushCache( 20 ); + $count = $writer->flushCache(); + asrt( $count, 0 ); + R::find( 'bean', ' prop < ? ', array( 1 ) ); + $count = $writer->flushCache(); + asrt( $count, 2 ); + R::find( 'bean', ' prop < ? ', array( 2 ) ); + $count = $writer->flushCache(); + asrt( $count, 5 ); + R::find( 'bean', ' prop < ? ', array( 2 ) ); + $count = $writer->flushCache(); + asrt( $count, 5 ); + for( $i = 0; $i < 40; $i ++ ) { + R::find( 'bean', ' prop < ? ', array( $i ) ); + } + $count = $writer->flushCache(); + asrt( $count, 85 ); + for( $i = 0; $i < 120; $i ++ ) { + R::find( 'bean', ' prop < ? ', array( $i ) ); + } + $count = $writer->flushCache( 1 ); + asrt( $count, 85 ); + for( $i = 0; $i < 20; $i ++ ) { + R::find( 'bean', ' prop < ? ', array( $i ) ); + } + $count = $writer->flushCache( 20 ); + asrt( $count, 9 ); + } + + /** + * When using fetchAs(), Query Cache does not recognize objects + * that have been previously fetched, see issue #400. + */ + public function testCachingAndFetchAs() + { + testpack( 'Testing whether you can cache multiple records of the same type' ); + R::debug( true, 1 ); + $logger = R::getDatabaseAdapter()->getDatabase()->getLogger(); + R::nuke(); + $coauthor1 = R::dispense( 'author' ); + $coauthor1->name = 'John'; + $book = R::dispense( 'book' ); + $book->title = 'a Funny Tale'; + $book->coauthor = $coauthor1; + $id = R::store( $book ); + $coauthor = R::dispense( 'author' ); + $coauthor->name = 'Pete'; + $book = R::dispense( 'book' ); + $book->title = 'a Funny Tale 2'; + $book->coauthor = $coauthor; + $id = R::store( $book ); + $book = R::dispense( 'book' ); + $book->title = 'a Funny Tale 3'; + $book->coauthor = $coauthor1; + $id = R::store( $book ); + $books = R::find( 'book' ); + $logger->clear(); + $authors = array(); + $authorsByName = array(); + foreach($books as $book) { + $coAuthor = $book->with( ' ORDER BY title ASC ' ) + ->fetchAs( 'author' )->coauthor; + $authors[] = $coAuthor->name; + $authorsByName[ $coAuthor->name ] = $coAuthor; + } + asrt( count( $logger->grep( 'SELECT' ) ), 2 ); //must be 2! 3 if cache does not work! + asrt( count( $authors ), 3 ); + asrt( isset( $authorsByName[ 'John' ] ), TRUE ); + asrt( isset( $authorsByName[ 'Pete' ] ), TRUE ); + $logger->clear(); + $authors = array(); + $authorsByName = array(); + foreach($books as $book) { + $coAuthor = $book->with( ' ORDER BY title DESC ' ) + ->fetchAs( 'author' )->coauthor; + $authors[] = $coAuthor->name; + $authorsByName[ $coAuthor->name ] = $coAuthor; + } + asrt( count( $logger->grep( 'SELECT' ) ), 0 ); //must be 0! + asrt( count( $authors ), 3 ); + asrt( isset( $authorsByName[ 'John' ] ), TRUE ); + asrt( isset( $authorsByName[ 'Pete' ] ), TRUE ); + } + + /** + * Test effects of cache. + * + * @return void + */ + public function testCachingEffects() + { + testpack( 'Testing WriteCache Query Writer Cache' ); + R::setNarrowFieldMode( FALSE ); + R::useWriterCache( FALSE ); + R::debug( TRUE, 1 ); + $logger = R::getDatabaseAdapter()->getDatabase()->getLogger(); + $book = R::dispense( 'book' )->setAttr( 'title', 'ABC' ); + $book->ownPage[] = R::dispense( 'page' ); + $id = R::store( $book ); + // Test load cache -- without + $logger->clear(); + $book = R::load( 'book', $id ); + $book = R::load( 'book', $id ); + asrt( count( $logger->grep( 'SELECT' ) ), 2 ); + // With cache + R::useWriterCache( TRUE ); + $logger->clear(); + $book = R::load( 'book', $id ); + $book = R::load( 'book', $id ); + asrt( count( $logger->grep( 'SELECT' ) ), 1 ); + R::useWriterCache( FALSE ); + // Test find cache + $logger->clear(); + $book = R::find( 'book' ); + $book = R::find( 'book' ); + asrt( count( $logger->grep( 'SELECT' ) ), 2 ); + // With cache + R::getWriter()->setUseCache( TRUE ); + $logger->clear(); + $book = R::find( 'book' ); + $book = R::find( 'book' ); + asrt( count( $logger->grep( 'SELECT' ) ), 1 ); + R::getWriter()->setUseCache( FALSE ); + // Test combinations + $logger->clear(); + $book = R::findOne( 'book', ' id = ? ', array( $id ) ); + $book->ownPage; + R::batch( 'book', array( $id ) ); + $book = R::findOne( 'book', ' id = ? ', array( $id ) ); + $book->ownPage; + R::batch( 'book', array( $id ) ); + asrt( count( $logger->grep( 'SELECT' ) ), 6 ); + // With cache + R::getWriter()->setUseCache( TRUE ); + $logger->clear(); + R::batch( 'book', array( $id ) ); + $book = R::findOne( 'book', ' id = ? ', array( $id ) ); + $book->ownPage; + $book = R::findOne( 'book', ' id = ? ', array( $id ) ); + $book->ownPage; + asrt( count( $logger->grep( 'SELECT' ) ), 3 ); + R::getWriter()->setUseCache( FALSE ); + // Test auto flush + $logger->clear(); + $book = R::findOne( 'book' ); + $book->name = 'X'; + R::store( $book ); + $book = R::findOne( 'book' ); + asrt( count( $logger->grep( 'SELECT *' ) ), 2 ); + // With cache + R::getWriter()->setUseCache( TRUE ); + $logger->clear(); + $book = R::findOne( 'book' ); + $book->name = 'Y'; + // Will flush + R::store( $book ); + $book = R::findOne( 'book' ); + // Now the same, auto flushed + asrt( count( $logger->grep( 'SELECT *' ) ), 2 ); + R::getWriter()->setUseCache( FALSE ); + // Test whether delete flushes as well (because uses selectRecord - might be a gotcha!) + R::store( R::dispense( 'garbage' ) ); + $garbage = R::findOne( 'garbage' ); + $logger->clear(); + $book = R::findOne( 'book' ); + R::trash( $garbage ); + $book = R::findOne( 'book' ); + asrt( count( $logger->grep( 'SELECT *' ) ), 2 ); + R::store( R::dispense( 'garbage' ) ); + $garbage = R::findOne( 'garbage' ); + // With cache + R::getWriter()->setUseCache( TRUE ); + $logger->clear(); + $book = R::findOne( 'book' ); + R::trash( $garbage ); + $book = R::findOne( 'book' ); + // Now the same, auto flushed + asrt( count( $logger->grep( 'SELECT *' ) ), 2 ); + R::getWriter()->setUseCache( FALSE ); + R::store( R::dispense( 'garbage' ) ); + $garbage = R::findOne( 'garbage' ); + // With cache + R::getWriter()->setUseCache( TRUE ); + $logger->clear(); + $book = R::findOne( 'book' ); + R::getWriter()->queryRecord( 'garbage', array( 'id' => array( $garbage->id ) ) ); + $book = R::findOne( 'book' ); + // Now the same, auto flushed + asrt( count( $logger->grep( 'SELECT *' ) ), 2 ); + $page = R::dispense('page'); + $book->sharedPage[] = $page; + R::store( $book ); + $logger->clear(); + $link = R::getWriter()->queryRecordLink( 'book', 'page', $book->id, $page->id ); + asrt( count( $logger->grep( 'SELECT' ) ), 1 ); + $link = R::getWriter()->queryRecordLink( 'book', 'page', $book->id, $page->id ); + asrt( count( $logger->grep( 'SELECT' ) ), 1 ); + R::getWriter()->setUseCache( FALSE ); + $link = R::getWriter()->queryRecordLink( 'book', 'page', $book->id, $page->id ); + asrt( count( $logger->grep( 'SELECT' ) ), 2 ); + R::getWriter()->setUseCache( TRUE ); + R::setNarrowFieldMode( TRUE ); + } + + /** + * Try to fool the cache :) + * + * @return void + */ + public function testRegressions() + { + testpack( 'Testing possible regressions: Try to fool the cache' ); + $str = 'SELECT * FROM ' . R::getWriter()->esc( 'bean', TRUE ) . ' WHERE ( ' . R::getWriter()->esc( 'id', TRUE ) . ' IN ( 1) ) '; + $bean = R::dispense( 'bean' ); + $bean->title = 'abc'; + $id = R::store( $bean ); + $bean = R::load( 'bean', $id ); + $bean->title = 'xxx'; + R::store( $bean ); + // Fire exact same query so cache may think no other query has been fired + R::exec( $str ); + $bean = R::load( 'bean', $id ); + asrt( $bean->title, 'xxx' ); + } + + /** + * Test keep-cache comment. + * + * @return void + */ + public function testKeepCacheCommentInSQL() + { + $bean = R::dispense( 'bean' ); + $bean->title = 'abc'; + $id = R::store( $bean ); + $bean = R::load( 'bean', $id ); + $bean->title = 'xxx'; + R::store( $bean ); + // Causes flush even though it contains -- keep-cache (not at the end, not intended) + R::findOne( 'bean', ' title = ? ', array( '-- keep-cache' ) ); + $bean = R::load( 'bean', $id ); + asrt( $bean->title, 'xxx' ); + } + + /** + * + * Same as above.. test keep cache. + * + * @return void + */ + public function testInstructNoDrop() + { + $str = 'SELECT * FROM ' . R::getWriter()->esc( 'bean', TRUE ) . ' -- keep-cache'; + $bean = R::dispense( 'bean' ); + $bean->title = 'abc'; + $id = R::store( $bean ); + $bean = R::load( 'bean', $id ); + $bean->title = 'xxx'; + R::store( $bean ); + R::exec( $str ); + $bean = R::load( 'bean', $id ); + asrt( $bean->title, 'abc' ); + R::nuke(); + // Now INSTRUCT the cache to not drop the cache CASE 2 + $str = 'SELECT * FROM ' . R::getWriter()->esc( 'bean', TRUE ) . ' -- keep-cache'; + $bean = R::dispense( 'bean' ); + $bean->title = 'abc'; + $id = R::store( $bean ); + $bean = R::load( 'bean', $id ); + $bean->title = 'xxx'; + R::store( $bean ); + R::findOne( 'bean', ' title = ? ', array( 'cache' ) ); + $bean = R::load( 'bean', $id ); + asrt( $bean->title, 'xxx' ); + } + + /** + * Can we confuse the cache? + * + * @return void + */ + public function testConfusionRegression() + { + testpack( 'Testing possible confusion regression' ); + $bean = R::dispense( 'bean' ); + $bean->title = 'abc'; + $id1 = R::store( $bean ); + $bean = R::dispense( 'bean' ); + $bean->title = 'abc2'; + $id2 = R::store( $bean ); + $bean = R::load( 'bean', $id1 ); + asrt( $bean->title, 'abc' ); + $bean = R::load( 'bean', $id2 ); + asrt( $bean->title, 'abc2' ); + } + + /** + * Test Ghost beans.... + * + * @return void + */ + public function testGhostBeans() + { + testpack( 'Testing ghost beans' ); + $bean = R::dispense( 'bean' ); + $bean->title = 'abc'; + $id1 = R::store( $bean ); + R::trash( $bean ); + $bean = R::load( 'bean', $id1 ); + asrt( (int) $bean->id, 0 ); + } + + /** + * Test explicit flush. + * + * @return void + */ + public function testExplicitCacheFlush() + { + testpack( 'Test cache flush (explicit)' ); + R::setNarrowFieldMode( FALSE ); + R::debug( true, 1 ); + $logger = R::getDatabaseAdapter()->getDatabase()->getLogger(); + $bean = R::dispense( 'bean' ); + $bean->title = 'abc'; + $id1 = R::store( $bean ); + $logger->clear(); + $bean = R::load( 'bean', $id1 ); + asrt( $bean->title, 'abc' ); + asrt( count( $logger->grep( 'SELECT *' ) ), 1 ); + $bean = R::load( 'bean', $id1 ); + asrt( count( $logger->grep( 'SELECT *' ) ), 1 ); + R::getWriter()->flushCache(); + $bean = R::load( 'bean', $id1 ); + asrt( count( $logger->grep( 'SELECT *' ) ), 2 ); + R::getWriter()->flushCache(); + R::getWriter()->setUseCache( FALSE ); + R::setNarrowFieldMode( TRUE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Xnull.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Xnull.php new file mode 100644 index 000000000..153fbd9ee --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Xnull.php @@ -0,0 +1,256 @@ +content = NULL; + //can we store a NULL? + asrt( is_null( $book->content ), TRUE ); + R::store( $book ); + //did we really store the NULL value ? + $book = R::findOne( 'book', ' content IS NULL ' ); + asrt( ( $book instanceof OODBBean ), TRUE ); + //still NULL, not empty STRING ? + asrt( is_null( $book->content ), TRUE ); + $book->pages = 100; + R::store( $book ); + //did we save it once again as NULL? + $book = R::findOne( 'book', ' content IS NULL ' ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( is_null( $book->content ), TRUE ); + asrt( gettype( $book->pages ), 'string' ); + $otherBook = R::dispense( 'book' ); + $otherBook->pages = 99; + //also if the column is VARCHAR-like? + $otherBook->content = 'blah blah'; + R::store( $otherBook ); + $book = R::findOne( 'book', ' content IS NULL ' ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( is_null( $book->content ), TRUE ); + asrt( intval( $book->pages ), 100 ); + //can we query not NULL as well? + $book = R::findOne( 'book', ' content IS NOT NULL ' ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( is_null( $book->content ), FALSE ); + asrt( intval( $book->pages ), 99 ); + asrt( $book->content, 'blah blah' ); + //Can we bind NULL directly? + $book->isGood = FALSE; + //Is NULL the default? And... no confusion with boolean FALSE? + R::store( $book ); + $book = R::findOne( 'book', ' is_good IS NULL' ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( is_null( $book->content ), TRUE ); + asrt( intval( $book->pages ), 100 ); + $book = R::findOne( 'book', ' is_good = ?', array( 0 ) ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( is_null( $book->content ), FALSE ); + asrt( intval( $book->pages ), 99 ); + } + + /** + * Tests whether we can NULLify a parent bean + * page->book if the parent (book) is already + * NULL. (isset vs array_key_exists bug). + * + * @return void + */ + public function testUnsetParent() + { + R::nuke(); + $book = R::dispense( 'book' ); + $book->title = 'My Book'; + $page = R::dispense( 'page' ); + $page->text = 'Lorem Ipsum'; + $book->ownPage[] = $page; + R::store( $book ); + $page = $page->fresh(); + R::freeze( TRUE ); + asrt( (int) $page->book->id, (int) $book->id ); + unset( $page->book ); + R::store( $page ); + $page = $page->fresh(); + asrt( (int) $page->book->id, (int) $book->id ); + $page->book = NULL; + R::store( $page ); + $page = $page->fresh(); + asrt( $page->book, NULL ); + asrt( $page->book_id, NULL ); + asrt( $page->bookID, NULL ); + asrt( $page->bookId, NULL ); + $page = R::dispense( 'page' ); + $page->text = 'Another Page'; + $page->book = NULL; + try { + R::store( $page ); + fail(); + } catch( \Exception $exception ) { + pass(); + } + unset($page->book); + R::store($page); + $page = $page->fresh(); + $page->book = NULL; //this must set field id to NULL not ADD column! + try { + R::store($page); + pass(); + } catch( \Exception $exception ) { + fail(); + } + $page = $page->fresh(); + $page->book = NULL; + R::store( $page ); + $page = $page->fresh(); + asrt( is_null( $page->book_id ), TRUE ); + $page->book = $book; + R::store( $page ); + $page = $page->fresh(); + asrt( (int) $page->book->id, (int) $book->id ); + $page->book = NULL; + R::store( $page ); + asrt( is_null( $page->book_id ), TRUE ); + asrt( is_null( $page->book ), TRUE ); + R::freeze( FALSE ); + } + + /** + * Test nullifying aliased parent. + * + * @return void + */ + public function testUnsetAliasedParent() + { + R::nuke(); + $book = R::dispense( 'book' ); + $author = R::dispense( 'author' ); + $book->coauthor = $author; + R::store( $book ); + $book = $book->fresh(); + asrt( is_null( $book->fetchAs('author')->coauthor ), FALSE ); + unset( $book->coauthor ); + R::store( $book ); + $book = $book->fresh(); + asrt( is_null( $book->fetchAs('author')->coauthor ), FALSE ); + $book->coauthor = NULL; + R::store( $book ); + $book = $book->fresh(); + asrt( is_null( $book->fetchAs('author')->coauthor ), TRUE ); + R::trash( $book ); + R::trash( $author ); + R::freeze( TRUE ); + $book = R::dispense( 'book' ); + $author = R::dispense( 'author' ); + $book->coauthor = $author; + R::store( $book ); + $book = $book->fresh(); + asrt( is_null( $book->fetchAs('author')->coauthor ), FALSE ); + unset( $book->coauthor ); + R::store( $book ); + $book = $book->fresh(); + asrt( is_null( $book->fetchAs('author')->coauthor ), FALSE ); + $book->coauthor = NULL; + R::store( $book ); + $book = $book->fresh(); + asrt( is_null( $book->fetchAs('author')->coauthor ), TRUE ); + R::trash( $book ); + R::trash( $author ); + R::freeze( FALSE ); + } + + /** + * Test NULL handling, setting a property to NULL must + * cause a change. + * + * @return void + */ + public function testBasicNullHandling() + { + // NULL can change bean + $bean = R::dispense( 'bean' ); + $bean->bla = 'a'; + R::store( $bean ); + $bean = $bean->fresh(); + asrt( $bean->hasChanged( 'bla' ), FALSE ); + $bean->bla = NULL; + asrt( $bean->hasChanged( 'bla' ), TRUE ); + // NULL test + $page = R::dispense( 'page' ); + $book = R::dispense( 'book' ); + $page->title = 'a NULL page'; + $page->book = $book; + $book->title = 'Why NUll is painful..'; + R::store( $page ); + $bookid = $page->book->id; + unset( $page->book ); + $id = R::store( $page ); + $page = R::load( 'page', $id ); + $page->title = 'another title'; + R::store( $page ); + pass(); + $page = R::load( 'page', $id ); + $page->title = 'another title'; + $page->book_id = NULL; + R::store( $page ); + pass(); + } + + /** + * Here we test whether the column type is set correctly. + * Normally if you store NULL, the smallest type (bool/set) will + * be selected. However in case of a foreign key type INT should + * be selected because fks columns require matching types. + * + * @return void + */ + public function ColumnType() + { + + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->ownPage[] = $page; + R::store( $book ); + pass(); + asrt( $page->getMeta( 'cast.book_id' ), 'id' ); + } + + /** + * Test meta column type. + * + * @return void + */ + public function TypeColumn() + { + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $page->book = $book; + R::store( $page ); + pass(); + asrt( $page->getMeta( 'cast.book_id' ), 'id' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole.php new file mode 100644 index 000000000..f947fa69e --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole.php @@ -0,0 +1,36 @@ +setMode( 1 ); + $debugger->setParamStringLength( 20 ); + if (!is_null($bindings)) { + $debugger->log($query, $bindings); + } else { + $debugger->log($query); + } + $logs = $debugger->getLogs(); + $log = reset($logs); + $log = str_replace( "\e[32m", '', $log ); + $log = str_replace( "\e[39m", '', $log ); + asrt($log, $expected); + $debugger->clear(); + } + + /** + * Tests the bean dump function used to inspect + * the contents of a bean. + * + * @return void + */ + public function testDump() + { + $beans = R::dispense( 'bean', 2 ); + $beans[0]->name = 'hello'; + $beans[1]->name = 'world'; + $array = R::dump($beans); + asrt( is_array( $array ), TRUE ); + foreach( $array as $item ) { + asrt( is_string( $item ), TRUE ); + } + $beans[1]->name = 'world, and a very long string that should be shortened'; + $array = R::dump($beans); + asrt( is_array( $array ), TRUE ); + asrt( strpos( $array[1], '...' ), 35 ); + //just to get 100% test cov, we dont need to test this + dmp( $beans ); + pass(); + //test wrong input + asrt( is_array( R::dump( NULL ) ), TRUE ); + asrt( count( R::dump( NULL ) ), 0 ); + asrt( is_array( R::dump( '' ) ), TRUE ); + asrt( count( R::dump( '' ) ), 0 ); + asrt( is_array( R::dump( 1 ) ), TRUE ); + asrt( count( R::dump( 1 ) ), 0 ); + asrt( is_array( R::dump( TRUE ) ), TRUE ); + asrt( count( R::dump( FALSE ) ), 0 ); + } + + /** + * Tests debugging with parameters. + * + * @return void + */ + public function testDebugger2() + { + testpack( 'Test debugger with params.' ); + $this->testDebug('SELECT * FROM table', NULL, 'SELECT * FROM table'); + $this->testDebug('SELECT * FROM book WHERE title = ?', array('my book'), 'SELECT * FROM book WHERE title = \'my book\''); + $this->testDebug('title = ? OR title = ?', array('book1', 'book2'), 'title = \'book1\' OR title = \'book2\''); + $this->testDebug('title = ? OR price = ?', array('book1', 20), 'title = \'book1\' OR price = 20'); + $this->testDebug('number IN (?,?)', array(8,900), 'number IN (8,900)'); + $this->testDebug('?', array(20), '20'); + $this->testDebug('?,?', array('test',20), '\'test\',20'); + $this->testDebug('?', array( NULL ), 'NULL'); + $this->testDebug('title = ?', array( NULL ), 'title = NULL'); + $this->testDebug('?,?', array( NULL,NULL ), 'NULL,NULL'); + $this->testDebug('title = ?', array('a very long title that should be shortened'), 'title = \'a very long title th... \''); + $this->testDebug('title = ? OR title = ?', array('a very long title that should be shortened', 'another long title that should be shortened'), 'title = \'a very long title th... \' OR title = \'another long title t... \''); + $this->testDebug('title = ? OR ?', array('a very long title that should be shortened', NULL), 'title = \'a very long title th... \' OR NULL'); + $this->testDebug('?,?', array('hello'), '\'hello\',:slot1'); + $this->testDebug('title = :first OR title = :second', array(':first'=>'book1', ':second'=>'book2'), 'title = \'book1\' OR title = \'book2\''); + $this->testDebug('title = :first OR price = :second', array(':first'=>'book1', ':second'=>20), 'title = \'book1\' OR price = 20'); + $this->testDebug('number IN (:one,:two)', array(':one'=>8, ':two'=>900), 'number IN (8,900)'); + $this->testDebug('number IN (:one,:two)', array(':one'=>8, ':two'=>900, ':three'=>999), 'number IN (8,900)'); + $this->testDebug('number IN (:one,:two)', array(':three'=>999, ':one'=>8, ':two'=>900), 'number IN (8,900)'); + $this->testDebug('number IN (:one,:two)', array(':one'=>8, ':three'=>999, ':two'=>900), 'number IN (8,900)'); + $this->testDebug(':a', array(':a'=>20), '20'); + $this->testDebug(':a,?', array(':a'=>20, 30), '20,30'); + $this->testDebug(':a,?', array(30, ':a'=>20), '20,30'); + $this->testDebug('?,?', array('test',20), '\'test\',20'); + $this->testDebug('?', array( NULL ), 'NULL'); + $this->testDebug('title = ?', array( NULL ), 'title = NULL'); + $this->testDebug('?,?', array( NULL,NULL ), 'NULL,NULL'); + $this->testDebug('title = ?', array('a very long title that should be shortened'), 'title = \'a very long title th... \''); + $this->testDebug('title = ? OR title = ?', array('a very long title that should be shortened', 'another long title that should be shortened'), 'title = \'a very long title th... \' OR title = \'another long title t... \''); + $this->testDebug('title = ? OR ?', array('a very long title that should be shortened', NULL), 'title = \'a very long title th... \' OR NULL'); + $this->testDebug('?,?', array('hello'), '\'hello\',:slot1'); + $this->testDebug('hello ?', 'world', 'hello ?'); + $this->testDebug(':slot0 :slot1 :slot2 :slot3 :slot4 :slot5 :slot6 :slot7 :slot8 :slot9 :slot10', array( + 'a','b','c','d','e','f','g','h','i','j','k' + ),"'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k'"); + $this->testDebug('? ? ? ? ? ? ? ? ? ? ?', array( + 'a','b','c','d','e','f','g','h','i','j','k' + ),"'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k'"); + $this->testDebug(':a :aaa :ab', array(':a'=>1,':aaa'=>2,':ab'=>3),'1 2 3'); + } + + /** + * Test facade fancyDebug function + */ + public function testDebug2InFacade() + { + R::fancyDebug( TRUE ); + pass(); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Export.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Export.php new file mode 100644 index 000000000..73674b2d8 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Export.php @@ -0,0 +1,130 @@ +import( array( 'a' => 1, 'b' => 2 ) ); + $bean->setMeta( 'justametaproperty', 'hellothere' ); + $arr = $bean->export(); + asrt( is_array( $arr ), TRUE ); + asrt( isset( $arr["a"] ), TRUE ); + asrt( isset( $arr["b"] ), TRUE ); + asrt( $arr["a"], 1 ); + asrt( $arr["b"], 2 ); + asrt( isset( $arr["__info"] ), FALSE ); + $arr = $bean->export( TRUE ); + asrt( isset( $arr["__info"] ), TRUE ); + asrt( $arr["a"], 1 ); + asrt( $arr["b"], 2 ); + $exportBean = $redbean->dispense( 'abean' ); + $exportBean->setMeta( 'metaitem.bla', 1 ); + $exportedBean = $exportBean->export( TRUE ); + asrt( $exportedBean["__info"]["metaitem.bla"], 1 ); + asrt( $exportedBean["__info"]["type"], "abean" ); + // Can we determine whether a bean is empty? + testpack( 'test $bean->isEmpty() function' ); + $bean = R::dispense( 'bean' ); + asrt( $bean->isEmpty(), TRUE ); + asrt( ( count( $bean ) > 0 ), TRUE ); + $bean->property = 1; + asrt( $bean->isEmpty(), FALSE ); + asrt( ( count( $bean ) > 0 ), TRUE ); + $bean->property = 0; + asrt( $bean->isEmpty(), TRUE ); + asrt( ( count( $bean ) > 0 ), TRUE ); + $bean->property = FALSE; + asrt( $bean->isEmpty(), TRUE ); + asrt( ( count( $bean ) > 0 ), TRUE ); + $bean->property = NULL; + asrt( $bean->isEmpty(), TRUE ); + asrt( ( count( $bean ) > 0 ), TRUE ); + unset( $bean->property ); + asrt( $bean->isEmpty(), TRUE ); + asrt( ( count( $bean ) > 0 ), TRUE ); + // Export bug I found + $bandmember = R::dispense( 'bandmember' ); + $bandmember->name = 'Duke'; + $instrument = R::dispense( 'instrument' ); + $instrument->name = 'Piano'; + $bandmember->ownInstrument[] = $instrument; + $a = R::exportAll( $bandmember ); + pass(); + asrt( isset( $a[0] ), TRUE ); + asrt( (int) $a[0]['id'], 0 ); + asrt( $a[0]['name'], 'Duke' ); + asrt( $a[0]['ownInstrument'][0]['name'], 'Piano' ); + R::nuke(); + $v = R::dispense( 'village' ); + $b = R::dispense( 'building' ); + $v->name = 'a'; + $b->name = 'b'; + $v->ownBuilding[] = $b; + $id = R::store( $v ); + $a = R::exportAll( $v ); + asrt( $a[0]['name'], 'a' ); + asrt( $a[0]['ownBuilding'][0]['name'], 'b' ); + $v = R::load( 'village', $id ); + $b2 = R::dispense( 'building' ); + $b2->name = 'c'; + $v->ownBuilding[] = $b2; + $a = R::exportAll( $v ); + asrt( $a[0]['name'], 'a' ); + asrt( $a[0]['ownBuilding'][0]['name'], 'b' ); + asrt( count( $a[0]['ownBuilding'] ), 2 ); + list( $r1, $r2 ) = R::dispense( 'army', 2 ); + $r1->name = '1'; + $r2->name = '2'; + $v->sharedArmy[] = $r2; + $a = R::exportAll( $v ); + asrt( count( $a[0]['sharedArmy'] ), 1 ); + R::store( $v ); + $v = R::load( 'village', $id ); + $a = R::exportAll( $v ); + asrt( count( $a[0]['sharedArmy'] ), 1 ); + asrt( $a[0]['name'], 'a' ); + asrt( $a[0]['ownBuilding'][0]['name'], 'b' ); + asrt( count( $a[0]['ownBuilding'] ), 2 ); + $v->sharedArmy[] = $r1; + $a = R::exportAll( $v ); + asrt( count( $a[0]['sharedArmy'] ), 2 ); + $v = R::load( 'village', $id ); + $a = R::exportAll( $v ); + asrt( count( $a[0]['sharedArmy'] ), 1 ); + $v->sharedArmy[] = $r1; + R::store( $v ); + $v = R::load( 'village', $id ); + $a = R::exportAll( $v ); + asrt( count( $a[0]['sharedArmy'] ), 2 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Fusebox.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Fusebox.php new file mode 100644 index 000000000..076df5d41 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Fusebox.php @@ -0,0 +1,66 @@ +taste() ); + asrt( 'tomato', $soup->flavour ); + } + + /** + * Test unboxing + * + * @param OODBBean $bean + */ + private function giveMeBean( OODBBean $bean ) + { + asrt( ( $bean instanceof OODBBean ), TRUE ); + asrt( 'A bit too salty', $bean->taste() ); + asrt( 'tomato', $bean->flavour ); + } + + /** + * Test boxing. + * + * @return void + */ + public function testBasicBox() + { + $soup = R::dispense( 'soup' ); + $soup->flavour = 'tomato'; + $this->giveMeSoup( $soup->box() ); + $this->giveMeBean( $soup->box()->unbox() ); + $this->giveMeBean( $soup ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Glue.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Glue.php new file mode 100644 index 000000000..d0845e0e6 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Glue.php @@ -0,0 +1,63 @@ +glueSQLCondition( ' name = ? '), ' WHERE name = ? ' ); + asrt( $writer->glueSQLCondition( ' value1 > ? OR value < ? '), ' WHERE value1 > ? OR value < ? ' ); + //Does it recognize NON-WHERE conditions? - usual suspects + asrt( $writer->glueSQLCondition( ' ORDER BY name '), ' ORDER BY name ' ); + asrt( $writer->glueSQLCondition( ' LIMIT 10 '), ' LIMIT 10 ' ); + asrt( $writer->glueSQLCondition( ' OFFSET 20 '), ' OFFSET 20 ' ); + //highly doubtful but who knows... - I think nobody will ever use this in a query snippet. + asrt( $writer->glueSQLCondition( ' GROUP BY grp '), ' GROUP BY grp ' ); + asrt( $writer->glueSQLCondition( ' HAVING x = ? '), ' HAVING x = ? ' ); + //can we replace WHERE with AND ? + asrt( $writer->glueSQLCondition( ' AND name = ? ', QueryWriter::C_GLUE_WHERE ), ' WHERE name = ? ' ); + //can we glue with AND instead of WHERE ? + asrt( $writer->glueSQLCondition( ' value1 > ? OR value < ? ', QueryWriter::C_GLUE_AND ), ' AND value1 > ? OR value < ? ' ); + //non-cases + asrt( $writer->glueSQLCondition( ' GROUP BY grp ', QueryWriter::C_GLUE_WHERE ), ' GROUP BY grp ' ); + asrt( $writer->glueSQLCondition( ' GROUP BY grp ', QueryWriter::C_GLUE_AND ), ' GROUP BY grp ' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Import.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Import.php new file mode 100644 index 000000000..6e1a67f50 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Import.php @@ -0,0 +1,271 @@ + 'book', 'title' => 'book one' ), + array( '_type' => 'book', 'title' => 'book two' ), + ) ); + asrt( is_array( $books ), TRUE ); + asrt( count( $books ), 2 ); + $book = reset( $books ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( $book->title, 'book one' ); + $book = next( $books ); + asrt( ( $book instanceof OODBBean ), TRUE ); + asrt( $book->title, 'book two' ); + } + + /** + * Test recursive imports (formely known as R::graph). + * + * @return void + */ + public function testRecursiveImport() + { + $book = R::dispense( + array( + '_type'=>'book', + 'title'=>'The magic book', + 'ownPageList' => array( + array( + '_type' => 'page', + 'content' => 'magic potions', + ), + array( + '_type' => 'page', + 'content' => 'magic spells', + ) + ) + ) + ); + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( $book->title, 'The magic book' ); + $pages = $book->with(' ORDER BY content ASC ')->ownPageList; + asrt( count($pages), 2 ); + $page1 = array_shift( $pages ); + asrt( $page1->content, 'magic potions' ); + $page2 = array_shift( $pages ); + asrt( $page2->content, 'magic spells' ); + R::nuke(); + $book = R::dispense( + array( + '_type'=>'book', + 'title'=>'The magic book', + 'author' => array( + '_type' => 'author', + 'name' => 'Dr. Evil' + ), + 'coAuthor' => array( + '_type' => 'author', + 'name' => 'Dr. Creepy' + ), + 'ownPageList' => array( + array( + '_type' => 'page', + 'content' => 'magic potions', + 'ownRecipe' => array( + 'a' => array('_type'=>'recipe', 'name'=>'Invisibility Salad'), + 'b' => array('_type'=>'recipe', 'name'=>'Soup of Madness'), + 'c' => array('_type'=>'recipe', 'name'=>'Love cake'), + ) + ), + array( + '_type' => 'page', + 'content' => 'magic spells', + ) + ), + 'sharedCategory' => array( + array( + '_type' => 'category', + 'label' => 'wizardry' + ), + ) + ) + ); + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( $book->title, 'The magic book' ); + $pages = $book->with(' ORDER BY content ASC ')->ownPageList; + asrt( count($pages), 2 ); + $page1 = array_shift( $pages ); + asrt( $page1->content, 'magic potions' ); + $page2 = array_shift( $pages ); + asrt( $page2->content, 'magic spells' ); + $recipes = $page1->with(' ORDER BY name ASC ')->ownRecipeList; + asrt( count( $recipes ), 3 ); + $recipe1 = array_shift( $recipes ); + asrt( $recipe1->name, 'Invisibility Salad' ); + $recipe2 = array_shift( $recipes ); + asrt( $recipe2->name, 'Love cake' ); + $recipe3 = array_shift( $recipes ); + asrt( $recipe3->name, 'Soup of Madness' ); + $categories = $book->sharedCategoryList; + asrt( count($categories), 1 ); + $category = reset( $categories ); + asrt( $category->label, 'wizardry' ); + asrt( $book->author->name, 'Dr. Evil' ); + asrt( $book->fetchAs('author')->coAuthor->name, 'Dr. Creepy' ); + try { + $list = R::dispense( array() ); + pass(); + asrt( is_array( $list ), TRUE ); + asrt( count( $list ), 0 ); + } catch ( RedException $ex ) { + pass(); + } + try { + R::dispense( array( array() ) ); + fail(); + } catch ( RedException $ex ) { + pass(); + } + try { + R::dispense( array( 'a' ) ); + fail(); + } catch ( RedException $ex ) { + pass(); + } + try { + R::dispense( array( 'property' => 'value' ) ); + fail(); + } catch ( RedException $ex ) { + pass(); + } + } + + /** + * Test import from and tainted. + * + * @return void + */ + public function testImportFromAndTainted() + { + testpack( 'Test importFrom() and Tainted' ); + $bean = R::dispense( 'bean' ); + R::store( $bean ); + $bean->name = 'abc'; + asrt( $bean->getMeta( 'tainted' ), TRUE ); + R::store( $bean ); + asrt( $bean->getMeta( 'tainted' ), FALSE ); + $copy = R::dispense( 'bean' ); + R::store( $copy ); + $copy = R::load( 'bean', $copy->id ); + asrt( $copy->getMeta( 'tainted' ), FALSE ); + $copy->import( array( 'name' => 'xyz' ) ); + asrt( $copy->getMeta( 'tainted' ), TRUE ); + $copy->setMeta( 'tainted', FALSE ); + asrt( $copy->getMeta( 'tainted' ), FALSE ); + $copy->importFrom( $bean ); + asrt( $copy->getMeta( 'tainted' ), TRUE ); + testpack( 'Test basic import() feature.' ); + $bean = new OODBBean; + $bean->import( array( "a" => 1, "b" => 2 ) ); + asrt( $bean->a, 1 ); + asrt( $bean->b, 2 ); + $bean->import( array( "a" => 3, "b" => 4 ), "a,b" ); + asrt( $bean->a, 3 ); + asrt( $bean->b, 4 ); + $bean->import( array( "a" => 5, "b" => 6 ), " a , b " ); + asrt( $bean->a, 5 ); + asrt( $bean->b, 6 ); + $bean->import( array( "a" => 1, "b" => 2 ) ); + testpack( 'Test inject() feature.' ); + $coffee = R::dispense( 'coffee' ); + $coffee->id = 2; + $coffee->liquid = 'black'; + $cup = R::dispense( 'cup' ); + $cup->color = 'green'; + // Pour coffee in cup + $cup->inject( $coffee ); + // Do we still have our own property? + asrt( $cup->color, 'green' ); + // Did we pour the liquid in the cup? + asrt( $cup->liquid, 'black' ); + // Id should not be transferred + asrt( $cup->id, 0 ); + } + + /** + * Test import using array access functions + * + * @return void + */ + public function testArrayAccess() + { + $book = R::dispense( 'book' ); + $book->isAwesome = TRUE; + asrt( isset( $book->isAwesome ), TRUE ); + $book = R::dispense( 'book' ); + $book['isAwesome'] = TRUE; + asrt( isset( $book->isAwesome ), TRUE ); + $book = R::dispense( 'book' ); + $book['xownPageList'] = R::dispense( 'page', 2 ); + asrt( isset( $book->ownPage ), TRUE ); + asrt( isset( $book->xownPage ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + asrt( isset( $book->xownPageList ), TRUE ); + $book = R::dispense( 'book' ); + $book['ownPageList'] = R::dispense( 'page', 2 ); + asrt( isset( $book->ownPage ), TRUE ); + asrt( isset( $book->xownPage ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + asrt( isset( $book->xownPageList ), TRUE ); + $book = R::dispense( 'book' ); + $book['xownPage'] = R::dispense( 'page', 2 ); + asrt( isset( $book->ownPage ), TRUE ); + asrt( isset( $book->xownPage ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + asrt( isset( $book->xownPageList ), TRUE ); + $book = R::dispense( 'book' ); + $book['ownPage'] = R::dispense( 'page', 2 ); + asrt( isset( $book->ownPage ), TRUE ); + asrt( isset( $book->xownPage ), TRUE ); + asrt( isset( $book->ownPageList ), TRUE ); + asrt( isset( $book->xownPageList ), TRUE ); + $book = R::dispense( 'book' ); + $book['sharedTag'] = R::dispense( 'tag', 2 ); + asrt( isset( $book->sharedTag ), TRUE ); + asrt( isset( $book->sharedTagList ), TRUE ); + $book = R::dispense( 'book' ); + $book['sharedTagList'] = R::dispense( 'tag', 2 ); + asrt( isset( $book->sharedTag ), TRUE ); + asrt( isset( $book->sharedTagList ), TRUE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Labels.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Labels.php new file mode 100644 index 000000000..7259dc9d3 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Labels.php @@ -0,0 +1,47 @@ +setMeta( "this.is.a.custom.metaproperty", "yes" ); + asrt( $bean->getMeta( "this.is.a.custom.metaproperty" ), "yes" ); + asrt( $bean->getMeta( "nonexistant" ), NULL ); + asrt( $bean->getMeta( "nonexistant", "abc" ), "abc" ); + asrt( $bean->getMeta( "nonexistant.nested" ), NULL ); + asrt( $bean->getMeta( "nonexistant,nested", "abc" ), "abc" ); + $bean->setMeta( "test.two", "second" ); + asrt( $bean->getMeta( "test.two" ), "second" ); + $bean->setMeta( "another.little.property", "yes" ); + asrt( $bean->getMeta( "another.little.property" ), "yes" ); + asrt( $bean->getMeta( "test.two" ), "second" ); + // Copy Metadata + $bean = new OODBBean; + $bean->setMeta( "meta.meta", "123" ); + $bean2 = new OODBBean; + asrt( $bean2->getMeta( "meta.meta" ), NULL ); + $bean2->copyMetaFrom( $bean ); + asrt( $bean2->getMeta( "meta.meta" ), "123" ); + } + + /** + * Meta properties should not be saved. + * + * @return void + */ + public function testMetaPersist() + { + $bean = R::dispense( 'bean' ); + $bean->property = 'test'; + $bean->setMeta( 'meta', 'hello' ); + R::store( $bean ); + asrt( $bean->getMeta( 'meta' ), 'hello' ); + $bean = $bean->fresh(); + asrt( $bean->getMeta( 'meta' ), NULL ); + } + + /** + * You cant access meta data using the array accessors. + * + * @return void + */ + public function testNoArrayMetaAccess() + { + $bean = R::dispense( 'bean' ); + $bean->setMeta( 'greet', 'hello' ); + asrt( isset( $bean['greet'] ), FALSE ); + asrt( isset( $bean['__info']['greet'] ), FALSE ); + asrt( isset( $bean['__info'] ), FALSE ); + asrt( isset( $bean['meta'] ), FALSE ); + asrt( count( $bean ), 1 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Misc.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Misc.php new file mode 100644 index 000000000..4e9fda7ed --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Misc.php @@ -0,0 +1,516 @@ +name = 'Overlook'; + $room = R::dispense( 'room' ); + $room->number = 237; + $hotel->ownRoomList[] = $room; + $shine = (string) $hotel; + asrt( $shine, '{"id":0,"name":"Overlook"}' ); //basic JSON + $shine = json_encode( $hotel->jsonSerialize() ); //As of PHP 5.4 json_encode() will call jsonSerializable + asrt( $shine, '{"id":0,"name":"Overlook","ownRoom":[{"id":0,"number":237}]}' ); //should get full JSON + } + + /** + * Tests max parameter binding. + * + * @return void + */ + public function testIntegerBindingMax() + { + if ( defined( 'HHVM_VERSION' ) ) return; //not for hhvm... + $driver = new RPDO( 'test-sqlite-53', 'user', 'pass' ); + $max = $driver->getIntegerBindingMax(); + asrt( $max, 2147483647 ); + $driver = new RPDO( 'cubrid', 'user', 'pass' ); + $max = $driver->getIntegerBindingMax(); + asrt( $max, 2147483647 ); + $driver = new RPDO( 'other', 'user', 'pass' ); + $max = $driver->getIntegerBindingMax(); + asrt( $max, PHP_INT_MAX ); + } + + /** + * Should not be able to pass invalid mode (must be 0 or 1). + * + */ + public function testInvalidDebugModeException() + { + try { + R::debug( TRUE, 6 ); + fail(); + } catch ( RedException $e ) { + pass(); + } + R::debug( FALSE ); + } + + /** + * Adding a database twice no longer allowed, causes confusion + * and possible damage. + */ + public function testAddingTwice() + { + testpack( 'Test adding DB twice.' ); + + try { + R::addDatabase( 'sqlite', '' ); + fail(); + } catch ( RedException $ex ) { + pass(); + } + } + + /** + * Tests whether getID never produces a notice. + * + * @return void + */ + public function testGetIDShouldNeverPrintNotice() + { + set_error_handler(function($err, $errStr){ + die('>>>>FAIL :'.$err.' '.$errStr); + }); + $bean = new OODBBean; + $bean->getID(); + restore_error_handler(); + pass(); + } + + /** + * Tests setProperty. + * + * @return void + */ + public function testSetProperty() + { + $bean = R::dispense( 'bean' ); + $bean->item = 2; + $bean->ownBean = R::dispense( 'bean', 2 ); + R::store( $bean ); + $bean = $bean->fresh(); + $bean->ownBean; + $bean->setProperty( 'ownBean', array(), FALSE, FALSE ); + asrt( count( $bean->ownBean ), 0 ); + asrt( count( $bean->getMeta( 'sys.shadow.ownBean' ) ), 2 ); + asrt( $bean->isTainted(), TRUE ); + $bean->setProperty( 'ownBean', array(), TRUE, FALSE ); + asrt( count( $bean->ownBean ), 0 ); + asrt( count( $bean->getMeta( 'sys.shadow.ownBean' ) ), 0 ); + asrt( $bean->isTainted(), TRUE ); + $bean = $bean->fresh(); + $bean->setProperty( 'ownBean', array(), TRUE, FALSE ); + asrt( count( $bean->ownBean ), 0 ); + asrt( count( $bean->getMeta( 'sys.shadow.ownBean' ) ), 0 ); + asrt( $bean->isTainted(), FALSE ); + $bean = $bean->fresh(); + $bean->setProperty( 'ownBean', array(), TRUE, TRUE ); + asrt( count( $bean->ownBean ), 0 ); + asrt( count( $bean->getMeta( 'sys.shadow.ownBean' ) ), 0 ); + asrt( $bean->isTainted(), TRUE ); + } + + /** + * Tests beansToArray(). + * + * @return void + */ + public function testBeansToArray() + { + testpack('Test R::beansToArray method'); + $bean1 = R::dispense( 'bean' ); + $bean1->name = 'hello'; + $bean2 = R::dispense( 'bean' ); + $bean2->name = 'world'; + $beans = array( $bean1, $bean2 ); + $array = R::beansToArray( $beans ); + asrt( $array[0]['name'], 'hello' ); + asrt( $array[1]['name'], 'world' ); + } + + /** + * Test debugging with custom logger. + * + * @return void + */ + public function testDebugCustomLogger() + { + testpack( 'Test debug mode with custom logger' ); + $pdoDriver = new RPDO( R::getDatabaseAdapter()->getDatabase()->getPDO() ); + $customLogger = new CustomLogger; + $pdoDriver->setDebugMode( TRUE, $customLogger ); + $pdoDriver->Execute( 'SELECT 123' ); + asrt( count( $customLogger->getLogMessage() ), 1 ); + $pdoDriver->setDebugMode( TRUE, NULL ); + asrt( ( $pdoDriver->getLogger() instanceof RDefault ), TRUE ); + testpack( 'Test bean->getProperties method' ); + $bean = R::dispense( 'bean' ); + $bean->property = 'hello'; + $props = $bean->getProperties(); + asrt( isset( $props['property'] ), TRUE ); + asrt( $props['property'], 'hello' ); + + } + + /** + * Test Facade transactions. + * + * @return void + * + * @throws\Exception + */ + public function testTransactionInFacade() + { + testpack( 'Test transaction in facade' ); + $bean = R::dispense( 'bean' ); + $bean->name = 'a'; + R::store( $bean ); + R::trash( $bean ); + R::freeze( TRUE ); + $bean = R::dispense( 'bean' ); + $bean->name = 'a'; + R::store( $bean ); + asrt( R::count( 'bean' ), 1 ); + R::trash( $bean ); + asrt( R::count( 'bean' ), 0 ); + $bean = R::dispense( 'bean' ); + $bean->name = 'a'; + $id = R::transaction( function() use( &$bean ) { + return R::transaction( function() use( &$bean ) { + return R::store( $bean ); + } ); + } ); + asrt( (int) $id, (int) $bean->id ); + R::trash( $bean ); + $bean = R::dispense( 'bean' ); + $bean->name = 'a'; + $id = R::transaction( function() use( &$bean ) { + return R::store( $bean ); + } ); + asrt( (int) $id, (int) $bean->id ); + R::trash( $bean ); + $bean = R::dispense( 'bean' ); + $bean->name = 'a'; + try { + R::transaction( function () use ( $bean ) { + R::store( $bean ); + R::transaction( function () { + throw new\Exception(); + } ); + } ); + } catch (\Exception $e ) { + pass(); + } + asrt( R::count( 'bean' ), 0 ); + $bean = R::dispense( 'bean' ); + $bean->name = 'a'; + try { + R::transaction( function () use ( $bean ) { + R::transaction( function () use ( $bean ) { + R::store( $bean ); + throw new\Exception(); + } ); + } ); + } catch (\Exception $e ) { + pass(); + } + asrt( R::count( 'bean' ), 0 ); + $bean = R::dispense( 'bean' ); + $bean->name = 'a'; + try { + R::transaction( function () use ( $bean ) { + R::transaction( function () use ( $bean ) { + R::store( $bean ); + } ); + } ); + } catch (\Exception $e ) { + pass(); + } + asrt( R::count( 'bean' ), 1 ); + R::freeze( FALSE ); + try { + R::transaction( 'nope' ); + fail(); + } catch (\Exception $e ) { + pass(); + } + testpack( 'Test Camelcase 2 underscore' ); + $names = array( + 'oneACLRoute' => 'one_acl_route', + 'ALLUPPERCASE' => 'alluppercase', + 'clientServerArchitecture' => 'client_server_architecture', + 'camelCase' => 'camel_case', + 'peer2peer' => 'peer2peer', + 'fromUs4You' => 'from_us4_you', + 'lowercase' => 'lowercase', + 'a1A2b' => 'a1a2b', + ); + $bean = R::dispense( 'bean' ); + foreach ( $names as $name => $becomes ) { + $bean->$name = 1; + asrt( isset( $bean->$becomes ), TRUE ); + } + testpack( 'Misc Tests' ); + R::debug( 1 ); + flush(); + ob_start(); + R::exec( 'SELECT 123' ); + $out = ob_get_contents(); + ob_end_clean(); + flush(); + pass(); + asrt( ( strpos( $out, 'SELECT 123' ) !== FALSE ), TRUE ); + R::debug( 0 ); + flush(); + ob_start(); + R::exec( 'SELECT 123' ); + $out = ob_get_contents(); + ob_end_clean(); + flush(); + pass(); + asrt( $out, '' ); + R::debug( 0 ); + pass(); + testpack( 'test to string override' ); + $band = R::dispense( 'band' ); + $str = strval( $band ); + asrt( $str, 'bigband' ); + testpack( 'test whether we can use isset/set in model' ); + $band->setProperty( 'property1', 123 ); + asrt( $band->property1, 123 ); + asrt( $band->checkProperty( 'property1' ), TRUE ); + asrt( $band->checkProperty( 'property2' ), FALSE ); + $band = new \Model_Band; + $bean = R::dispense( 'band' ); + $bean->property3 = 123; + $band->loadBean( $bean ); + $bean->property4 = 345; + $band->setProperty( 'property1', 123 ); + asrt( $band->property1, 123 ); + asrt( $band->checkProperty( 'property1' ), TRUE ); + asrt( $band->checkProperty( 'property2' ), FALSE ); + asrt( $band->property3, 123 ); + asrt( $band->property4, 345 ); + testpack( 'Can we pass a\PDO object to Setup?' ); + $pdo = new \PDO( 'sqlite:test.db' ); + R::addDatabase( 'pdo', $pdo ); + R::selectDatabase( 'pdo' ); + R::getCell('SELECT 123;'); + testpack( 'Test array interface of beans' ); + $bean = R::dispense( 'bean' ); + $bean->hello = 'hi'; + $bean->world = 'planet'; + asrt( $bean['hello'], 'hi' ); + asrt( isset( $bean['hello'] ), TRUE ); + asrt( isset( $bean['bye'] ), FALSE ); + $bean['world'] = 'sphere'; + asrt( $bean->world, 'sphere' ); + foreach ( $bean as $key => $el ) { + if ( $el == 'sphere' || $el == 'hi' || $el == 0 ) { + pass(); + } else { + fail(); + } + if ( $key == 'hello' || $key == 'world' || $key == 'id' ) { + pass(); + } else { + fail(); + } + } + asrt( count( $bean ), 3 ); + unset( $bean['hello'] ); + asrt( count( $bean ), 2 ); + asrt( count( R::dispense( 'countable' ) ), 1 ); + // Otherwise untestable... + $bean->setBeanHelper( new SimpleFacadeBeanHelper() ); + R::getRedBean()->setBeanHelper( new SimpleFacadeBeanHelper() ); + pass(); + // Test whether properties like owner and shareditem are still possible + testpack( 'Test Bean Interface for Lists' ); + $bean = R::dispense( 'bean' ); + // Must not be list, because first char after own is lowercase + asrt( is_array( $bean->owner ), FALSE ); + // Must not be list, because first char after shared is lowercase + asrt( is_array( $bean->shareditem ), FALSE ); + asrt( is_array( $bean->own ), FALSE ); + asrt( is_array( $bean->shared ), FALSE ); + asrt( is_array( $bean->own_item ), FALSE ); + asrt( is_array( $bean->shared_item ), FALSE ); + asrt( is_array( $bean->{'own item'} ), FALSE ); + asrt( is_array( $bean->{'shared Item'} ), FALSE ); + } + + public function testConv2Beans() + { + $row1 = array('id' => 1, 'title'=>'test'); + $row2 = array('id' => 2, 'title'=>'test2'); + $beans = R::convertToBeans('page', array($row1, $row2)); + asrt(count($beans), 2); + asrt($beans[2]->title, 'test2'); + } + + /** + * Test the most important invalid bean combinations. + * + * @return void + */ + public function testInvalidType() + { + $invalid = array( + 'book_page', //no link beans + 'a_b_c', //no prefix + 'a b', //no space + 'bean@', //no invalid symbols + 'bean#', //no invalid symbols + 'bean$', //sometimes used in DB, not allowed + '__bean',//no prefixes + '.bean', //no object notation + 'bean-item', //no dash + 'beanOther'); //no camelcase (uppercase because of file system issues) + + foreach( $invalid as $j ) { + try { + R::dispense( $j ); + fail(); + } catch( RedException $e ) { + pass(); + } + } + } + + /** + * Test whether batch still works if no IDs have been passed. + * + * @return void + */ + public function testBatch0() + { + $zero = R::batch( 'page', array() ); + asrt( is_array( $zero ), TRUE ); + asrt( count( $zero ), 0 ); + $zero = R::batch( 'page', FALSE ); + asrt( is_array( $zero ), TRUE ); + asrt( count( $zero ), 0 ); + $zero = R::batch( 'page', NULL); + asrt( is_array( $zero ), TRUE ); + asrt( count( $zero ), 0 ); + } + + /** + * Test whether connection failure does not reveal + * credentials. + * + * @return void + */ + public function testConnect() + { + $driver = new RPDO( 'dsn:invalid', 'usr', 'psst' ); + try { + $driver->connect(); + fail(); + } + catch( \PDOException $e ) { + asrt( strpos( $e->getMessage(), 'invalid' ), FALSE ); + asrt( strpos( $e->getMessage(), 'usr' ), FALSE ); + asrt( strpos( $e->getMessage(), 'psst' ), FALSE ); + } + } + + /** + * Test whether we can create an instant database using + * R::setup(). + * + * Probably only works on *NIX systems. + * + * @return void + */ + public function testSetup() + { + $tmpDir = sys_get_temp_dir(); + R::setup(); + } + + /** + * Test camelCase to snake_case conversions. + * + * @return void + */ + public function testCamel2Snake() + { + asrt( AQueryWriter::camelsSnake('bookPage'), 'book_page' ); + asrt( AQueryWriter::camelsSnake('FTP'), 'ftp' ); + asrt( AQueryWriter::camelsSnake('ACLRules'), 'acl_rules' ); + asrt( AQueryWriter::camelsSnake('SSHConnectionProxy'), 'ssh_connection_proxy' ); + asrt( AQueryWriter::camelsSnake('proxyServerFacade'), 'proxy_server_facade' ); + asrt( AQueryWriter::camelsSnake('proxySSHClient'), 'proxy_ssh_client' ); + asrt( AQueryWriter::camelsSnake('objectACL2Factory'), 'object_acl2_factory' ); + asrt( AQueryWriter::camelsSnake('bookItems4Page'), 'book_items4_page' ); + asrt( AQueryWriter::camelsSnake('book☀Items4Page'), 'book☀_items4_page' ); + } +} + +/** + * Custom Logger class. + * For testing purposes. + */ +class CustomLogger extends RDefault +{ + + private $log; + + public function getLogMessage() + { + return $this->log; + } + + public function log() + { + $this->log = func_get_args(); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Plugins.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Plugins.php new file mode 100644 index 000000000..2ae7975f3 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Plugins.php @@ -0,0 +1,82 @@ +getMessage(), 'Plugin name may only contain alphanumeric characters.' ); + } + + try { + R::__callStatic( '---', function() {} ); + fail(); + } catch ( RedException $e ) { + asrt( $e->getMessage(), 'Plugin name may only contain alphanumeric characters.' ); + } + + try { + R::invalidMethod(); + fail(); + } catch ( RedException $e ) { + asrt( $e->getMessage(), 'Plugin \'invalidMethod\' does not exist, add this plugin using: R::ext(\'invalidMethod\')' ); + } + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Tainted.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Tainted.php new file mode 100644 index 000000000..306949227 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Tainted.php @@ -0,0 +1,131 @@ +hasListChanged( 'ownPage' ), FALSE ); + $book->ownPage[] = $page; + asrt( $book->hasListChanged( 'ownPage' ), TRUE ); + R::store( $book ); + $book = $book->fresh(); + asrt( $book->hasListChanged( 'ownPage' ), FALSE ); + $page = R::dispense( 'page' ); + $book->ownPageList[] = $page; + asrt( $book->hasListChanged( 'ownPage' ), TRUE ); + R::store( $book ); + $book = $book->fresh(); + asrt( $book->hasListChanged( 'ownPage' ), FALSE ); + asrt( count( $book->ownPageList ), 2 ); + array_pop( $book->ownPageList ); + asrt( count( $book->ownPageList ), 1 ); + asrt( $book->hasListChanged( 'ownPage' ), TRUE ); + array_pop( $book->ownPageList ); + asrt( count( $book->ownPageList ), 0 ); + asrt( $book->hasListChanged( 'ownPage' ), TRUE ); + $book = $book->fresh(); + asrt( $book->hasListChanged( 'ownPage' ), FALSE ); + asrt( count( $book->ownPageList ), 2 ); + $otherPage = R::dispense( 'page' ); + array_pop( $book->ownPageList ); + $book->ownPageList[] = $otherPage; + asrt( count( $book->ownPageList ), 2 ); + asrt( $book->hasListChanged( 'ownPage' ), TRUE ); + $book = $book->fresh(); + $firstPage = reset( $book->ownPageList ); + $firstPage->content = 'abc'; + asrt( $book->hasListChanged( 'ownPage' ), FALSE ); + $book = $book->fresh(); + asrt( $book->hasListChanged( 'ownPage' ), FALSE ); + $lastPage = end( $book->ownPageList ); + $lastPage->ownText[] = R::dispense( 'text' ); + asrt( $book->hasListChanged( 'ownPage' ), FALSE ); + } + + /** + * Tests whether we can clear the history of a bean. + * + * @return void + */ + public function testClearHist() + { + R::nuke(); + $book = R::dispense( 'book' ); + asrt( $book->hasChanged( 'title' ), FALSE ); + $book->title = 'book'; + asrt( $book->hasChanged( 'title' ), TRUE ); + R::store( $book ); + asrt( $book->hasChanged( 'title' ), TRUE ); + $book->clearHistory(); + asrt( $book->hasChanged( 'title' ), FALSE ); + } + + /** + * Test tainted. + * + * @return void + */ + public function testTainted() + { + testpack( 'Original Tainted Tests' ); + $redbean = R::getRedBean(); + $spoon = $redbean->dispense( "spoon" ); + asrt( $spoon->getMeta( "tainted" ), TRUE ); + $spoon->dirty = "yes"; + asrt( $spoon->getMeta( "tainted" ), TRUE ); + testpack( 'Tainted List test' ); + $note = R::dispense( 'note' ); + $note->text = 'abc'; + $note->ownNote[] = R::dispense( 'note' )->setAttr( 'text', 'def' ); + $id = R::store( $note ); + $note = R::load( 'note', $id ); + asrt( $note->isTainted(), FALSE ); + // Shouldn't affect tainted + $note->text; + asrt( $note->isTainted(), FALSE ); + $note->ownNote; + asrt( $note->isTainted(), TRUE ); + testpack( 'Tainted Test Old Value' ); + $text = $note->old( 'text' ); + asrt( $text, 'abc' ); + asrt( $note->hasChanged( 'text' ), FALSE ); + $note->text = 'xxx'; + asrt( $note->hasChanged( 'text' ), TRUE ); + $text = $note->old( 'text' ); + asrt( $text, 'abc' ); + testpack( 'Tainted Non-exist' ); + asrt( $note->hasChanged( 'text2' ), FALSE ); + testpack( 'Misc Tainted Tests' ); + $bean = R::dispense( 'bean' ); + $bean->hasChanged( 'prop' ); + $bean->old( 'prop' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Toolbox.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Toolbox.php new file mode 100644 index 000000000..885ea5531 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Toolbox.php @@ -0,0 +1,148 @@ +getToolbox(); + asrt( ( $toolbox2 instanceof TB), TRUE ); + asrt( $toolbox, $toolbox2 ); + $extractedToolbox = $beanHelper->getExtractedToolbox(); + asrt( is_array( $extractedToolbox ), TRUE ); + asrt( count( $extractedToolbox ), 4 ); + asrt( ( $extractedToolbox[0] instanceof OODB ), TRUE ); + asrt( ( $extractedToolbox[1] instanceof Adapter ), TRUE ); + asrt( ( $extractedToolbox[2] instanceof QueryWriter ), TRUE ); + asrt( ( $extractedToolbox[3] instanceof TB ), TRUE ); + } + + /** + * Does the toolbox contain the necessary tools ? + * + * @return void + */ + public function testDoesToolboxContainTheTools() + { + $toolbox = R::getToolBox(); + asrt( ( $toolbox->getDatabaseAdapter() instanceof Adapter ), TRUE ); + asrt( ( $toolbox->getRedBean() instanceof OODB ), TRUE ); + asrt( ( $toolbox->getWriter() instanceof QueryWriter ), TRUE ); + } + + /** + * Tests whether freeze() switches the repository object + * as it is supposed to do. + * + * @return void + */ + public function testRepoSwitching() + { + asrt( class_exists( 'RedBeanPHP\Repository' ), TRUE ); + asrt( class_exists( 'RedBeanPHP\Repository\Fluid' ), TRUE ); + asrt( class_exists( 'RedBeanPHP\Repository\Frozen' ), TRUE ); + R::freeze( FALSE ); + $redbean = R::getRedBean(); + $repo = $redbean->getCurrentRepository(); + asrt( is_object( $repo ), TRUE ); + asrt( ( $repo instanceof Repository ), TRUE ); + asrt( ( $repo instanceof FluidRepo ), TRUE ); + R::freeze( TRUE ); + $fluid = $repo; + $repo = $redbean->getCurrentRepository(); + asrt( is_object( $repo ), TRUE ); + asrt( ( $repo instanceof Repository ), TRUE ); + asrt( ( $repo instanceof FrozenRepo ), TRUE ); + $frozen = $repo; + R::freeze( FALSE ); + $redbean = R::getRedBean(); + $repo = $redbean->getCurrentRepository(); + asrt( is_object( $repo ), TRUE ); + asrt( ( $repo instanceof Repository ), TRUE ); + asrt( ( $repo instanceof FluidRepo ), TRUE ); + asrt( $repo, $fluid ); + R::freeze( TRUE ); + $fluid = $repo; + $repo = $redbean->getCurrentRepository(); + asrt( is_object( $repo ), TRUE ); + asrt( ( $repo instanceof Repository ), TRUE ); + asrt( ( $repo instanceof FrozenRepo ), TRUE ); + asrt( $repo, $frozen ); + R::freeze( FALSE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Version.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Version.php new file mode 100644 index 000000000..678ade08d --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Blackhole/Version.php @@ -0,0 +1,48 @@ +sqlStateIn( '000', array() ); + // Unknown state must return FALSE. + asrt( $a, FALSE ); + try { + R::getWriter()->esc( '`aaa`' ); + fail(); + } catch (\Exception $e ) { + pass(); + } + asrt( ( $e instanceof RedException ), TRUE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/CUBRID/Writer.php b/vendor/gabordemooij/redbean/testing/RedUNIT/CUBRID/Writer.php new file mode 100644 index 000000000..fe34f27f6 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/CUBRID/Writer.php @@ -0,0 +1,58 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + + $writer->createTable( "testtable" ); + + $writer->addColumn( "testtable", "special", CUBRID::C_DATATYPE_SPECIAL_DATE ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols['special'], TRUE ), CUBRID::C_DATATYPE_SPECIAL_DATE ); + + asrt( $writer->code( $cols['special'], FALSE ), CUBRID::C_DATATYPE_SPECIFIED ); + + $writer->addColumn( "testtable", "special2", CUBRID::C_DATATYPE_SPECIAL_DATETIME ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols['special2'], TRUE ), CUBRID::C_DATATYPE_SPECIAL_DATETIME ); + + asrt( $writer->code( $cols['special'], FALSE ), CUBRID::C_DATATYPE_SPECIFIED ); + + } + +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql.php new file mode 100644 index 000000000..e8ca95b66 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql.php @@ -0,0 +1,35 @@ +id, $book1ID ); + asrt( $book1->title, 'book 1' ); + + $book2 = R::load( 'book', $book2ID ); + + asrt( $book2->id, $book2ID ); + asrt( $book2->title, 'book 2' ); + + asrt( count( $book1->ownPage ), 2 ); + asrt( count( $book1->fresh()->with( 'LIMIT 1' )->ownPage ), 1 ); + asrt( count( $book1->fresh()->withCondition( ' title = ? ', array('page 2 of book 1'))->ownPage ), 1 ); + + asrt( count($book2->ownPage), 1 ); + asrt( $book2->fresh()->countOwn( 'page' ), 1 ); + + $page1 = R::load( 'page', $page1ID ); + asrt( count( $page1->sharedPage ), 0 ); + asrt( $page1->fetchAs( 'book' )->magazine->id, $book2ID ); + + $page2 = R::load( 'page', $page2ID ); + asrt( count($page2->sharedPage), 1 ); + asrt( $page2->fresh()->countShared( 'page' ), 1 ); + + $page3 = R::findOne( 'page', ' title = ? ', array( 'page 1 of book 2' ) ); + asrt( $page3->id, $page3ID ); + asrt( $page3->book->id, $book2ID ); + + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Double.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Double.php new file mode 100644 index 000000000..42422879f --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Double.php @@ -0,0 +1,50 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + $largeDouble = 999999888889999922211111; //8.88889999922211e+17; + $page = $redbean->dispense( "page" ); + $page->weight = $largeDouble; + $id = $redbean->store( $page ); + $cols = $writer->getColumns( 'page' ); + asrt( $cols['weight'], 'double' ); + $page = $redbean->load( 'page', $id ); + $page->name = 'dont change the numbers!'; + $redbean->store( $page ); + $page = $redbean->load( 'page', $id ); + $cols = $writer->getColumns( 'page' ); + asrt( $cols['weight'], 'double' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Foreignkeys.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Foreignkeys.php new file mode 100644 index 000000000..1d9a71ac9 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Foreignkeys.php @@ -0,0 +1,429 @@ +xownMetrics[] = $metrics; + R::store( $constraint ); + asrt( 1, R::count( 'metrics' ) ); + R::trash($constraint); + asrt( 0, R::count( 'metrics') ); + } + + /** + * Basic FK tests. + * + * @return void + */ + public function testFKS() + { + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $cover = R::dispense( 'cover' ); + + list( $g1, $g2 ) = R::dispense( 'genre', 2 ); + + $g1->name = '1'; + $g2->name = '2'; + + $book->ownPage = array( $page ); + + $book->cover = $cover; + + $book->sharedGenre = array( $g1, $g2 ); + + R::store( $book ); + + $fkbook = R::getAll( 'describe book' ); + $fkgenre = R::getAll( 'describe book_genre' ); + $fkpage = R::getAll( 'describe cover' ); + + $j = json_encode( R::getAll( 'SELECT + ke.referenced_table_name parent, + ke.table_name child, + ke.constraint_name + FROM + information_schema.KEY_COLUMN_USAGE ke + WHERE + ke.referenced_table_name IS NOT NULL + AND ke.CONSTRAINT_SCHEMA="oodb" + ORDER BY + constraint_name;' ) ); + + $json = '[ + { + "parent": "genre", + "child": "book_genre", + "constraint_name": "c_fk_book_genre_genre_id" + }, + { + "parent": "book", + "child": "book_genre", + "constraint_name": "c_fk_book_genre_book_id" + }, + { + "parent": "cover", + "child": "book", + "constraint_name": "c_fk_book_cover_id" + }, + { + "parent": "book", + "child": "page", + "constraint_name": "c_fk_page_book_id" + } + ]'; + + $j1 = json_decode( $j, TRUE ); + + $j2 = json_decode( $json, TRUE ); + + foreach ( $j1 as $jrow ) { + $s = json_encode( $jrow ); + + $found = 0; + + foreach ( $j2 as $k => $j2row ) { + + if ( json_encode( $j2row ) === $s ) { + pass(); + + unset( $j2[$k] ); + + $found = 1; + break; + } + } + + if ( !$found ) fail(); + } + } + + /** + * Test widen for constraint. + * + * @return void + */ + public function testWideningColumnForConstraint() + { + testpack( 'widening column for constraint' ); + + $bean1 = R::dispense( 'project' ); + $bean2 = R::dispense( 'invoice' ); + + $bean3 = R::getRedBean()->dispense( 'invoice_project' ); + + $bean3->project_id = false; + $bean3->invoice_id = true; + + R::store( $bean3 ); + + $cols = R::getColumns( 'invoice_project' ); + + asrt( $cols['project_id'], "int(11) unsigned" ); + asrt( $cols['invoice_id'], "int(11) unsigned" ); + } + + /** + * Test adding of constraints directly by invoking + * the writer method. + * + * @return void + */ + public function testContrain() + { + R::nuke(); + + $sql = ' + CREATE TABLE book ( + id INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT, + PRIMARY KEY ( id ) + ) + ENGINE = InnoDB + '; + + R::exec( $sql ); + + $sql = ' + CREATE TABLE page ( + id INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT, + PRIMARY KEY ( id ) + ) + ENGINE = InnoDB + '; + + R::exec( $sql ); + + $sql = ' + CREATE TABLE book_page ( + id INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT, + book_id INT( 11 ) UNSIGNED NOT NULL, + page_id INT( 11 ) UNSIGNED NOT NULL, + PRIMARY KEY ( id ) + ) + ENGINE = InnoDB + '; + + R::exec( $sql ); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "book_page" AND DELETE_RULE = "CASCADE"'); + + asrt( (int) $numOfFKS, 0 ); + + $writer = R::getWriter(); + + $writer->addFK( 'book_page', 'book', 'book_id', 'id', TRUE ); + $writer->addFK( 'book_page', 'page', 'page_id', 'id', TRUE ); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "book_page" AND DELETE_RULE = "CASCADE"'); + + asrt( (int) $numOfFKS, 2 ); + + $writer->addFK( 'book_page', 'book', 'book_id', 'id', TRUE ); + $writer->addFK( 'book_page', 'page', 'page_id', 'id', TRUE ); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "book_page" AND DELETE_RULE = "CASCADE"'); + + asrt( (int) $numOfFKS, 2 ); + } + + /** + * Test adding foreign keys. + * + * @return void + */ + public function testAddingForeignKey() + { + R::nuke(); + + $sql = ' + CREATE TABLE book ( + id INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT, + PRIMARY KEY ( id ) + ) + ENGINE = InnoDB + '; + + R::exec( $sql ); + + $sql = ' + CREATE TABLE page ( + id INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT, + book_id INT( 11 ) UNSIGNED NOT NULL, + PRIMARY KEY ( id ) + ) + ENGINE = InnoDB + '; + + R::exec( $sql ); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "page" AND DELETE_RULE = "CASCADE"'); + + asrt( (int) $numOfFKS, 0 ); + + $writer = R::getWriter(); + + //Can we add a foreign key with cascade? + $writer->addFK('page', 'book', 'book_id', 'id', TRUE); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "page" AND DELETE_RULE = "CASCADE"'); + + asrt( (int) $numOfFKS, 1 ); + + //dont add it twice + $writer->addFK('page', 'book', 'book_id', 'id', TRUE); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "page" AND DELETE_RULE = "CASCADE"'); + + asrt( (int) $numOfFKS, 1 ); + + //even if different + $writer->addFK('page', 'book', 'book_id', 'id', FALSE); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "page" '); + + asrt( (int) $numOfFKS, 1 ); + + //Now add non-dep key + R::nuke(); + + $sql = ' + CREATE TABLE book ( + id INT( 11 ) UNSIGNED NULL AUTO_INCREMENT, + PRIMARY KEY ( id ) + ) + ENGINE = InnoDB + '; + + R::exec( $sql ); + + $sql = ' + CREATE TABLE page ( + id INT( 11 ) UNSIGNED AUTO_INCREMENT, + book_id INT( 11 ) UNSIGNED NULL, + PRIMARY KEY ( id ) + ) + ENGINE = InnoDB + '; + + R::exec( $sql ); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "page" AND DELETE_RULE = "CASCADE"'); + + asrt( (int) $numOfFKS, 0 ); + + //even if different + $writer->addFK('page', 'book', 'book_id', 'id', FALSE); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "page" AND DELETE_RULE = "CASCADE"'); + + asrt( (int) $numOfFKS, 0 ); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "page" AND DELETE_RULE = "SET NULL"'); + + asrt( (int) $numOfFKS, 1 ); + + $writer->addFK('page', 'book', 'book_id', 'id', TRUE); + + $numOfFKS = R::getCell(' + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS + WHERE TABLE_NAME = "page" '); + } + + /** + * Test whether we can manually create indexes. + * + * @return void + */ + public function testAddingIndex() + { + R::nuke(); + + $sql = ' + CREATE TABLE song ( + id INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT, + album_id INT( 11 ) UNSIGNED NOT NULL, + category VARCHAR( 255 ), + PRIMARY KEY ( id ) + ) + ENGINE = InnoDB + '; + + R::exec( $sql ); + + $sql = 'SHOW INDEX FROM song'; + + $indexes = R::getAll( $sql ); + + asrt( count( $indexes ), 1 ); + asrt( $indexes[0]['Table'], 'song' ); + asrt( $indexes[0]['Key_name'], 'PRIMARY' ); + + $writer = R::getWriter(); + + $writer->addIndex('song', 'index1', 'album_id'); + + $indexes = R::getAll( 'SHOW INDEX FROM song' ); + + asrt( count( $indexes ), 2 ); + asrt( $indexes[0]['Table'], 'song' ); + asrt( $indexes[0]['Key_name'], 'PRIMARY' ); + asrt( $indexes[1]['Table'], 'song' ); + asrt( $indexes[1]['Key_name'], 'index1' ); + + //Cant add the same index twice + $writer->addIndex('song', 'index2', 'category'); + + $indexes = R::getAll( 'SHOW INDEX FROM song' ); + + asrt( count( $indexes ), 3 ); + + //Dont fail, just dont + try { + $writer->addIndex('song', 'index3', 'nonexistant'); + pass(); + } catch( \Exception $e ) { + fail(); + } + + asrt( count( $indexes ), 3 ); + + try { + $writer->addIndex('nonexistant', 'index4', 'nonexistant'); + pass(); + } catch( \Exception $e ) { + fail(); + } + + asrt( count( $indexes ), 3 ); + + try { + $writer->addIndex('nonexistant', '', 'nonexistant'); + pass(); + } catch( \Exception $e ) { + fail(); + } + + asrt( count( $indexes ), 3 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Freeze.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Freeze.php new file mode 100644 index 000000000..5fdea1f12 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Freeze.php @@ -0,0 +1,105 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + $a = new AssociationManager( $toolbox ); + $post = $redbean->dispense( 'post' ); + $post->title = 'title'; + $redbean->store( $post ); + $page = $redbean->dispense( 'page' ); + $page->name = 'title'; + $redbean->store( $page ); + $page = $redbean->dispense( "page" ); + $page->name = "John's page"; + $idpage = $redbean->store( $page ); + $page2 = $redbean->dispense( "page" ); + $page2->name = "John's second page"; + $idpage2 = $redbean->store( $page2 ); + $a->associate( $page, $page2 ); + $redbean->freeze( TRUE ); + $page = $redbean->dispense( "page" ); + $page->sections = 10; + $page->name = "half a page"; + try { + $id = $redbean->store( $page ); + fail(); + } catch ( SQL $e ) { + pass(); + } + $post = $redbean->dispense( "post" ); + $post->title = "existing table"; + try { + $id = $redbean->store( $post ); + pass(); + } catch ( SQL $e ) { + fail(); + } + asrt( in_array( "name", array_keys( $writer->getColumns( "page" ) ) ), TRUE ); + asrt( in_array( "sections", array_keys( $writer->getColumns( "page" ) ) ), FALSE ); + $newtype = $redbean->dispense( "newtype" ); + $newtype->property = 1; + try { + $id = $redbean->store( $newtype ); + fail(); + } catch ( SQL $e ) { + pass(); + } + $logger = R::debug( true, 1 ); + // Now log and make sure no 'describe SQL' happens + $page = $redbean->dispense( "page" ); + $page->name = "just another page that has been frozen..."; + $id = $redbean->store( $page ); + $page = $redbean->load( "page", $id ); + $page->name = "just a frozen page..."; + $redbean->store( $page ); + $page2 = $redbean->dispense( "page" ); + $page2->name = "an associated frozen page"; + $a->associate( $page, $page2 ); + $a->related( $page, "page" ); + $a->unassociate( $page, $page2 ); + $a->clearRelations( $page, "page" ); + $items = $redbean->find( "page", array(), array( "1" ) ); + $redbean->trash( $page ); + $redbean->freeze( FALSE ); + asrt( count( $logger->grep( "SELECT" ) ) > 0, TRUE ); + asrt( count( $logger->grep( "describe" ) ) < 1, TRUE ); + asrt( is_array( $logger->getLogs() ), TRUE ); + R::debug( FALSE ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Issue411.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Issue411.php new file mode 100644 index 000000000..ebfd3cc6f --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Issue411.php @@ -0,0 +1,63 @@ +text = 'abcd'; + R::store( $book ); + $columns = R::inspect( 'book' ); + asrt( isset( $columns['text'] ), TRUE ); + asrt( $columns['text'], 'varchar(191)' ); + $book = $book->fresh(); + $book->text = str_repeat( 'x', 190 ); + R::store( $book ); + $columns = R::inspect( 'book' ); + asrt( isset( $columns['text'] ), TRUE ); + asrt( $columns['text'], 'varchar(191)' ); + $book = $book->fresh(); + $book->text = str_repeat( 'x', 191 ); + R::store( $book ); + $columns = R::inspect( 'book' ); + asrt( isset( $columns['text'] ), TRUE ); + asrt( $columns['text'], 'varchar(191)' ); + $book = $book->fresh(); + $book->text = str_repeat( 'x', 192 ); + R::store( $book ); + $columns = R::inspect( 'book' ); + asrt( isset( $columns['text'] ), TRUE ); + asrt( $columns['text'], 'varchar(255)' ); + } +} + diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Parambind.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Parambind.php new file mode 100644 index 000000000..bed92c7d6 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Parambind.php @@ -0,0 +1,118 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + R::getDatabaseAdapter()->getDatabase()->setUseStringOnlyBinding( TRUE ); + try { + R::getAll( "select * from job limit ? ", array( 1 ) ); + fail(); + } catch (\Exception $e ) { + pass(); + } + try { + R::getAll( "select * from job limit :l ", array( ":l" => 1 ) ); + fail(); + } catch (\Exception $e ) { + pass(); + } + try { + R::exec( "select * from job limit ? ", array( 1 ) ); + fail(); + } catch (\Exception $e ) { + pass(); + } + try { + R::exec( "select * from job limit :l ", array( ":l" => 1 ) ); + fail(); + } catch (\Exception $e ) { + pass(); + } + R::getDatabaseAdapter()->getDatabase()->setUseStringOnlyBinding( FALSE ); + try { + R::getAll( "select * from job limit ? ", array( 1 ) ); + pass(); + } catch (\Exception $e ) { + fail(); + } + try { + R::getAll( "select * from job limit :l ", array( ":l" => 1 ) ); + pass(); + } catch (\Exception $e ) { + fail(); + } + try { + R::exec( "select * from job limit ? ", array( 1 ) ); + pass(); + } catch (\Exception $e ) { + fail(); + } + try { + R::exec( "select * from job limit :l ", array( ":l" => 1 ) ); + pass(); + } catch (\Exception $e ) { + fail(); + } + testpack( "Test findOrDispense" ); + $person = R::findOrDispense( "person", " job = ? ", array( "developer" ) ); + asrt( ( count( $person ) > 0 ), TRUE ); + $person = R::findOrDispense( "person", " job = ? ", array( "musician" ) ); + asrt( ( count( $person ) > 0 ), TRUE ); + $musician = array_pop( $person ); + asrt( intval( $musician->id ), 0 ); + try { + $adapter->exec( "an invalid query" ); + fail(); + } catch ( SQL $e ) { + pass(); + } + asrt( (int) $adapter->getCell( "SELECT 123" ), 123 ); + asrt( (int) $adapter->getCell( "SELECT ?", array( "987" ) ), 987 ); + asrt( (int) $adapter->getCell( "SELECT ?+?", array( "987", "2" ) ), 989 ); + asrt( (int) $adapter->getCell( "SELECT :numberOne+:numberTwo", array( + ":numberOne" => 42, ":numberTwo" => 50 ) ), 92 ); + $pair = $adapter->getAssoc( "SELECT 'thekey','thevalue' " ); + asrt( is_array( $pair ), TRUE ); + asrt( count( $pair ), 1 ); + asrt( isset( $pair["thekey"] ), TRUE ); + asrt( $pair["thekey"], "thevalue" ); + testpack( 'Test whether we can properly bind and receive NULL values' ); + asrt( $adapter->getCell( 'SELECT :nil ', array( ':nil' => 'NULL' ) ), 'NULL' ); + asrt( $adapter->getCell( 'SELECT :nil ', array( ':nil' => NULL ) ), NULL ); + asrt( $adapter->getCell( 'SELECT ? ', array( 'NULL' ) ), 'NULL' ); + asrt( $adapter->getCell( 'SELECT ? ', array( NULL ) ), NULL ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Preexist.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Preexist.php new file mode 100644 index 000000000..dcf4c2a9d --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Preexist.php @@ -0,0 +1,58 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + $a = new AssociationManager( $toolbox ); + $page = $redbean->dispense( "page" ); + $page->name = "John's page"; + $idpage = $redbean->store( $page ); + $page2 = $redbean->dispense( "page" ); + $page2->name = "John's second page"; + $idpage2 = $redbean->store( $page2 ); + $a->associate( $page, $page2 ); + $adapter->exec( "ALTER TABLE " . $writer->esc( 'page' ) . " + CHANGE " . $writer->esc( 'name' ) . " " . $writer->esc( 'name' ) . " + VARCHAR( 254 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL " ); + $page = $redbean->dispense( "page" ); + $page->name = "Just Another Page In a Table"; + $cols = $writer->getColumns( "page" ); + asrt( $cols["name"], "varchar(254)" ); + $redbean->store( $page ); + pass(); // No crash? + $cols = $writer->getColumns( "page" ); + asrt( $cols["name"], "varchar(254)" ); //must still be same + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Setget.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Setget.php new file mode 100644 index 000000000..8c777a7ae --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Setget.php @@ -0,0 +1,160 @@ +id, $book1ID ); + asrt( $book1->title, 'book 1' ); + + $book2 = R::load( 'book', $book2ID ); + + asrt( $book2->id, $book2ID ); + asrt( $book2->title, 'book 2' ); + + asrt( count( $book1->ownPage ), 2 ); + asrt( count( $book1->fresh()->with( 'LIMIT 1' )->ownPage ), 1 ); + asrt( count( $book1->fresh()->withCondition( ' title = ? ', array('page 2 of book 1'))->ownPage ), 1 ); + + asrt( count($book2->ownPage), 1 ); + asrt( $book2->fresh()->countOwn( 'page' ), 1 ); + + $page1 = R::load( 'page', $page1ID ); + asrt( count( $page1->sharedPage ), 0 ); + asrt( $page1->fetchAs( 'book' )->magazine->id, $book2ID ); + + $page2 = R::load( 'page', $page2ID ); + asrt( count($page2->sharedPage), 1 ); + asrt( $page2->fresh()->countShared( 'page' ), 1 ); + + $page3 = R::findOne( 'page', ' title = ? ', array( 'page 1 of book 2' ) ); + asrt( $page3->id, $page3ID ); + asrt( $page3->book->id, $book2ID ); + } + + /** + * Test Full fluid UUID support. + * + */ + public function testFullSupport() + { + R::nuke(); + //Rewire objects to support UUIDs. + $oldToolBox = R::getToolBox(); + $oldAdapter = $oldToolBox->getDatabaseAdapter(); + $uuidWriter = new \UUIDWriterMySQL( $oldAdapter ); + $newRedBean = new OODB( $uuidWriter ); + $newToolBox = new ToolBox( $newRedBean, $oldAdapter, $uuidWriter ); + R::configureFacadeWithToolbox( $newToolBox ); + + list( $mansion, $rooms, $ghosts, $key ) = R::dispenseAll( 'mansion,room*3,ghost*4,key' ); + $mansion->name = 'Haunted Mansion'; + $mansion->xownRoomList = $rooms; + $rooms[0]->name = 'Green Room'; + $rooms[1]->name = 'Red Room'; + $rooms[2]->name = 'Blue Room'; + $ghosts[0]->name = 'zero'; + $ghosts[1]->name = 'one'; + $ghosts[2]->name = 'two'; + $ghosts[3]->name = 'three'; + $rooms[0]->sharedGhostList = array( $ghosts[0], $ghosts[1] ); + $rooms[1]->sharedGhostList = array( $ghosts[0], $ghosts[2] ); + $rooms[2]->sharedGhostList = array( $ghosts[1], $ghosts[3], $ghosts[2] ); + $rooms[2]->xownKey = array( $key ); + //Can we store a bean hierachy with UUIDs? + $id = R::store( $mansion ); + asrt( is_string( $id ), TRUE ); + asrt( strlen( $id ), 36 ); + $haunted = R::load( 'mansion', $id ); + asrt( $haunted->name, 'Haunted Mansion' ); + asrt( is_string( $haunted->id ), TRUE ); + asrt( strlen( $haunted->id ), 36 ); + asrt( is_array( $haunted->xownRoomList ), TRUE ); + asrt( count( $haunted->ownRoom ), 3 ); + $rooms = $haunted->xownRoomList; + + //Do some counting... + $greenRoom = NULL; + foreach( $rooms as $room ) { + if ( $room->name === 'Green Room' ) { + $greenRoom = $room; + break; + } + } + asrt( !is_null( $greenRoom ), TRUE ); + asrt( is_array( $greenRoom->with(' ORDER BY id ')->sharedGhostList ), TRUE ); + asrt( count( $greenRoom->sharedGhostList ), 2 ); + $names = array(); + foreach( $greenRoom->sharedGhost as $ghost ) $names[] = $ghost->name; + sort($names); + $names = implode(',', $names); + asrt($names, 'one,zero'); + $rooms = $haunted->xownRoomList; + $blueRoom = NULL; + foreach( $rooms as $room ) { + if ( $room->name === 'Blue Room' ) { + $blueRoom = $room; + break; + } + } + asrt( !is_null( $blueRoom ), TRUE ); + asrt( is_array( $blueRoom->sharedGhostList ), TRUE ); + asrt( count( $blueRoom->sharedGhostList ), 3 ); + $names = array(); + foreach( $blueRoom->sharedGhost as $ghost ) $names[] = $ghost->name; + sort($names); + $names = implode(',', $names); + asrt($names, 'one,three,two'); + $rooms = $haunted->xownRoomList; + $redRoom = NULL; + foreach( $rooms as $room ) { + if ( $room->name === 'Red Room' ) { + $redRoom = $room; break; + } + } + $names = array(); + foreach( $redRoom->sharedGhost as $ghost ) $names[] = $ghost->name; + sort($names); + $names = implode(',', $names); + asrt($names, 'two,zero'); + asrt( !is_null( $redRoom ), TRUE ); + asrt( is_array( $redRoom->sharedGhostList ), TRUE ); + asrt( count( $redRoom->sharedGhostList ), 2 ); + + //Can we repaint a room? + $redRoom->name = 'Yellow Room'; + $id = R::store($redRoom); + $yellowRoom = R::load( 'room', $id ); + asrt( $yellowRoom->name, 'Yellow Room'); + asrt( !is_null( $yellowRoom ), TRUE ); + asrt( is_array( $yellowRoom->sharedGhostList ), TRUE ); + asrt( count( $yellowRoom->sharedGhostList ), 2 ); + + //Can we throw one ghost out? + array_pop( $yellowRoom->sharedGhost ); + R::store( $yellowRoom ); + $yellowRoom = $yellowRoom->fresh(); + asrt( $yellowRoom->name, 'Yellow Room'); + asrt( !is_null( $yellowRoom ), TRUE ); + asrt( is_array( $yellowRoom->sharedGhostList ), TRUE ); + asrt( count( $yellowRoom->sharedGhostList ), 1 ); + + //can we remove one of the rooms? + asrt( R::count('key'), 1); + $list = $mansion->withCondition(' `name` = ? ', array('Blue Room'))->xownRoomList; + $room = reset($list); + unset($mansion->xownRoomList[$room->id]); + R::store($mansion); + asrt(R::count('room'), 2); + + //and what about its dependent beans? + asrt(R::count('key'), 0); + asrt(R::count('ghost_room'), 3); + + //and can we find ghosts? + $ghosts = R::find('ghost'); + asrt(count($ghosts), 4); + $ghosts = R::findAll('ghost', 'ORDER BY id'); + asrt(count($ghosts), 4); + $ghosts = R::findAll('ghost', 'ORDER BY id LIMIT 2'); + asrt(count($ghosts), 2); + $ghostZero = R::findOne('ghost', ' `name` = ? ', array( 'zero' ) ); + asrt( ($ghostZero instanceof OODBBean), TRUE ); + + //can we create link properties on existing tables? + $blackRoom = R::dispense( 'room' ); + $blackRoom->name = 'Black Room'; + $ghostZero->link('ghost_room', array('mood'=>'grumpy'))->room = $blackRoom; + R::store($ghostZero); + $ghostZero = $ghostZero->fresh(); + $list = $ghostZero->sharedRoomList; + asrt(count($list), 3); + $ghostZero = $ghostZero->fresh(); + $list = $ghostZero->withCondition(' ghost_room.mood = ? ', array('grumpy'))->sharedRoomList; + asrt(count($list), 1); + + //can we load a batch? + $ids = R::getCol('SELECT id FROM ghost'); + $ghosts = R::batch('ghost', $ids); + asrt(count($ghosts), 4); + + //can we do an aggregation? + $ghosts = $greenRoom->aggr('ownGhostRoom', 'ghost', 'ghost'); + asrt(count($ghosts), 2); + + //can we duplicate the mansion? + asrt(R::count('mansion'), 1); + asrt(R::count('room'), 3); + asrt(R::count('ghost'), 4); + $copy = R::dup($mansion); + R::store($copy); + asrt(R::count('mansion'), 2); + asrt(R::count('room'), 5); //black room does not belong to mansion 1 + asrt(R::count('ghost'), 4); + + //can we do some counting using the list? + asrt( $copy->countOwn('room'), 2); + $rooms = $copy->withCondition(' `name` = ? ', array('Green Room'))->xownRoomList; + $room = reset($rooms); + asrt($room->countShared('ghost'), 2); + + //Finally restore old toolbox + R::configureFacadeWithToolbox( $oldToolBox ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Writer.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Writer.php new file mode 100644 index 000000000..4ba17ff72 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Mysql/Writer.php @@ -0,0 +1,667 @@ +point = 'POINT(14 6)'; + R::store($location); + $columns = R::inspect( 'location' ); + asrt( $columns['point'], 'point' ); + $location = $location->fresh(); + asrt( $location->point, 'POINT(14 6)' ); + R::nuke(); + $location = R::dispense( 'location' ); + $location->point = 'LINESTRING(0 0,1 1,2 2)'; + R::store($location); + $columns = R::inspect( 'location' ); + asrt( $columns['point'], 'linestring' ); + $location->bustcache = 2; + R::store($location); + $location = $location->fresh(); + asrt( $location->point, 'LINESTRING(0 0,1 1,2 2)' ); + R::nuke(); + $location = R::dispense( 'location' ); + $location->point = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))'; + R::store($location); + $columns = R::inspect( 'location' ); + asrt( $columns['point'], 'polygon' ); + $location->bustcache = 4; + R::store($location); + $location = $location->fresh(); + asrt( $location->point, 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))' ); + R::bindFunc( 'read', 'location.point', NULL ); + $location->bustcache = 1; + R::store($location); + $location = $location->fresh(); + asrt( ( $location->point === 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))' ), FALSE ); + $filters = AQueryWriter::getSQLFilters(); + asrt( is_array( $filters ), TRUE ); + asrt( count( $filters ), 2 ); + asrt( isset( $filters[ QueryWriter::C_SQLFILTER_READ] ), TRUE ); + asrt( isset( $filters[ QueryWriter::C_SQLFILTER_WRITE] ), TRUE ); + R::bindFunc( 'read', 'place.point', 'asText' ); + R::bindFunc( 'write', 'place.point', 'GeomFromText' ); + R::bindFunc( 'read', 'place.line', 'asText' ); + R::bindFunc( 'write', 'place.line', 'GeomFromText' ); + R::nuke(); + $place = R::dispense( 'place' ); + $place->point = 'POINT(13.2 666.6)'; + $place->line = 'LINESTRING(9.2 0,3 1.33)'; + R::store( $place ); + $columns = R::inspect( 'place' ); + asrt( $columns['point'], 'point' ); + asrt( $columns['line'], 'linestring' ); + $place = R::findOne('place'); + asrt( $place->point, 'POINT(13.2 666.6)' ); + asrt( $place->line, 'LINESTRING(9.2 0,3 1.33)' ); + R::bindFunc( 'read', 'place.point', NULL ); + R::bindFunc( 'write', 'place.point', NULL ); + R::bindFunc( 'read', 'place.line', NULL ); + R::bindFunc( 'write', 'place.line', NULL ); + } + + /** + * Test scanning and coding of values. + * + * @return void + */ + public function testScanningAndCoding() + { + $toolbox = R::getToolBox(); + $adapter = $toolbox->getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + + $a = new AssociationManager( $toolbox ); + + $adapter->exec( "DROP TABLE IF EXISTS testtable" ); + + asrt( in_array( "testtable", $adapter->getCol( "show tables" ) ), FALSE ); + + $writer->createTable( "testtable" ); + + asrt( in_array( "testtable", $adapter->getCol( "show tables" ) ), TRUE ); + + asrt( count( array_diff( $writer->getTables(), $adapter->getCol( "show tables" ) ) ), 0 ); + asrt( count( array_keys( $writer->getColumns( "testtable" ) ) ), 1 ); + + asrt( in_array( "id", array_keys( $writer->getColumns( "testtable" ) ) ), TRUE ); + asrt( in_array( "c1", array_keys( $writer->getColumns( "testtable" ) ) ), FALSE ); + + $writer->addColumn( "testtable", "c1", MySQL::C_DATATYPE_UINT32 ); + + asrt( count( array_keys( $writer->getColumns( "testtable" ) ) ), 2 ); + + asrt( in_array( "c1", array_keys( $writer->getColumns( "testtable" ) ) ), TRUE ); + + foreach ( $writer->sqltype_typeno as $key => $type ) { + if ( $type < 100 ) { + asrt( $writer->code( $key, TRUE ), $type ); + } else { + asrt( $writer->code( $key, TRUE ), MySQL::C_DATATYPE_SPECIFIED ); + } + } + + asrt( $writer->code( MySQL::C_DATATYPE_SPECIAL_DATETIME ), MySQL::C_DATATYPE_SPECIFIED ); + + asrt( $writer->code( "unknown" ), MySQL::C_DATATYPE_SPECIFIED ); + + asrt( $writer->scanType( FALSE ), MySQL::C_DATATYPE_BOOL ); + asrt( $writer->scanType( TRUE ), MySQL::C_DATATYPE_BOOL ); + asrt( $writer->scanType( INF ), MySQL::C_DATATYPE_TEXT7 ); + + asrt( $writer->scanType( NULL ), MySQL::C_DATATYPE_BOOL ); + + asrt( $writer->scanType( 2 ), MySQL::C_DATATYPE_UINT32 ); + asrt( $writer->scanType( 255 ), MySQL::C_DATATYPE_UINT32 ); //no more uint8 + asrt( $writer->scanType( 256 ), MySQL::C_DATATYPE_UINT32 ); + + asrt( $writer->scanType( -1 ), MySQL::C_DATATYPE_DOUBLE ); + asrt( $writer->scanType( 1.5 ), MySQL::C_DATATYPE_DOUBLE ); + + asrt( $writer->scanType( "abc" ), MySQL::C_DATATYPE_TEXT7 ); + + asrt( $writer->scanType( str_repeat( 'abcd', 100000 ) ), MySQL::C_DATATYPE_TEXT32 ); + + asrt( $writer->scanType( "2001-10-10", TRUE ), MySQL::C_DATATYPE_SPECIAL_DATE ); + + asrt( $writer->scanType( "2001-10-10 10:00:00", TRUE ), MySQL::C_DATATYPE_SPECIAL_DATETIME ); + + asrt( $writer->scanType( "2001-10-10" ), MySQL::C_DATATYPE_TEXT7 ); + + asrt( $writer->scanType( "2001-10-10 10:00:00" ), MySQL::C_DATATYPE_TEXT7 ); + + asrt( $writer->scanType( "1.23", TRUE ), MySQL::C_DATATYPE_SPECIAL_MONEY ); + asrt( $writer->scanType( "12.23", TRUE ), MySQL::C_DATATYPE_SPECIAL_MONEY ); + asrt( $writer->scanType( "124.23", TRUE ), MySQL::C_DATATYPE_SPECIAL_MONEY ); + + asrt( $writer->scanType( str_repeat( "lorem ipsum", 100 ) ), MySQL::C_DATATYPE_TEXT16 ); + + $writer->widenColumn( "testtable", "c1", MySQL::C_DATATYPE_UINT32 ); + + $writer->addColumn( "testtable", "special", MySQL::C_DATATYPE_SPECIAL_DATE ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols['special'], TRUE ), MySQL::C_DATATYPE_SPECIAL_DATE ); + + asrt( $writer->code( $cols['special'], FALSE ), MySQL::C_DATATYPE_SPECIFIED ); + + $writer->addColumn( "testtable", "special2", MySQL::C_DATATYPE_SPECIAL_DATETIME ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols['special2'], TRUE ), MySQL::C_DATATYPE_SPECIAL_DATETIME ); + + asrt( $writer->code( $cols['special'], FALSE ), MySQL::C_DATATYPE_SPECIFIED ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols["c1"] ), MySQL::C_DATATYPE_UINT32 ); + + $writer->widenColumn( "testtable", "c1", MySQL::C_DATATYPE_DOUBLE ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols["c1"] ), MySQL::C_DATATYPE_DOUBLE ); + + $writer->widenColumn( "testtable", "c1", MySQL::C_DATATYPE_TEXT7 ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols["c1"] ), MySQL::C_DATATYPE_TEXT7 ); + + $writer->widenColumn( "testtable", "c1", MySQL::C_DATATYPE_TEXT8 ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols["c1"] ), MySQL::C_DATATYPE_TEXT8 ); + + $id = $writer->updateRecord( "testtable", array( array( "property" => "c1", "value" => "lorem ipsum" ) ) ); + + $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) ); + + asrt( $row[0]["c1"], "lorem ipsum" ); + + $writer->updateRecord( "testtable", array( array( "property" => "c1", "value" => "ipsum lorem" ) ), $id ); + + $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) ); + + asrt( $row[0]["c1"], "ipsum lorem" ); + + $writer->deleteRecord( "testtable", array( "id" => array( $id ) ) ); + + $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) ); + + asrt( empty( $row ), TRUE ); + + $writer->addColumn( "testtable", "c2", MySQL::C_DATATYPE_UINT32 ); + } + + /** + * (FALSE should be stored as 0 not as '') + * + * @return voids + */ + public function testZeroIssue() + { + testpack( "Zero issue" ); + + $toolbox = R::getToolBox(); + $redbean = $toolbox->getRedBean(); + $adapter = $toolbox->getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $pdo = $adapter->getDatabase(); + + $pdo->Execute( "DROP TABLE IF EXISTS `zero`" ); + + $bean = $redbean->dispense( "zero" ); + + $bean->zero = FALSE; + $bean->title = "bla"; + + $redbean->store( $bean ); + + asrt( count( $redbean->find( "zero", array(), " zero = 0 " ) ), 1 ); + + R::store( R::dispense( 'hack' ) ); + + testpack( "Test RedBean Security - bean interface " ); + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + $bean = $redbean->load( "page", "13; drop table hack" ); + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + try { + $bean = $redbean->load( "page where 1; drop table hack", 1 ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + $bean = $redbean->dispense( "page" ); + + $evil = "; drop table hack"; + + $bean->id = $evil; + + try { + $redbean->store( $bean ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + unset( $bean->id ); + + $bean->name = "\"" . $evil; + + try { + $redbean->store( $bean ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + $bean->name = "'" . $evil; + + try { + $redbean->store( $bean ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + $bean->$evil = 1; + + try { + $redbean->store( $bean ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + unset( $bean->$evil ); + + $bean->id = 1; + $bean->name = "\"" . $evil; + + try { + $redbean->store( $bean ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + $bean->name = "'" . $evil; + + try { + $redbean->store( $bean ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + $bean->$evil = 1; + + try { + $redbean->store( $bean ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + try { + $redbean->trash( $bean ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + try { + $redbean->find( "::", array(), "" ); + } catch (\Exception $e ) { + pass(); + } + + $adapter->exec( "drop table if exists sometable" ); + + testpack( "Test RedBean Security - query writer" ); + + try { + $writer->createTable( "sometable` ( `id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT , PRIMARY KEY ( `id` ) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ; drop table hack; --" ); + } catch (\Exception $e ) { + } + + asrt( in_array( "hack", $adapter->getCol( "show tables" ) ), TRUE ); + + testpack( "Test ANSI92 issue in clearrelations" ); + + $pdo->Execute( "DROP TABLE IF EXISTS book_group" ); + $pdo->Execute( "DROP TABLE IF EXISTS author_book" ); + $pdo->Execute( "DROP TABLE IF EXISTS book" ); + $pdo->Execute( "DROP TABLE IF EXISTS author" ); + + $redbean = $toolbox->getRedBean(); + + $a = new AssociationManager( $toolbox ); + + $book = $redbean->dispense( "book" ); + $author1 = $redbean->dispense( "author" ); + $author2 = $redbean->dispense( "author" ); + + $book->title = "My First Post"; + + $author1->name = "Derek"; + $author2->name = "Whoever"; + + set1toNAssoc( $a, $book, $author1 ); + set1toNAssoc( $a, $book, $author2 ); + + pass(); + + $pdo->Execute( "DROP TABLE IF EXISTS book_group" ); + $pdo->Execute( "DROP TABLE IF EXISTS book_author" ); + $pdo->Execute( "DROP TABLE IF EXISTS author_book" ); + $pdo->Execute( "DROP TABLE IF EXISTS book" ); + $pdo->Execute( "DROP TABLE IF EXISTS author" ); + + $redbean = $toolbox->getRedBean(); + + $a = new AssociationManager( $toolbox ); + + $book = $redbean->dispense( "book" ); + $author1 = $redbean->dispense( "author" ); + $author2 = $redbean->dispense( "author" ); + + $book->title = "My First Post"; + + $author1->name = "Derek"; + $author2->name = "Whoever"; + + $a->associate( $book, $author1 ); + $a->associate( $book, $author2 ); + + pass(); + + testpack( "Test Association Issue Group keyword (Issues 9 and 10)" ); + + $pdo->Execute( "DROP TABLE IF EXISTS `book_group`" ); + $pdo->Execute( "DROP TABLE IF EXISTS `group`" ); + + $group = $redbean->dispense( "group" ); + + $group->name = "mygroup"; + + $redbean->store( $group ); + + try { + $a->associate( $group, $book ); + + pass(); + } catch ( SQL $e ) { + fail(); + } + + // Test issue SQL error 23000 + try { + $a->associate( $group, $book ); + + pass(); + } catch ( SQL $e ) { + fail(); + } + + asrt( (int) $adapter->getCell( "select count(*) from book_group" ), 1 ); //just 1 rec! + + $pdo->Execute( "DROP TABLE IF EXISTS book_group" ); + $pdo->Execute( "DROP TABLE IF EXISTS author_book" ); + $pdo->Execute( "DROP TABLE IF EXISTS book" ); + $pdo->Execute( "DROP TABLE IF EXISTS author" ); + + $redbean = $toolbox->getRedBean(); + + $a = new AssociationManager( $toolbox ); + + $book = $redbean->dispense( "book" ); + $author1 = $redbean->dispense( "author" ); + $author2 = $redbean->dispense( "author" ); + + $book->title = "My First Post"; + + $author1->name = "Derek"; + $author2->name = "Whoever"; + + $a->unassociate( $book, $author1 ); + $a->unassociate( $book, $author2 ); + + pass(); + + $redbean->trash( $redbean->dispense( "bla" ) ); + + pass(); + + $bean = $redbean->dispense( "bla" ); + + $bean->name = 1; + $bean->id = 2; + + $redbean->trash( $bean ); + + pass(); + } + + /** + * Test special data types. + * + * @return void + */ + public function testTypes() + { + testpack( 'Special data types' ); + + $bean = R::dispense( 'bean' ); + + $bean->date = 'someday'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'varchar(191)' ); + + $bean = R::dispense( 'bean' ); + + $bean->date = '2011-10-10'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'varchar(191)' ); + } + + /** + * Test date types. + * + * @return void + */ + public function testTypesDates() + { + $bean = R::dispense( 'bean' ); + + $bean->date = '2011-10-10'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'date' ); + } + + /** + * Test money types. + * + * @return void + */ + public function testTypesMon() + { + $bean = R::dispense( 'bean' ); + + $bean->amount = '22.99'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['amount'], 'decimal(10,2)' ); + + R::nuke(); + + $bean = R::dispense( 'bean' ); + + $bean->amount = '-22.99'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['amount'], 'decimal(10,2)' ); + } + + + /** + * Date-time + * + * @return void + */ + public function testTypesDateTimes() + { + $bean = R::dispense( 'bean' ); + + $bean->date = '2011-10-10 10:00:00'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'datetime' ); + + $bean = R::dispense( 'bean' ); + + try { + $bean = R::dispense( 'bean' ); + + $bean->title = 123; + + $bean->setMeta( 'cast.title', 'invalid' ); + + R::store( $bean ); + + fail(); + } catch ( RedException $e ) { + pass(); + } catch (\Exception $e ) { + fail(); + } + + $bean = R::dispense( 'bean' ); + + $bean->title = 123; + + $bean->setMeta( 'cast.title', 'text' ); + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['title'], 'text' ); + + R::nuke(); + + $bean = R::dispense( 'bean' ); + + $bean->title = 123; + + $bean->setMeta( 'cast.title', 'string' ); + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['title'], 'varchar(191)' ); + } + + /** + * Stored and reloads spatial data to see if the + * value is preserved correctly. + * + * @return void + */ + protected function setGetSpatial( $data ) + { + R::nuke(); + + $place = R::dispense( 'place' ); + + $place->location = $data; + + R::store( $place ); + + asrt( R::getCell( 'SELECT AsText(location) FROM place LIMIT 1' ), $data ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres.php new file mode 100644 index 000000000..950f22d4d --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres.php @@ -0,0 +1,34 @@ +id, $book1ID ); + asrt( $book1->title, 'book 1' ); + + $book2 = R::load( 'book', $book2ID ); + + asrt( $book2->id, $book2ID ); + asrt( $book2->title, 'book 2' ); + + asrt( count( $book1->ownPage ), 2 ); + asrt( count( $book1->fresh()->with( 'LIMIT 1' )->ownPage ), 1 ); + asrt( count( $book1->fresh()->withCondition( ' title = ? ', array('page 2 of book 1'))->ownPage ), 1 ); + + asrt( count($book2->ownPage), 1 ); + asrt( $book2->fresh()->countOwn( 'page' ), 1 ); + + $page1 = R::load( 'page', $page1ID ); + asrt( count( $page1->sharedPage ), 0 ); + asrt( $page1->fetchAs( 'book' )->magazine->id, $book2ID ); + + $page2 = R::load( 'page', $page2ID ); + asrt( count($page2->sharedPage), 1 ); + asrt( $page2->fresh()->countShared( 'page' ), 1 ); + + $page3 = R::findOne( 'page', ' title = ? ', array( 'page 1 of book 2' ) ); + asrt( $page3->id, $page3ID ); + asrt( $page3->book->id, $book2ID ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Foreignkeys.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Foreignkeys.php new file mode 100644 index 000000000..64a1c22d0 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Foreignkeys.php @@ -0,0 +1,292 @@ +addFK( 'a', 'b', 'c', 'd' ); //must fail + pass(); //survive without exception + asrt( $a, FALSE ); //must return false + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $cover = R::dispense( 'cover' ); + list( $g1, $g2 ) = R::dispense( 'genre', 2 ); + $g1->name = '1'; + $g2->name = '2'; + $book->ownPage = array( $page ); + $book->cover = $cover; + $book->sharedGenre = array( $g1, $g2 ); + R::store( $book ); + $sql = "SELECT + tc.constraint_name, tc.table_name, kcu.column_name, + ccu.table_name AS foreign_table_name, + ccu.column_name AS foreign_column_name + FROM + information_schema.table_constraints AS tc + JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name + JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name + WHERE constraint_type = 'FOREIGN KEY' AND (tc.table_name='book' OR tc.table_name='book_genre' OR tc.table_name='page');"; + $fks = R::getAll( $sql ); + $json = '[ + { + "constraint_name": "book_cover_id_fkey", + "table_name": "book", + "column_name": "cover_id", + "foreign_table_name": "cover", + "foreign_column_name": "id" + }, + { + "constraint_name": "page_book_id_fkey", + "table_name": "page", + "column_name": "book_id", + "foreign_table_name": "book", + "foreign_column_name": "id" + }, + { + "constraint_name": "book_genre_genre_id_fkey", + "table_name": "book_genre", + "column_name": "genre_id", + "foreign_table_name": "genre", + "foreign_column_name": "id" + }, + { + "constraint_name": "book_genre_book_id_fkey", + "table_name": "book_genre", + "column_name": "book_id", + "foreign_table_name": "book", + "foreign_column_name": "id" + } + ]'; + $j = json_encode( $fks ); + $j1 = json_decode( $j, TRUE ); + $j2 = json_decode( $json, TRUE ); + foreach ( $j1 as $jrow ) { + $s = json_encode( $jrow ); + $found = 0; + foreach ( $j2 as $k => $j2row ) { + if ( json_encode( $j2row ) === $s ) { + pass(); + unset( $j2[$k] ); + $found = 1; + } + } + if ( !$found ) fail(); + } + } + + /** + * Test constraint function directly in Writer. + * + * @return void + */ + public function testConstraint() + { + R::nuke(); + $database = R::getCell('SELECT current_database()'); + $sql = 'CREATE TABLE book (id SERIAL PRIMARY KEY)'; + R::exec( $sql ); + $sql = 'CREATE TABLE page (id SERIAL PRIMARY KEY)'; + R::exec( $sql ); + $sql = 'CREATE TABLE book_page ( + id SERIAL PRIMARY KEY, + book_id INTEGER, + page_id INTEGER + )'; + R::exec( $sql ); + $writer = R::getWriter(); + $sql = " + SELECT + COUNT(*) + FROM information_schema.key_column_usage AS k + LEFT JOIN information_schema.table_constraints AS c ON c.constraint_name = k.constraint_name + WHERE k.table_catalog = '$database' + AND k.table_schema = 'public' + AND k.table_name = 'book_page' + AND c.constraint_type = 'FOREIGN KEY'"; + $numFKS = R::getCell( $sql ); + asrt( (int) $numFKS, 0 ); + $writer->addFK( 'book_page', 'book', 'book_id', 'id', TRUE ); + $writer->addFK( 'book_page', 'page', 'page_id', 'id', TRUE ); + $numFKS = R::getCell( $sql ); + asrt( (int) $numFKS, 2 ); + $writer->addFK( 'book_page', 'book', 'book_id', 'id', TRUE ); + $writer->addFK( 'book_page', 'page', 'page_id', 'id', TRUE ); + $numFKS = R::getCell( $sql ); + asrt( (int) $numFKS, 2 ); + } + + /** + * Test adding foreign keys. + * + * @return void + */ + public function testAddingForeignKey() + { + R::nuke(); + $database = R::getCell('SELECT current_database()'); + $sql = 'CREATE TABLE book ( + id SERIAL PRIMARY KEY + )'; + R::exec( $sql ); + $sql = 'CREATE TABLE page ( + id SERIAL PRIMARY KEY, + book_id INTEGER + )'; + R::exec( $sql ); + $writer = R::getWriter(); + $sql = " + SELECT + COUNT(*) + FROM information_schema.key_column_usage AS k + LEFT JOIN information_schema.table_constraints AS c ON c.constraint_name = k.constraint_name + WHERE k.table_catalog = '$database' + AND k.table_schema = 'public' + AND k.table_name = 'page' + AND c.constraint_type = 'FOREIGN KEY'"; + $numFKS = R::getCell( $sql ); + asrt( (int) $numFKS, 0 ); + $writer->addFK('page', 'page', 'book_id', 'id', TRUE); + $sql = " + SELECT + COUNT(*) + FROM information_schema.key_column_usage AS k + LEFT JOIN information_schema.table_constraints AS c ON c.constraint_name = k.constraint_name + WHERE k.table_catalog = '$database' + AND k.table_schema = 'public' + AND k.table_name = 'page' + AND c.constraint_type = 'FOREIGN KEY'"; + $numFKS = R::getCell( $sql ); + asrt( (int) $numFKS, 1 ); + //dont add twice + $writer->addFK('page', 'page', 'book_id', 'id', TRUE); + $sql = " + SELECT + COUNT(*) + FROM information_schema.key_column_usage AS k + LEFT JOIN information_schema.table_constraints AS c ON c.constraint_name = k.constraint_name + WHERE k.table_catalog = '$database' + AND k.table_schema = 'public' + AND k.table_name = 'page' + AND c.constraint_type = 'FOREIGN KEY'"; + $numFKS = R::getCell( $sql ); + asrt( (int) $numFKS, 1 ); + //even if it is different + $writer->addFK('page', 'page', 'book_id', 'id', FALSE); + $sql = " + SELECT + COUNT(*) + FROM information_schema.key_column_usage AS k + LEFT JOIN information_schema.table_constraints AS c ON c.constraint_name = k.constraint_name + WHERE k.table_catalog = '$database' + AND k.table_schema = 'public' + AND k.table_name = 'page' + AND c.constraint_type = 'FOREIGN KEY'"; + $numFKS = R::getCell( $sql ); + asrt( (int) $numFKS, 1 ); + R::nuke(); + $sql = 'CREATE TABLE book ( + id SERIAL PRIMARY KEY + )'; + R::exec( $sql ); + $sql = 'CREATE TABLE page ( + id SERIAL PRIMARY KEY, + book_id INTEGER + )'; + R::exec( $sql ); + $writer = R::getWriter(); + $sql = " + SELECT + COUNT(*) + FROM information_schema.key_column_usage AS k + LEFT JOIN information_schema.table_constraints AS c ON c.constraint_name = k.constraint_name + WHERE k.table_catalog = '$database' + AND k.table_schema = 'public' + AND k.table_name = 'page' + AND c.constraint_type = 'FOREIGN KEY'"; + $numFKS = R::getCell( $sql ); + asrt( (int) $numFKS, 0 ); + $writer->addFK('page', 'page', 'book_id', 'id', FALSE); + $sql = " + SELECT + COUNT(*) + FROM information_schema.key_column_usage AS k + LEFT JOIN information_schema.table_constraints AS c ON c.constraint_name = k.constraint_name + WHERE k.table_catalog = '$database' + AND k.table_schema = 'public' + AND k.table_name = 'page' + AND c.constraint_type = 'FOREIGN KEY'"; + $numFKS = R::getCell( $sql ); + asrt( (int) $numFKS, 1 ); + } + + /** + * Test whether we can manually create indexes. + * + * @return void + */ + public function testAddingIndex() + { + R::nuke(); + $sql = 'CREATE TABLE song ( + id SERIAL PRIMARY KEY, + album_id INTEGER, + category VARCHAR(255) + )'; + R::exec( $sql ); + $indexes = R::getAll( " SELECT * FROM pg_indexes WHERE schemaname = 'public' AND tablename = 'song' "); + asrt( count( $indexes ), 1 ); + $writer = R::getWriter(); + $writer->addIndex( 'song', 'index1', 'album_id' ); + $indexes = R::getAll( " SELECT * FROM pg_indexes WHERE schemaname = 'public' AND tablename = 'song' "); + asrt( count( $indexes ), 2 ); + //Cant add the same index twice + $writer->addIndex( 'song', 'index1', 'album_id' ); + $indexes = R::getAll( " SELECT * FROM pg_indexes WHERE schemaname = 'public' AND tablename = 'song' "); + asrt( count( $indexes ), 2 ); + $writer->addIndex( 'song', 'index2', 'category' ); + $indexes = R::getAll( " SELECT * FROM pg_indexes WHERE schemaname = 'public' AND tablename = 'song' "); + asrt( count( $indexes ), 3 ); + //Dont fail, just dont + try { + $writer->addIndex( 'song', 'index3', 'nonexistant' ); + pass(); + } catch( \Exception $e ) { + fail(); + } + $indexes = R::getAll( " SELECT * FROM pg_indexes WHERE schemaname = 'public' AND tablename = 'song' "); + asrt( count( $indexes ), 3 ); + try { + $writer->addIndex( 'nonexistant', 'index4', 'nonexistant' ); + pass(); + } catch( \Exception $e ) { + fail(); + } + $indexes = R::getAll( " SELECT * FROM pg_indexes WHERE schemaname = 'public' AND tablename = 'song' "); + asrt( count( $indexes ), 3 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Parambind.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Parambind.php new file mode 100644 index 000000000..fdfa51757 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Parambind.php @@ -0,0 +1,51 @@ +name = "abc"; + $page->number = 2; + R::store( $page ); + R::exec( "insert into page (name) values(:name) ", array( ":name" => "my name" ) ); + R::exec( "insert into page (number) values(:one) ", array( ":one" => 1 ) ); + R::exec( "insert into page (number) values(:one) ", array( ":one" => "1" ) ); + R::exec( "insert into page (number) values(:one) ", array( ":one" => "1234" ) ); + R::exec( "insert into page (number) values(:one) ", array( ":one" => "-21" ) ); + pass(); + testpack( 'Test whether we can properly bind and receive NULL values' ); + $adapter = R::getDatabaseAdapter(); + asrt( $adapter->getCell( 'SELECT TEXT( :nil ) ', array( ':nil' => 'NULL' ) ), 'NULL' ); + asrt( $adapter->getCell( 'SELECT TEXT( :nil ) ', array( ':nil' => NULL ) ), NULL ); + asrt( $adapter->getCell( 'SELECT TEXT( ? ) ', array( 'NULL' ) ), 'NULL' ); + asrt( $adapter->getCell( 'SELECT TEXT( ? ) ', array( NULL ) ), NULL ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Setget.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Setget.php new file mode 100644 index 000000000..aa51fceb0 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Setget.php @@ -0,0 +1,134 @@ +id, $book1ID ); + asrt( $book1->title, 'book 1' ); + + $book2 = R::load( 'book', $book2ID ); + + asrt( $book2->id, $book2ID ); + asrt( $book2->title, 'book 2' ); + + asrt( count( $book1->ownPage ), 2 ); + asrt( count( $book1->fresh()->with( 'LIMIT 1' )->ownPage ), 1 ); + asrt( count( $book1->fresh()->withCondition( ' title = ? ', array('page 2 of book 1'))->ownPage ), 1 ); + + asrt( count($book2->ownPage), 1 ); + asrt( $book2->fresh()->countOwn( 'page' ), 1 ); + + $page1 = R::load( 'page', $page1ID ); + asrt( count( $page1->sharedPage ), 0 ); + asrt( $page1->fetchAs( 'book' )->magazine->id, $book2ID ); + + $page2 = R::load( 'page', $page2ID ); + asrt( count($page2->sharedPage), 1 ); + asrt( $page2->fresh()->countShared( 'page' ), 1 ); + + $page3 = R::findOne( 'page', ' title = ? ', array( 'page 1 of book 2' ) ); + asrt( $page3->id, $page3ID ); + asrt( $page3->book->id, $book2ID ); + } + + /** + * Test Full fluid UUID support. + * + */ + public function testFullSupport() + { + + //Rewire objects to support UUIDs. + $oldToolBox = R::getToolBox(); + $oldAdapter = $oldToolBox->getDatabaseAdapter(); + $uuidWriter = new \UUIDWriterPostgres( $oldAdapter ); + $newRedBean = new OODB( $uuidWriter ); + $newToolBox = new ToolBox( $newRedBean, $oldAdapter, $uuidWriter ); + R::configureFacadeWithToolbox( $newToolBox ); + + list( $mansion, $rooms, $ghosts, $key ) = R::dispenseAll( 'mansion,room*3,ghost*4,key' ); + $mansion->name = 'Haunted Mansion'; + $mansion->xownRoomList = $rooms; + $rooms[0]->name = 'Green Room'; + $rooms[1]->name = 'Red Room'; + $rooms[2]->name = 'Blue Room'; + $ghosts[0]->name = 'zero'; + $ghosts[1]->name = 'one'; + $ghosts[2]->name = 'two'; + $ghosts[3]->name = 'three'; + $rooms[0]->noLoad()->sharedGhostList = array( $ghosts[0], $ghosts[1] ); + $rooms[1]->noLoad()->sharedGhostList = array( $ghosts[0], $ghosts[2] ); + $rooms[2]->noLoad()->sharedGhostList = array( $ghosts[1], $ghosts[3], $ghosts[2] ); + $rooms[2]->xownKey = array( $key ); + //Can we store a bean hierachy with UUIDs? + + R::debug(1); + $id = R::store( $mansion ); + //exit; + + asrt( is_string( $id ), TRUE ); + asrt( strlen( $id ), 36 ); + $haunted = R::load( 'mansion', $id ); + asrt( $haunted->name, 'Haunted Mansion' ); + asrt( is_string( $haunted->id ), TRUE ); + asrt( strlen( $haunted->id ), 36 ); + asrt( is_array( $haunted->xownRoomList ), TRUE ); + asrt( count( $haunted->ownRoom ), 3 ); + $rooms = $haunted->xownRoomList; + + //Do some counting... + $greenRoom = NULL; + foreach( $rooms as $room ) { + if ( $room->name === 'Green Room' ) { + $greenRoom = $room; + break; + } + } + asrt( !is_null( $greenRoom ), TRUE ); + asrt( is_array( $greenRoom->with(' ORDER BY id ')->sharedGhostList ), TRUE ); + asrt( count( $greenRoom->sharedGhostList ), 2 ); + $names = array(); + foreach( $greenRoom->sharedGhost as $ghost ) $names[] = $ghost->name; + sort($names); + $names = implode(',', $names); + asrt($names, 'one,zero'); + $rooms = $haunted->xownRoomList; + $blueRoom = NULL; + foreach( $rooms as $room ) { + if ( $room->name === 'Blue Room' ) { + $blueRoom = $room; + break; + } + } + asrt( !is_null( $blueRoom ), TRUE ); + asrt( is_array( $blueRoom->sharedGhostList ), TRUE ); + asrt( count( $blueRoom->sharedGhostList ), 3 ); + $names = array(); + foreach( $blueRoom->sharedGhost as $ghost ) $names[] = $ghost->name; + sort($names); + $names = implode(',', $names); + asrt($names, 'one,three,two'); + $rooms = $haunted->xownRoomList; + $redRoom = NULL; + foreach( $rooms as $room ) { + if ( $room->name === 'Red Room' ) { + $redRoom = $room; break; + } + } + $names = array(); + foreach( $redRoom->sharedGhost as $ghost ) $names[] = $ghost->name; + sort($names); + $names = implode(',', $names); + asrt($names, 'two,zero'); + asrt( !is_null( $redRoom ), TRUE ); + asrt( is_array( $redRoom->sharedGhostList ), TRUE ); + asrt( count( $redRoom->sharedGhostList ), 2 ); + + //Can we repaint a room? + $redRoom->name = 'Yellow Room'; + $id = R::store($redRoom); + $yellowRoom = R::load( 'room', $id ); + asrt( $yellowRoom->name, 'Yellow Room'); + asrt( !is_null( $yellowRoom ), TRUE ); + asrt( is_array( $yellowRoom->sharedGhostList ), TRUE ); + asrt( count( $yellowRoom->sharedGhostList ), 2 ); + + //Can we throw one ghost out? + array_pop( $yellowRoom->sharedGhost ); + R::store( $yellowRoom ); + $yellowRoom = $yellowRoom->fresh(); + asrt( $yellowRoom->name, 'Yellow Room'); + asrt( !is_null( $yellowRoom ), TRUE ); + asrt( is_array( $yellowRoom->sharedGhostList ), TRUE ); + asrt( count( $yellowRoom->sharedGhostList ), 1 ); + + //can we remove one of the rooms? + asrt( R::count('key'), 1); + $list = $mansion->withCondition(' "name" = ? ', array('Blue Room'))->xownRoomList; + $room = reset($list); + unset($mansion->xownRoomList[$room->id]); + R::store($mansion); + asrt(R::count('room'), 2); + + //and what about its dependent beans? + asrt(R::count('key'), 0); + asrt(R::count('ghost_room'), 3); + + //and can we find ghosts? + $ghosts = R::find('ghost'); + asrt(count($ghosts), 4); + $ghosts = R::findAll('ghost', 'ORDER BY id'); + asrt(count($ghosts), 4); + $ghosts = R::findAll('ghost', 'ORDER BY id LIMIT 2'); + asrt(count($ghosts), 2); + $ghostZero = R::findOne('ghost', ' "name" = ? ', array( 'zero' ) ); + asrt( ($ghostZero instanceof OODBBean), TRUE ); + + //can we create link properties on existing tables? + $blackRoom = R::dispense( 'room' ); + $blackRoom->name = 'Black Room'; + $ghostZero->link('ghost_room', array('mood'=>'grumpy'))->room = $blackRoom; + R::store($ghostZero); + $ghostZero = $ghostZero->fresh(); + $list = $ghostZero->sharedRoomList; + asrt(count($list), 3); + $ghostZero = $ghostZero->fresh(); + $list = $ghostZero->withCondition(' ghost_room.mood = ? ', array('grumpy'))->sharedRoomList; + asrt(count($list), 1); + + //can we load a batch? + $ids = R::getCol('SELECT id FROM ghost'); + $ghosts = R::batch('ghost', $ids); + asrt(count($ghosts), 4); + + //can we do an aggregation? + $ghosts = $greenRoom->aggr('ownGhostRoom', 'ghost', 'ghost'); + asrt(count($ghosts), 2); + + //can we duplicate the mansion? + asrt(R::count('mansion'), 1); + asrt(R::count('room'), 3); + asrt(R::count('ghost'), 4); + $copy = R::dup($mansion); + R::store($copy); + asrt(R::count('mansion'), 2); + asrt(R::count('room'), 5); //black room does not belong to mansion 1 + asrt(R::count('ghost'), 4); + + //can we do some counting using the list? + asrt( $copy->countOwn('room'), 2); + $rooms = $copy->withCondition(' "name" = ? ', array('Green Room'))->xownRoomList; + $room = reset($rooms); + asrt($room->countShared('ghost'), 2); + + //Finally restore old toolbox + R::configureFacadeWithToolbox( $oldToolBox ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Writer.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Writer.php new file mode 100644 index 000000000..388772661 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Postgres/Writer.php @@ -0,0 +1,704 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + + $a = new AssociationManager( $toolbox ); + + $adapter->exec( "DROP TABLE IF EXISTS testtable" ); + + asrt( in_array( "testtable", $writer->getTables() ), FALSE ); + + $writer->createTable( "testtable" ); + + asrt( in_array( "testtable", $writer->getTables() ), TRUE ); + + asrt( count( array_keys( $writer->getColumns( "testtable" ) ) ), 1 ); + + asrt( in_array( "id", array_keys( $writer->getColumns( "testtable" ) ) ), TRUE ); + asrt( in_array( "c1", array_keys( $writer->getColumns( "testtable" ) ) ), FALSE ); + + $writer->addColumn( "testtable", "c1", 1 ); + + asrt( count( array_keys( $writer->getColumns( "testtable" ) ) ), 2 ); + + asrt( in_array( "c1", array_keys( $writer->getColumns( "testtable" ) ) ), TRUE ); + + foreach ( $writer->sqltype_typeno as $key => $type ) { + if ( $type < 100 ) { + asrt( $writer->code( $key, TRUE ), $type ); + } else { + asrt( $writer->code( $key ), PostgreSQL::C_DATATYPE_SPECIFIED ); + } + } + + asrt( $writer->code( PostgreSQL::C_DATATYPE_SPECIAL_DATETIME ), PostgreSQL::C_DATATYPE_SPECIFIED ); + + asrt( $writer->code( "unknown" ), PostgreSQL::C_DATATYPE_SPECIFIED ); + + asrt( $writer->scanType( FALSE ), PostgreSQL::C_DATATYPE_INTEGER ); + asrt( $writer->scanType( TRUE ), PostgreSQL::C_DATATYPE_INTEGER ); + + asrt( $writer->scanType( NULL ), PostgreSQL::C_DATATYPE_INTEGER ); + + asrt( $writer->scanType( 2 ), PostgreSQL::C_DATATYPE_INTEGER ); + + asrt( $writer->scanType( 255 ), PostgreSQL::C_DATATYPE_INTEGER ); + asrt( $writer->scanType( 256 ), PostgreSQL::C_DATATYPE_INTEGER ); + + asrt( $writer->scanType( -1 ), PostgreSQL::C_DATATYPE_INTEGER ); + + asrt( $writer->scanType( 1.5 ), PostgreSQL::C_DATATYPE_DOUBLE ); + + asrt( $writer->scanType( INF ), PostgreSQL::C_DATATYPE_TEXT ); + + asrt( $writer->scanType( "abc" ), PostgreSQL::C_DATATYPE_TEXT ); + + asrt( $writer->scanType( "2001-10-10", TRUE ), PostgreSQL::C_DATATYPE_SPECIAL_DATE ); + + asrt( $writer->scanType( "2001-10-10 10:00:00", TRUE ), PostgreSQL::C_DATATYPE_SPECIAL_DATETIME ); + + asrt( $writer->scanType( "2001-10-10 10:00:00" ), PostgreSQL::C_DATATYPE_TEXT ); + + asrt( $writer->scanType( "2001-10-10" ), PostgreSQL::C_DATATYPE_TEXT ); + + asrt( $writer->scanType( str_repeat( "lorem ipsum", 100 ) ), PostgreSQL::C_DATATYPE_TEXT ); + + $writer->widenColumn( "testtable", "c1", PostgreSQL::C_DATATYPE_TEXT ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols["c1"] ), PostgreSQL::C_DATATYPE_TEXT ); + + $writer->addColumn( "testtable", "special", PostgreSQL::C_DATATYPE_SPECIAL_DATE ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols['special'], TRUE ), PostgreSQL::C_DATATYPE_SPECIAL_DATE ); + + asrt( $writer->code( $cols['special'], FALSE ), PostgreSQL::C_DATATYPE_SPECIFIED ); + + $writer->addColumn( "testtable", "special2", PostgreSQL::C_DATATYPE_SPECIAL_DATETIME ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols['special2'], TRUE ), PostgreSQL::C_DATATYPE_SPECIAL_DATETIME ); + + asrt( $writer->code( $cols['special'], FALSE ), PostgreSQL::C_DATATYPE_SPECIFIED ); + + //$id = $writer->insertRecord("testtable", array("c1"), array(array("lorem ipsum"))); + + $id = $writer->updateRecord( "testtable", array( array( "property" => "c1", "value" => "lorem ipsum" ) ) ); + + $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) ); + + asrt( $row[0]["c1"], "lorem ipsum" ); + + $writer->updateRecord( "testtable", array( array( "property" => "c1", "value" => "ipsum lorem" ) ), $id ); + + $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) ); + + asrt( $row[0]["c1"], "ipsum lorem" ); + + $writer->deleteRecord( "testtable", array( "id" => array( $id ) ) ); + + $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) ); + + asrt( empty( $row ), TRUE ); + } + + /** + * (FALSE should be stored as 0 not as '') + * + * @return void + */ + public function testZeroIssue() + { + testpack( "Zero issue" ); + + $toolbox = R::getToolBox(); + $redbean = $toolbox->getRedBean(); + + $bean = $redbean->dispense( "zero" ); + + $bean->zero = FALSE; + $bean->title = "bla"; + + $redbean->store( $bean ); + + asrt( count( $redbean->find( "zero", array(), " zero = 0 " ) ), 1 ); + + testpack( "Test ANSI92 issue in clearrelations" ); + + $a = new AssociationManager( $toolbox ); + + $book = $redbean->dispense( "book" ); + $author1 = $redbean->dispense( "author" ); + $author2 = $redbean->dispense( "author" ); + + $book->title = "My First Post"; + + $author1->name = "Derek"; + $author2->name = "Whoever"; + + set1toNAssoc( $a, $book, $author1 ); + set1toNAssoc( $a, $book, $author2 ); + + pass(); + } + + /** + * Various. + * Tests whether writer correctly handles keyword 'group' and SQL state 23000 issue. + * These tests remain here to make sure issues 9 and 10 never happen again. + * However this bug will probably never re-appear due to changed architecture. + * + * @return void + */ + public function testIssue9and10() + { + $toolbox = R::getToolBox(); + $redbean = $toolbox->getRedBean(); + $adapter = $toolbox->getDatabaseAdapter(); + + $a = new AssociationManager( $toolbox ); + + $book = $redbean->dispense( "book" ); + + $author1 = $redbean->dispense( "author" ); + $author2 = $redbean->dispense( "author" ); + + $book->title = "My First Post"; + + $author1->name = "Derek"; + $author2->name = "Whoever"; + + $a->associate( $book, $author1 ); + $a->associate( $book, $author2 ); + + pass(); + + testpack( "Test Association Issue Group keyword (Issues 9 and 10)" ); + + R::nuke(); + + $group = $redbean->dispense( "group" ); + + $group->name = "mygroup"; + + $redbean->store( $group ); + + try { + $a->associate( $group, $book ); + + pass(); + } catch ( SQL $e ) { + fail(); + } + + // Test issue SQL error 23000 + try { + $a->associate( $group, $book ); + + pass(); + } catch ( SQL $e ) { + fail(); + } + + asrt( (int) $adapter->getCell( "select count(*) from book_group" ), 1 ); //just 1 rec! + } + + /** + * Test various. + * Test various somewhat uncommon trash/unassociate scenarios. + * (i.e. unassociate unrelated beans, trash non-persistant beans etc). + * Should be handled gracefully - no output checking. + * + * @return void + */ + public function testVaria() + { + $toolbox = R::getToolBox(); + $redbean = $toolbox->getRedBean(); + + $a = new AssociationManager( $toolbox ); + + $book = $redbean->dispense( "book" ); + $author1 = $redbean->dispense( "author" ); + $author2 = $redbean->dispense( "author" ); + + $book->title = "My First Post"; + + $author1->name = "Derek"; + $author2->name = "Whoever"; + + $a->unassociate( $book, $author1 ); + $a->unassociate( $book, $author2 ); + + pass(); + + $redbean->trash( $redbean->dispense( "bla" ) ); + + pass(); + + $bean = $redbean->dispense( "bla" ); + + $bean->name = 1; + $bean->id = 2; + + $redbean->trash( $bean ); + + pass(); + } + + /** + * Test special types. + * + * @return void + */ + public function testTypes() + { + testpack( 'Special data types' ); + + $bean = R::dispense( 'bean' ); + + $bean->date = 'someday'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'text' ); + + $bean = R::dispense( 'bean' ); + + $bean->date = '2011-10-10'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'text' ); + } + + /** + * Test dates. + * + * @return void + */ + public function testTypesDates() + { + $bean = R::dispense( 'bean' ); + + $bean->date = '2011-10-10'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'date' ); + } + + /** + * Datetime. + * + * @return void + */ + public function testTypesDateTimes() + { + $bean = R::dispense( 'bean' ); + + $bean->date = '2011-10-10 10:00:00'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'timestamp without time zone' ); + } + + /** + * Test spatial data types. + * + * @return void + */ + public function testTypesPoints() + { + $bean = R::dispense( 'bean' ); + + $bean->point = '(92,12)'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['point'], 'point' ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->point, '(92,12)' ); + + $bean->note = 'taint'; + + R::store( $bean ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->point, '(92,12)' ); + } + + /** + * Test points. + * + * @return void + */ + public function testTypesDecPoints() + { + $bean = R::dispense( 'bean' ); + + $bean->point = '(9.2,1.2)'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['point'], 'point' ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->point, '(9.2,1.2)' ); + + $bean->note = 'taint'; + + R::store( $bean ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->point, '(9.2,1.2)' ); + } + + /** + * Test polygons. + * + * @return void + */ + public function testPolygons() + { + $bean = R::dispense( 'bean' ); + $bean->polygon = '((0,0),(1,1),(2,0))'; + R::store( $bean ); + $cols = R::getColumns( 'bean' ); + asrt( $cols['polygon'], 'polygon' ); + $bean = R::load( 'bean', $bean->id ); + asrt( $bean->polygon, '((0,0),(1,1),(2,0))' ); + $bean->note = 'taint'; + R::store( $bean ); + $bean = R::load( 'bean', $bean->id ); + asrt( $bean->polygon, '((0,0),(1,1),(2,0))' ); + $bean = R::dispense( 'bean' ); + $bean->polygon = '((0,0),(1.2,1),(2,0.3))'; + R::store( $bean ); + $cols = R::getColumns( 'bean' ); + asrt( $cols['polygon'], 'polygon' ); + $bean = R::load( 'bean', $bean->id ); + asrt( $bean->polygon, '((0,0),(1.2,1),(2,0.3))' ); + $bean->note = 'taint'; + R::store( $bean ); + $bean = R::load( 'bean', $bean->id ); + asrt( $bean->polygon, '((0,0),(1.2,1),(2,0.3))' ); + } + + /** + * Test multi points. + * + * @return void + */ + public function testTypesMultiDecPoints() + { + $bean = R::dispense( 'bean' ); + + $bean->line = '[(1.2,1.4),(2.2,34)]'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['line'], 'lseg' ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->line, '[(1.2,1.4),(2.2,34)]' ); + + $bean->note = 'taint'; + + R::store( $bean ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->line, '[(1.2,1.4),(2.2,34)]' ); + } + + /** + * More points... + * + * @return void + */ + public function testTypesWeirdPoints() + { + $bean = R::dispense( 'bean' ); + + $bean->circle = '<(9.2,1.2),7.9>'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['circle'], 'circle' ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->circle, '<(9.2,1.2),7.9>' ); + + $bean->note = 'taint'; + + R::store( $bean ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->circle, '<(9.2,1.2),7.9>' ); + } + + /** + * Test money types. + * + * @return void + */ + public function testTypesMon() + { + $bean = R::dispense( 'bean' ); + + $bean->amount = '22.99'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['amount'], 'numeric' ); + + R::nuke(); + + $bean = R::dispense( 'bean' ); + + $bean->amount = '-22.99'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['amount'], 'numeric' ); + } + + /** + * Test money data type. + * + * @return void + */ + public function testTypesMoney() + { + $bean = R::dispense( 'bean' ); + + $bean->money = '$123.45'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['money'], 'money' ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->money, '$123.45' ); + + $bean->note = 'taint'; + + R::store( $bean ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->money, '$123.45' ); + + $bean->money = '$123,455.01'; + + R::store($bean); + + $bean = $bean->fresh(); + + asrt( $bean->money, '$123,455.01' ); + + } + + /** + * Test negative money data type. + * + * @return void + */ + public function testTypesNegativeMoney() + { + $bean = R::dispense( 'bean' ); + + $bean->money = '-$123.45'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['money'], 'money' ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->money, '-$123.45' ); + + $bean->note = 'taint'; + + R::store( $bean ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->money, '-$123.45' ); + } + + /** + * Issue #340 + * Redbean is currently picking up bcrypt hashed passwords + * (which look like this: $2y$12$85lAS....SnpDNVGPAC7w0G) + * as PostgreSQL money types. + * Then, once R::store is called on the bean, it chokes and throws the following error: + * PHP Fatal error: Uncaught [22P02] - SQLSTATE[22P02]: Invalid text representation: 7 ERROR: + * invalid input syntax for type money: .... + * + * @return void + */ + public function testTypesInvalidMoney() + { + $bean = R::dispense( 'bean' ); + + $bean->nomoney = '$2y$12$85lAS'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['nomoney'], 'text' ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->nomoney, '$2y$12$85lAS' ); + + $bean->note = 'taint'; + + R::store( $bean ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->nomoney, '$2y$12$85lAS' ); + } + + /** + * Test types of strings. + * + * @return void + */ + public function testTypesStrings() + { + $bean = R::dispense( 'bean' ); + + $bean->data = 'abcdefghijk'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['data'], 'text' ); + + $bean = R::load( 'bean', $bean->id ); + + asrt( $bean->data, 'abcdefghijk' ); + + $bean->data = '(1,2)'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['data'], 'text' ); + + $bean->data = '[(1.2,1.4),(2.2,34)]'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['data'], 'text' ); + + $bean->data = '<(9.2,1.2),7.9>'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['data'], 'text' ); + + $bean->data = '$25'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['data'], 'text' ); + + $bean->data = '2012-10-10 10:00:00'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['data'], 'text' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Pretest.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Pretest.php new file mode 100644 index 000000000..ff88f00ed --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Pretest.php @@ -0,0 +1,32 @@ +title = 'a'; + R::store( $book ); + try { + R::getWriter()->addIndex( 'book' , '\'', 'title' ); + pass(); + } catch( \Exception $e ) { + fail(); + } + R::getWriter()->addIndex( 'book' , '\'', 'title' ); + pass(); + } + + /** + * Test foreign keys with SQLite. + * + * @return void + */ + public function testForeignKeysWithSQLite() + { + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $cover = R::dispense( 'cover' ); + list( $g1, $g2 ) = R::dispense( 'genre', 2 ); + $g1->name = '1'; + $g2->name = '2'; + $book->ownPage = array( $page ); + $book->cover = $cover; + $book->sharedGenre = array( $g1, $g2 ); + R::store( $book ); + $fkbook = R::getAll( 'pragma foreign_key_list(book)' ); + $fkgenre = R::getAll( 'pragma foreign_key_list(book_genre)' ); + $fkpage = R::getAll( 'pragma foreign_key_list(page)' ); + asrt( $fkpage[0]['from'], 'book_id' ); + asrt( $fkpage[0]['to'], 'id' ); + asrt( $fkpage[0]['table'], 'book' ); + asrt( count( $fkgenre ), 2 ); + if ( $fkgenre[0]['from'] == 'book' ) { + asrt( $fkgenre[0]['to'], 'id' ); + asrt( $fkgenre[0]['table'], 'book' ); + } + if ( $fkgenre[0]['from'] == 'genre' ) { + asrt( $fkgenre[0]['to'], 'id' ); + asrt( $fkgenre[0]['table'], 'genre' ); + } + asrt( $fkbook[0]['from'], 'cover_id' ); + asrt( $fkbook[0]['to'], 'id' ); + asrt( $fkbook[0]['table'], 'cover' ); + } + + /** + * Constrain test for SQLite Writer. + * + * @return void + */ + public function testConstrain() + { + R::nuke(); + $sql = 'CREATE TABLE book ( id INTEGER PRIMARY KEY AUTOINCREMENT ) '; + R::exec( $sql ); + $sql = 'CREATE TABLE page ( id INTEGER PRIMARY KEY AUTOINCREMENT ) '; + R::exec( $sql ); + $sql = 'CREATE TABLE book_page ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + book_id INTEGER, + page_id INTEGER + ) '; + R::exec( $sql ); + $sql = 'PRAGMA foreign_key_list("book_page")'; + $fkList = R::getAll( $sql ); + asrt( count( $fkList), 0 ); + $writer = R::getWriter(); + $writer->addFK( 'book_page', 'book', 'book_id', 'id', TRUE ); + $writer->addFK( 'book_page', 'page', 'page_id', 'id', TRUE ); + $sql = 'PRAGMA foreign_key_list("book_page")'; + $fkList = R::getAll( $sql ); + asrt( count( $fkList), 2 ); + $writer->addFK( 'book_page', 'book', 'book_id', 'id', TRUE ); + $writer->addFK( 'book_page', 'page', 'page_id', 'id', TRUE ); + $sql = 'PRAGMA foreign_key_list("book_page")'; + $fkList = R::getAll( $sql ); + asrt( count( $fkList), 2 ); + } + + /** + * Test adding foreign keys. + * + * @return void + */ + public function testAddingForeignKeys() + { + R::nuke(); + + $sql = 'CREATE TABLE book ( id INTEGER PRIMARY KEY AUTOINCREMENT ) '; + R::exec( $sql ); + $sql = 'CREATE TABLE page ( id INTEGER PRIMARY KEY AUTOINCREMENT, book_id INTEGER ) '; + R::exec( $sql ); + asrt( count( R::getAll(' PRAGMA foreign_key_list("page") ') ), 0 ); + $writer = R::getWriter(); + $writer->addFK('page', 'book', 'book_id', 'id', TRUE); + asrt( count( R::getAll(' PRAGMA foreign_key_list("page") ') ), 1 ); + $writer->addFK('page', 'book', 'book_id', 'id', TRUE); + asrt( count( R::getAll(' PRAGMA foreign_key_list("page") ') ), 1 ); + $writer->addFK('page', 'book', 'book_id', 'id', FALSE); + asrt( count( R::getAll(' PRAGMA foreign_key_list("page") ') ), 1 ); + R::nuke(); + $sql = 'CREATE TABLE book ( id INTEGER PRIMARY KEY AUTOINCREMENT ) '; + R::exec( $sql ); + $sql = 'CREATE TABLE page ( id INTEGER PRIMARY KEY AUTOINCREMENT, book_id INTEGER ) '; + R::exec( $sql ); + asrt( count( R::getAll(' PRAGMA foreign_key_list("page") ') ), 0 ); + $writer = R::getWriter(); + $writer->addFK('page', 'book', 'book_id', 'id', FALSE); + asrt( count( R::getAll(' PRAGMA foreign_key_list("page") ') ), 1 ); + $writer->addFK('page', 'book', 'book_id', 'id', TRUE); + asrt( count( R::getAll(' PRAGMA foreign_key_list("page") ') ), 1 ); + $writer->addFK('page', 'book', 'book_id', 'id', FALSE); + asrt( count( R::getAll(' PRAGMA foreign_key_list("page") ') ), 1 ); + } + + /** + * Test whether we can manually create indexes. + * + * @return void + */ + public function testAddingIndex() + { + R::nuke(); + $sql = 'CREATE TABLE song ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + album_id INTEGER, + category TEXT + ) '; + R::exec( $sql ); + $writer = R::getWriter(); + $indexes = R::getAll('PRAGMA index_list("song") '); + asrt( count( $indexes ), 0 ); + $writer->addIndex( 'song', 'index1', 'album_id' ); + $indexes = R::getAll('PRAGMA index_list("song") '); + asrt( count( $indexes ), 1 ); + $writer->addIndex( 'song', 'index1', 'album_id' ); + $indexes = R::getAll('PRAGMA index_list("song") '); + asrt( count( $indexes ), 1 ); + $writer->addIndex( 'song', 'index2', 'category' ); + $indexes = R::getAll('PRAGMA index_list("song") '); + asrt( count( $indexes ), 2 ); + try { + $writer->addIndex( 'song', 'index1', 'nonexistant' ); + pass(); + } catch ( \Exception $ex ) { + fail(); + } + $indexes = R::getAll('PRAGMA index_list("song") '); + asrt( count( $indexes ), 2 ); + try { + $writer->addIndex( 'nonexistant', 'index1', 'nonexistant' ); + pass(); + } catch ( \Exception $ex ) { + fail(); + } + $indexes = R::getAll('PRAGMA index_list("song") '); + asrt( count( $indexes ), 2 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Sqlite/Parambind.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Sqlite/Parambind.php new file mode 100644 index 000000000..b3013da2e --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Sqlite/Parambind.php @@ -0,0 +1,60 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + asrt( (int) $adapter->getCell( "SELECT 123" ), 123 ); + asrt( (int) $adapter->getCell( "SELECT ?", array( "987" ) ), 987 ); + asrt( (int) $adapter->getCell( "SELECT ?+?", array( "987", "2" ) ), 989 ); + asrt( (int) $adapter->getCell( + "SELECT :numberOne+:numberTwo", + array( + ":numberOne" => 42, + ":numberTwo" => 50 ) + ), + 92 + ); + $pair = $adapter->getAssoc( "SELECT 'thekey','thevalue' " ); + asrt( is_array( $pair ), TRUE ); + asrt( count( $pair ), 1 ); + asrt( isset( $pair["thekey"] ), TRUE ); + asrt( $pair["thekey"], "thevalue" ); + testpack( 'Test whether we can properly bind and receive NULL values' ); + asrt( $adapter->getCell( 'SELECT :nil ', array( ':nil' => 'NULL' ) ), 'NULL' ); + asrt( $adapter->getCell( 'SELECT :nil ', array( ':nil' => NULL ) ), NULL ); + asrt( $adapter->getCell( 'SELECT ? ', array( 'NULL' ) ), 'NULL' ); + asrt( $adapter->getCell( 'SELECT ? ', array( NULL ) ), NULL ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Sqlite/Rebuild.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Sqlite/Rebuild.php new file mode 100644 index 000000000..81ad4055e --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Sqlite/Rebuild.php @@ -0,0 +1,63 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->xownPage[] = $page; + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( count( $book->xownPage ), 1 ); + asrt( (int) R::getCell( 'SELECT COUNT(*) FROM page' ), 1 ); + R::trash( $book ); + asrt( (int) R::getCell( 'SELECT COUNT(*) FROM page' ), 0 ); + $book = R::dispense( 'book' ); + $page = R::dispense( 'page' ); + $book->xownPage[] = $page; + $id = R::store( $book ); + $book = R::load( 'book', $id ); + asrt( count( $book->xownPage ), 1 ); + asrt( (int) R::getCell( 'SELECT COUNT(*) FROM page' ), 1 ); + $book->added = 2; + R::store( $book ); + $book->added = 'added'; + R::store( $book ); + R::trash( $book ); + asrt( (int) R::getCell( 'SELECT COUNT(*) FROM page' ), 0 ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Sqlite/Setget.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Sqlite/Setget.php new file mode 100644 index 000000000..563fb55c4 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Sqlite/Setget.php @@ -0,0 +1,128 @@ +getDatabaseAdapter(); + $writer = $toolbox->getWriter(); + $redbean = $toolbox->getRedBean(); + $pdo = $adapter->getDatabase(); + + $a = new AssociationManager( $toolbox ); + + asrt( in_array( "testtable", $writer->getTables() ), FALSE ); + + $writer->createTable( "testtable" ); + + asrt( in_array( "testtable", $writer->getTables() ), TRUE ); + + asrt( count( array_keys( $writer->getColumns( "testtable" ) ) ), 1 ); + + asrt( in_array( "id", array_keys( $writer->getColumns( "testtable" ) ) ), TRUE ); + asrt( in_array( "c1", array_keys( $writer->getColumns( "testtable" ) ) ), FALSE ); + + $writer->addColumn( "testtable", "c1", 1 ); + + asrt( count( array_keys( $writer->getColumns( "testtable" ) ) ), 2 ); + + asrt( in_array( "c1", array_keys( $writer->getColumns( "testtable" ) ) ), TRUE ); + + foreach ( $writer->sqltype_typeno as $key => $type ) { + asrt( $writer->code( $key ), $type ); + } + + asrt( $writer->code( "unknown" ), 99 ); + + asrt( $writer->scanType( FALSE ), SQLiteT::C_DATATYPE_INTEGER ); + asrt( $writer->scanType( NULL ), SQLiteT::C_DATATYPE_INTEGER ); + + asrt( $writer->scanType( 2 ), SQLiteT::C_DATATYPE_INTEGER ); + asrt( $writer->scanType( 255 ), SQLiteT::C_DATATYPE_INTEGER ); + asrt( $writer->scanType( 256 ), SQLiteT::C_DATATYPE_INTEGER ); + asrt( $writer->scanType( -1 ), SQLiteT::C_DATATYPE_INTEGER ); + asrt( $writer->scanType( 1.5 ), SQLiteT::C_DATATYPE_NUMERIC ); + + asrt( $writer->scanType( 2147483648 - 1 ), SQLiteT::C_DATATYPE_INTEGER ); + asrt( $writer->scanType( 2147483648 ), SQLiteT::C_DATATYPE_TEXT ); + + asrt( $writer->scanType( -2147483648 + 1), SQLiteT::C_DATATYPE_INTEGER ); + asrt( $writer->scanType( -2147483648 ), SQLiteT::C_DATATYPE_TEXT ); + + asrt( $writer->scanType( INF ), SQLiteT::C_DATATYPE_TEXT ); + + asrt( $writer->scanType( "abc" ), SQLiteT::C_DATATYPE_TEXT ); + + asrt( $writer->scanType( '2010-10-10' ), SQLiteT::C_DATATYPE_NUMERIC ); + asrt( $writer->scanType( '2010-10-10 10:00:00' ), SQLiteT::C_DATATYPE_NUMERIC ); + + asrt( $writer->scanType( str_repeat( "lorem ipsum", 100 ) ), SQLiteT::C_DATATYPE_TEXT ); + + $writer->widenColumn( "testtable", "c1", 2 ); + + $cols = $writer->getColumns( "testtable" ); + + asrt( $writer->code( $cols["c1"] ), 2 ); + + //$id = $writer->insertRecord("testtable", array("c1"), array(array("lorem ipsum"))); + $id = $writer->updateRecord( "testtable", array( array( "property" => "c1", "value" => "lorem ipsum" ) ) ); + $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) ); + + asrt( $row[0]["c1"], "lorem ipsum" ); + + $writer->updateRecord( "testtable", array( array( "property" => "c1", "value" => "ipsum lorem" ) ), $id ); + + $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) ); + + asrt( $row[0]["c1"], "ipsum lorem" ); + + $writer->deleteRecord( "testtable", array( "id" => array( $id ) ) ); + + $row = $writer->queryRecord( "testtable", array( "id" => array( $id ) ) ); + + asrt( empty( $row ), TRUE ); + } + + /** + * (FALSE should be stored as 0 not as '') + * + * @return void + */ + public function testZeroIssue() + { + testpack( "Zero issue" ); + + $toolbox = R::getToolBox(); + $redbean = $toolbox->getRedBean(); + + $bean = $redbean->dispense( "zero" ); + + $bean->zero = FALSE; + $bean->title = "bla"; + + $redbean->store( $bean ); + + asrt( count( $redbean->find( "zero", array(), " zero = 0 " ) ), 1 ); + + testpack( "Test ANSI92 issue in clearrelations" ); + + $redbean = $toolbox->getRedBean(); + + $a = new AssociationManager( $toolbox ); + + $book = $redbean->dispense( "book" ); + $author1 = $redbean->dispense( "author" ); + $author2 = $redbean->dispense( "author" ); + + $book->title = "My First Post"; + + $author1->name = "Derek"; + $author2->name = "Whoever"; + + set1toNAssoc( $a, $book, $author1 ); + set1toNAssoc( $a, $book, $author2 ); + + pass(); + } + + /** + * Various. + * Tests whether writer correctly handles keyword 'group' and SQL state 23000 issue. + * These tests remain here to make sure issues 9 and 10 never happen again. + * However this bug will probably never re-appear due to changed architecture. + * + * @return void + */ + public function testIssue9and10() + { + $toolbox = R::getToolBox(); + $redbean = $toolbox->getRedBean(); + $adapter = $toolbox->getDatabaseAdapter(); + + $a = new AssociationManager( $toolbox ); + + $book = $redbean->dispense( "book" ); + $author1 = $redbean->dispense( "author" ); + $author2 = $redbean->dispense( "author" ); + + $book->title = "My First Post"; + + $author1->name = "Derek"; + $author2->name = "Whoever"; + + $a->associate( $book, $author1 ); + $a->associate( $book, $author2 ); + + pass(); + + testpack( "Test Association Issue Group keyword (Issues 9 and 10)" ); + + $group = $redbean->dispense( "group" ); + $group->name = "mygroup"; + + $redbean->store( $group ); + + try { + $a->associate( $group, $book ); + + pass(); + } catch ( SQL $e ) { + fail(); + } + + // Test issue SQL error 23000 + try { + $a->associate( $group, $book ); + + pass(); + } catch ( SQL $e ) { + print_r( $e ); + + fail(); + } + + asrt( (int) $adapter->getCell( "select count(*) from book_group" ), 1 ); //just 1 rec! + } + + /** + * Test various. + * Test various somewhat uncommon trash/unassociate scenarios. + * (i.e. unassociate unrelated beans, trash non-persistant beans etc). + * Should be handled gracefully - no output checking. + * + * @return void + */ + public function testVaria2() + { + $toolbox = R::getToolBox(); + $redbean = $toolbox->getRedBean(); + + $a = new AssociationManager( $toolbox ); + + $book = $redbean->dispense( "book" ); + $author1 = $redbean->dispense( "author" ); + $author2 = $redbean->dispense( "author" ); + + $book->title = "My First Post"; + + $author1->name = "Derek"; + $author2->name = "Whoever"; + + $a->unassociate( $book, $author1 ); + $a->unassociate( $book, $author2 ); + + pass(); + + $redbean->trash( $redbean->dispense( "bla" ) ); + + pass(); + + $bean = $redbean->dispense( "bla" ); + + $bean->name = 1; + $bean->id = 2; + + $redbean->trash( $bean ); + + pass(); + } + + /** + * Test special data types. + * + * @return void + */ + public function testSpecialDataTypes() + { + testpack( 'Special data types' ); + + $bean = R::dispense( 'bean' ); + + $bean->date = 'someday'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'TEXT' ); + + $bean = R::dispense( 'bean' ); + + $bean->date = '2011-10-10'; + + R::nuke(); + + $bean = R::dispense( 'bean' ); + + $bean->date = '2011-10-10'; + + R::store( $bean ); + + $cols = R::getColumns( 'bean' ); + + asrt( $cols['date'], 'NUMERIC' ); + } +} diff --git a/vendor/gabordemooij/redbean/testing/cli/plugins/myhooks.php b/vendor/gabordemooij/redbean/testing/cli/plugins/myhooks.php new file mode 100644 index 000000000..386999461 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/cli/plugins/myhooks.php @@ -0,0 +1,27 @@ + 'localhost', + 'schema' => 'cubase', + 'user' => 'dba', + 'pass' => '' +); + +$colorMap[ 'CUBRID' ] = '0;35'; + +$dsn = "cubrid:host={$ini['CUBRID']['host']};port=33000;dbname={$ini['CUBRID']['schema']}"; +R::addDatabase( 'CUBRID', $dsn, $ini['CUBRID']['user'], $ini['CUBRID']['pass'], FALSE ); +R::selectDatabase( 'CUBRID' ); +R::exec( 'AUTOCOMMIT IS ON' ); diff --git a/vendor/gabordemooij/redbean/testing/cli/runperf.php b/vendor/gabordemooij/redbean/testing/cli/runperf.php new file mode 100644 index 000000000..1d584d56d --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/cli/runperf.php @@ -0,0 +1,96 @@ +getTargetDrivers(); + +foreach ( $drivers as $driver ) { + + if ( !isset( $ini[$driver] ) ) continue; + if ( !isset( $_SERVER['argv'][1])) die('Missing parameter. Usage: php runperf.php '); + + $method = $_SERVER['argv'][1]; + + if ($method === 'setup') { + + echo 'Setup...'.PHP_EOL; + + $test->$method(); + + echo 'READY'.PHP_EOL; + + } else { + + $times = 100; + if (isset($_SERVER['argv'][2])) { + $times = (int) $_SERVER['argv'][2]; + } + + echo "Performing test: $method with driver $driver ".PHP_EOL; + + for ($j=0; $j<$times; $j++) { + + $t1 = microtime( TRUE ); + + $test->$method(); + + $t2 = microtime( TRUE ); + + $d[] = ($t2 - $t1); + + } + + $s = array_sum($d); + $a = ($s / $times); + $mx = max($d); + $mn = min($d); + + echo PHP_EOL."AVG: $a, MAX: $mx, MIN: $mn, TOTAL: $s, TIMES: $times ".PHP_EOL; + } +} \ No newline at end of file diff --git a/vendor/gabordemooij/redbean/testing/cli/runtests.php b/vendor/gabordemooij/redbean/testing/cli/runtests.php new file mode 100644 index 000000000..8f75b5635 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/cli/runtests.php @@ -0,0 +1,312 @@ + '0;31', + 'pgsql' => '0;32', + 'sqlite' => '0;34', +); + +@include 'cli/test_hook.php'; + +//Configure the databases +if ( isset( $ini['mysql'] ) ) { + $dsn = "mysql:host={$ini['mysql']['host']};dbname={$ini['mysql']['schema']}"; + + R::addDatabase( 'mysql', $dsn, $ini['mysql']['user'], $ini['mysql']['pass'], FALSE ); + + R::selectDatabase( 'mysql' ); + + R::exec( ' SET GLOBAL sql_mode="" ' ); +} + +//HHVM on Travis does not yet support PostgreSQL. +if ( defined( 'HHVM_VERSION' ) ) { + unset( $ini['pgsql'] ); +} else { + if ( isset( $ini['pgsql'] ) ) { + $dsn = "pgsql:host={$ini['pgsql']['host']};dbname={$ini['pgsql']['schema']}"; + R::addDatabase( 'pgsql', $dsn, $ini['pgsql']['user'], $ini['pgsql']['pass'], FALSE ); + } +} + +if ( isset( $ini['sqlite'] ) ) { + R::addDatabase( 'sqlite', 'sqlite:' . $ini['sqlite']['file'], NULL, NULL, FALSE ); +} + +R::selectDatabase( 'sqlite' ); + +// Function to activate a driver +function activate_driver( $d ) +{ + R::selectDatabase( $d ); +} + +$arguments = $_SERVER['argc']; + +$mode = 'all'; +if ( $arguments > 1 ) { + $mode = $_SERVER['argv'][1]; +} + +$classSpec = null; +if ( $arguments > 2 ) { + $classSpec = $_SERVER['argv'][2]; +} + +$covFilter = null; +if ( $arguments > 3 ) { + $covFilter = $_SERVER['argv'][3]; +} + +$path = 'RedUNIT/'; + +// Possible Selections +$packList = array(); + +$allPacks = array( + 'Blackhole/Version', + 'Blackhole/Toolbox', + 'Blackhole/Fusebox', + 'Blackhole/Labels', + 'Blackhole/Tainted', + 'Blackhole/Meta', + 'Blackhole/Import', + 'Blackhole/Export', + 'Blackhole/Glue', + 'Blackhole/Plugins', + 'Blackhole/Debug', + 'Base/Dispense', + 'Base/Logging', + 'Base/Cursors', + 'Base/Indexes', + 'Base/Issue408', + 'Base/Threeway', + 'Base/Chill', + 'Base/Arrays', + 'Base/Boxing', + 'Base/Typechecking', + 'Base/Observers', + 'Base/Database', + 'Base/Foreignkeys', + 'Base/Namedparams', + 'Base/Prefixes', + 'Base/Copy', + 'Base/Dup', + 'Base/Update', + 'Base/Utf8', + 'Base/Batch', + 'Base/Bean', + 'Base/Writecache', + 'Base/Relations', + 'Base/Association', + 'Base/Aliasing', + 'Base/Cross', + 'Base/Finding', + 'Base/Facade', + 'Base/Frozen', + 'Base/Fuse', + 'Base/Tags', + 'Base/Xnull', + 'Base/Largenum', + 'Base/Issue90', + 'Base/Issue259', + 'Base/Issue303', + 'Base/Nuke', + 'Base/Keywords', + 'Base/Count', + 'Base/With', + 'Base/Joins', + 'Base/Traverse', + 'Base/Misc', + 'Base/Via', + 'Base/PullRequest530', + 'Mysql/Preexist', + 'Mysql/Double', + 'Mysql/Writer', + 'Mysql/Freeze', + 'Mysql/Setget', + 'Mysql/Foreignkeys', + 'Mysql/Parambind', + 'Mysql/Uuid', + 'Mysql/Bigint', + 'Mysql/Issue411', + 'Postgres/Setget', + 'Postgres/Foreignkeys', + 'Postgres/Parambind', + 'Postgres/Writer', + 'Postgres/Uuid', + 'Postgres/Bigint', + 'Sqlite/Setget', + 'Sqlite/Foreignkeys', + 'Sqlite/Parambind', + 'Sqlite/Writer', + 'Sqlite/Rebuild', +); + +$suffix = array( + 'Blackhole/Misc', + 'Base/Close' +); + +// Default (mode == all) +if ( $mode == 'all' ) { + $packList = $allPacks; +} else { + foreach ( $allPacks as $pack ) { + if ( strpos( $pack, $mode ) === 0 ) $packList[] = $pack; + } + //Add plugin pack to list. + if ( count($packList) === 0 && count($extraTestsFromHook) === 0 ) { + $packList[] = $mode; + } +} + +// Always include the last ones. +$packList = array_unique(array_merge( $packList, $suffix, $extraTestsFromHook )); +$j = 0; +foreach ( $packList as $testPack ) { + $j++; + if ( file_exists( $path . $testPack . '.php' ) ) require( $path . $testPack . '.php' ); + elseif ( file_exists( $hookPath . $testPack . '.php') ) require( $hookPath . $testPack . '.php' ); + $testPack = str_replace( '../', '', $testPack ); + if ($j === 1 && $classSpec) { + $testClass = $classSpec; + } else { + $testClassName = str_replace( ' ', '\\', ( str_replace( '/', ' ', $testPack ) ) ); + $testClass = '\\RedUNIT\\' . ucfirst( $testClassName ); + } + $test = new $testClass(); + $drivers = $test->getTargetDrivers(); + maintestpack( str_replace( '_', ' ', get_class( $test ) ) ); + $round = 0; + $test->setRound( $round ); + if ( $drivers && is_array( $drivers ) ) { + foreach ( $drivers as $driver ) { + if ( !isset( $ini[$driver] ) ) continue; + echo PHP_EOL; + echo '===== DRIVER : (' . $driver . ') ====='; + echo PHP_EOL; + echo PHP_EOL; + if ( isset( $colorMap[$driver] ) ) { + echo "\033[{$colorMap[$driver]}m"; + } + activate_driver( $driver ); + $currentDriver = $driver; + $test->setCurrentDriver( $driver ); + $test->prepare(); + $test->run(); + $test->cleanUp(); + if ( isset ( $colorMap[$driver] ) ) { + echo "\033[0m"; + } + echo PHP_EOL; + $test->setRound( ++$round ); + } + } else { + $test->prepare(); + $test->run(); + $test->cleanUp(); + } +} + +if (!$xdebugSupported) { + echo 'Done. No report - XDEBUG not installed.'; + exit(0); +} + +$report = xdebug_get_code_coverage(); +$misses = 0; +$hits = 0; + +$covLines = array(); +foreach( $report as $file => $lines ) { + + $pi = pathinfo( $file ); + + if ( $covFilter !== null ) { + if ( strpos( $file, $covFilter ) === false ) continue; + } else { + if ( strpos( $file, '/rb.php' ) === false) { + if ( strpos( $file, 'phar/' ) === false ) continue; + if ( strpos( $file, '.php' ) === false ) continue; + if ( strpos( $file, 'RedBeanPHP' ) === false ) continue; + } + } + $covLines[] = '***** File:'.$file.' ******'; + $fileData = file_get_contents( $file ); + $fileLines = explode( "\n", $fileData ); + $i = 1; + foreach( $fileLines as $covLine ) { + if ( isset( $lines [$i] ) ) { + if ( $lines[$i] === 1 ) { + $covLines[] = '[ OK ] '.$covLine; + $hits ++; + } else if ( $lines[$i] === -1 ){ + $covLines[] = '[ MISSED! ] '.$covLine; + $misses ++; + } else { + $covLines[] = '[ - ] '.$covLine; + } + } else { + $covLines[] = '[ - ] '.$covLine; + } + $i ++; + } +} +$covFile = implode( "\n", $covLines ); +@file_put_contents( 'cli/coverage_log.txt', $covFile ); +if ( $hits > 0 ) { + $perc = ( $hits / ( $hits + $misses ) ) * 100; +} else { + $perc = 0; +} +echo 'Code Coverage: '.PHP_EOL; +echo 'Hits: '.$hits.PHP_EOL; +echo 'Misses: '.$misses.PHP_EOL; +echo 'Percentage: '.$perc.' %'.PHP_EOL; +exit( 0 ); diff --git a/vendor/gabordemooij/redbean/testing/cli/test_hook_example.php b/vendor/gabordemooij/redbean/testing/cli/test_hook_example.php new file mode 100644 index 000000000..ab86d2653 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/cli/test_hook_example.php @@ -0,0 +1,14 @@ + add 1 additional path which will be searched for unit tests + * $extraTestsFromHook -> array with additional test packs (will be executed if you pass 'all' argument to CLI runner) + * + * + */ \ No newline at end of file diff --git a/vendor/gabordemooij/redbean/testing/cli/testcontainer/put-rb-file-here.txt b/vendor/gabordemooij/redbean/testing/cli/testcontainer/put-rb-file-here.txt new file mode 100644 index 000000000..796d8aac2 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/cli/testcontainer/put-rb-file-here.txt @@ -0,0 +1,5 @@ +/* + +Put the rb.php file in this directory + +*/ diff --git a/vendor/gabordemooij/redbean/testing/config/test-dist.ini b/vendor/gabordemooij/redbean/testing/config/test-dist.ini new file mode 100644 index 000000000..e2d1b8a43 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/config/test-dist.ini @@ -0,0 +1,17 @@ +; Test suite database config +; Rename this file to test.ini if you are done + +[mysql] +host = "localhost" +schema = "" +user = "" +pass = "" + +[pgsql] +host = "localhost" +schema = "" +user = "" +pass = "" + +[sqlite] +file = "/tmp/database.db" diff --git a/vendor/gabordemooij/redbean/testing/config/test-travis.ini b/vendor/gabordemooij/redbean/testing/config/test-travis.ini new file mode 100644 index 000000000..f6dd1ed51 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/config/test-travis.ini @@ -0,0 +1,18 @@ +; Test suite database config +; Rename this file to test.ini if you are done + +[mysql] +host = "localhost" +schema = "oodb" +user = "root" +pass = "" + +[pgsql] +host = "localhost" +schema = "oodb" +user = "postgres" +pass = "" + +[sqlite] +file = "/tmp/oodb.db" + diff --git a/vendor/gabordemooij/redbean/testing/helpers/classes.php b/vendor/gabordemooij/redbean/testing/helpers/classes.php new file mode 100644 index 000000000..d3a897b91 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/helpers/classes.php @@ -0,0 +1,669 @@ +signal( $eventname, $info ); + } +} + +/** + * Observer Mock + * This is just for testing + */ +class ObserverMock implements \RedBeanPHP\Observer +{ + /** + * @var bool + */ + public $event = FALSE; + + /** + * @var bool + */ + public $info = FALSE; + + /** + * @param string $event + * @param $info + */ + public function onEvent( $event, $info ) + { + $this->event = $event; + $this->info = $info; + } +} + +/** + * Shared helper class for tests. + * A test model to test FUSE functions. + */ +class Model_Band extends RedBeanPHP\SimpleModel +{ + public function after_update() { } + + private $notes = array(); + + /** + * @throws Exception + */ + public function update() + { + if ( count( $this->ownBandmember ) > 4 ) { + throw new Exception( 'too many!' ); + } + } + + /** + * @return string + */ + public function __toString() + { + return 'bigband'; + } + + /** + * @param $prop + * @param $value + */ + public function setProperty( $prop, $value ) + { + $this->$prop = $value; + } + + /** + * @param $prop + * + * @return bool + */ + public function checkProperty( $prop ) + { + return isset( $this->$prop ); + } + + /** + * Sets a note. + * + * @param string $note + * + * @param mixed $value + * + * @return void + */ + public function setNote( $note, $value ) + { + $this->notes[ $note ] = $value; + } + + /** + * Returns the value of a note. + * + * @param string $note + * + * @return string + */ + public function getNote( $note ) + { + return $this->notes[ $note ]; + } +} + +/** + * Shared helper class for tests. + * A Model class for testing Models/FUSE and related features. + */ +class Model_Box extends RedBeanPHP\SimpleModel +{ + public function delete() { $a = $this->bean->ownBottle; } +} + +/** + * Shared helper class for tests. + * A Model class for testing Models/FUSE and related features. + */ +class Model_Cocoa extends RedBeanPHP\SimpleModel +{ + public function update(){} +} + +/** + * Shared helper class for tests. + * A Model class for testing Models/FUSE and related features. + */ +class Model_Taste extends RedBeanPHP\SimpleModel +{ + public function after_update() + { + asrt( count( $this->bean->ownCocoa ), 0 ); + } +} + +/** + * Shared helper class for tests. + * A Model class for testing Models/FUSE and related features. + */ +class Model_Coffee extends RedBeanPHP\SimpleModel +{ + public function update() + { + while ( count( $this->bean->ownSugar ) > 3 ) { + array_pop( $this->bean->ownSugar ); + } + } +} + +/** + * Shared helper class for tests. + * A Model class for testing Models/FUSE and related features. + */ +class Model_Test extends RedBeanPHP\SimpleModel +{ + public function update() + { + if ( $this->bean->item->val ) { + $this->bean->item->val = 'Test2'; + $can = R::dispense( 'can' ); + $can->name = 'can for bean'; + $s = reset( $this->bean->sharedSpoon ); + $s->name = "S2"; + $this->bean->item->deep->name = '123'; + $this->bean->ownCan[] = $can; + $this->bean->sharedPeas = R::dispense( 'peas', 10 ); + $this->bean->ownChip = R::dispense( 'chip', 9 ); + } + } +} + +global $lifeCycle; + +/** + * Shared helper class for tests. + * A Model class for testing Models/FUSE and related features. + */ +class Model_Bandmember extends RedBeanPHP\SimpleModel +{ + public function open() + { + global $lifeCycle; + + $lifeCycle .= "\n called open: " . $this->id; + } + + public function dispense() + { + global $lifeCycle; + + $lifeCycle .= "\n called dispense() " . $this->bean; + } + + public function update() + { + global $lifeCycle; + + $lifeCycle .= "\n called update() " . $this->bean; + } + + public function after_update() + { + global $lifeCycle; + + $lifeCycle .= "\n called after_update() " . $this->bean; + } + + public function delete() + { + global $lifeCycle; + + $lifeCycle .= "\n called delete() " . $this->bean; + } + + public function after_delete() + { + global $lifeCycle; + + $lifeCycle .= "\n called after_delete() " . $this->bean; + } +} + +/** + * A model to box soup models :) + */ +class Model_Soup extends \RedBeanPHP\SimpleModel +{ + private $flavour = ''; + + public function taste() + { + return 'A bit too salty'; + } + + public function setFlavour( $flavour ) + { + $this->flavour = $flavour; + } + + public function getFlavour() + { + return $this->flavour; + } +} + +/** + * A custom BeanHelper to test custom FUSE operations. + */ +class SoupBeanHelper extends \RedBeanPHP\BeanHelper\SimpleFacadeBeanHelper +{ + /** + * Returns a model for a bean based on its type. + * + * @param OODBBean $bean + * + * @return object + */ + public function getModelForBean( \RedBeanPHP\OODBBean $bean ) + { + if ( $bean->getMeta( 'type' ) === 'meal' ) { + $model = new Model_Soup; + $model->loadBean( $bean ); + return $model; + } else { + return parent::getModelForBean( $bean ); + } + } +} + +/** + * Test Model. + */ +class Model_Boxedbean extends \RedBeanPHP\SimpleModel +{ +} + +/** + * Mock class for testing purposes. + */ +class Model_Ghost_House extends \RedBeanPHP\SimpleModel +{ + public static $deleted = FALSE; + + public function delete() + { + self::$deleted = TRUE; + } +} + +/** + * Mock class for testing purposes. + */ +class Model_Ghost_Ghost extends \RedBeanPHP\SimpleModel +{ + public static $deleted = FALSE; + + public function delete() + { + self::$deleted = TRUE; + } +} + +/** + * Mock class for testing purposes. + */ +class FaultyWriter extends \RedBeanPHP\QueryWriter\MySQL +{ + + protected $sqlState; + + /** + * Mock method. + * + * @param string $sqlState sql state + */ + public function setSQLState( $sqlState ) + { + $this->sqlState = $sqlState; + } + + /** + * Mock method + * + * @param string $sourceType destination type + * @param string $destType source type + * + * @throws SQL + */ + public function addUniqueConstraint( $sourceType, $destType ) + { + $exception = new \RedBeanPHP\RedException\SQL; + $exception->setSQLState( $this->sqlState ); + throw $exception; + } + + /** + * Mock method. + * Generates an exception when trying to invoke + * getKeyMapForType via getForeignKeyForTypeProperty. + * + * @return void + */ + protected function getKeyMapForType( $type ) + { + throw new \RedBeanPHP\RedException\SQL; + } +} + +/** + * Mock class to test default implementations in AQueryWriter. + */ +class NullWriter extends \RedBeanPHP\QueryWriter\AQueryWriter { +} + +class ProxyWriter extends \RedBeanPHP\QueryWriter\AQueryWriter { + + public static function callMethod( $object, $method, $arg1 = NULL, $arg2 = NULL, $arg3 = NULL ) { + return $object->$method( $arg1, $arg2, $arg3 ); + } + +} + +/** + * Mock class to test proper model name + * beautificattion for link table beans in FUSE. + */ +class Model_PageWidget extends RedBean_SimpleModel { + /** + * @var string + */ + private static $test = ''; + + /** + * Returns the test flag. + * + * @return string + */ + public static function getTestReport() + { + return self::$test; + } + + /** + * Update method to set the flag. + */ + public function update() + { + self::$test = 'didSave'; + } +} + +/** + * Mock class to test proper model name + * beautificattion for link table beans in FUSE. + */ +class Model_Gadget_Page extends RedBean_SimpleModel { + /** + * @var string + */ + private static $test = ''; + + /** + * Returns the test flag. + * + * @return string + */ + public static function getTestReport() + { + return self::$test; + } + + /** + * Update method to set the flag. + */ + public function update() + { + self::$test = 'didSave'; + } +} + +/** + * Mock class to test proper model name + * beautificattion for link table beans in FUSE. + */ +class Model_A_B_C extends RedBean_SimpleModel { + /** + * @var string + */ + private static $test = ''; + + /** + * Returns the test flag. + * + * @return string + */ + public static function getTestReport() + { + return self::$test; + } + + /** + * Update method to set the flag. + */ + public function update() + { + self::$test = 'didSave'; + } +} + +class Model_BookBook extends \RedBean_SimpleModel { + public function delete() { + asrt($this->bean->shelf, 'x13'); + } +} + +class Model_Feed extends \RedbeanPHP\SimpleModel { + public function update() { + $this->bean->post = json_encode($this->bean->post); + } + + public function open() { + $this->bean->post = json_decode($this->bean->post, true); + } +} + +/** + * UUID QueryWriter for MySQL for testing purposes. + */ +class UUIDWriterMySQL extends \RedBeanPHP\QueryWriter\MySQL { + + protected $defaultValue = '@uuid'; + const C_DATATYPE_SPECIAL_UUID = 97; + + public function __construct( \RedBeanPHP\Adapter $adapter ) + { + parent::__construct( $adapter ); + $this->addDataType( self::C_DATATYPE_SPECIAL_UUID, 'char(36)' ); + } + + public function createTable( $table ) + { + $table = $this->esc( $table ); + $sql = " + CREATE TABLE {$table} ( + id char(36) NOT NULL, + PRIMARY KEY ( id )) + ENGINE = InnoDB DEFAULT + CHARSET=utf8mb4 + COLLATE=utf8mb4_unicode_ci "; + $this->adapter->exec( $sql ); + } + + public function updateRecord($table, $updateValues, $id = NULL) + { + $flagNeedsReturnID = (!$id); + if ($flagNeedsReturnID) R::exec('SET @uuid = uuid() '); + $id = parent::updateRecord( $table, $updateValues, $id ); + if ( $flagNeedsReturnID ) $id = R::getCell('SELECT @uuid'); + return $id; + } + + public function getTypeForID() + { + return self::C_DATATYPE_SPECIAL_UUID; + } +} + +/** + * UUID QueryWriter for PostgreSQL for testing purposes. + */ +class UUIDWriterPostgres extends \RedBeanPHP\QueryWriter\PostgreSQL { + + protected $defaultValue = 'uuid_generate_v4()'; + const C_DATATYPE_SPECIAL_UUID = 97; + + public function __construct( \RedBeanPHP\Adapter $adapter ) + { + parent::__construct( $adapter ); + $this->addDataType( self::C_DATATYPE_SPECIAL_UUID, 'uuid' ); + } + + public function createTable( $table ) + { + $table = $this->esc( $table ); + $this->adapter->exec( " CREATE TABLE $table (id uuid PRIMARY KEY); " ); + } + + public function getTypeForID() + { + return self::C_DATATYPE_SPECIAL_UUID; + } +} + +class DiagnosticBean extends \RedBeanPHP\OODBBean { + + /** + * Returns current status of modification flags. + * + * @return string + */ + public function getModFlags() + { + $modFlags = ''; + if ($this->aliasName !== NULL) $modFlags .= 'a'; + if ($this->fetchType !== NULL) $modFlags .= 'f'; + if ($this->noLoad === TRUE) $modFlags .= 'n'; + if ($this->all === TRUE) $modFlags .= 'r'; + if ($this->withSql !== '') $modFlags .= 'w'; + + return $modFlags; + } + +} + +class DiagnosticModel extends \RedBeanPHP\SimpleModel +{ + + private $logs = array(); + + public function open() + { + $this->logs[] = array( + 'action' => 'open', + 'data' => array( + 'id' => $this->id + ) + ); + } + + public function dispense() + { + $this->logs[] = array( + 'action' => 'dispense', + 'data' => array( + 'bean' => $this->bean + ) + ); + } + + public function update() + { + $this->logs[] = array( + 'action' => 'update', + 'data' => array( + 'bean' => $this->bean + ) + ); + } + + public function after_update() + { + $this->logs[] = array( + 'action' => 'after_update', + 'data' => array( + 'bean' => $this->bean + ) + ); + } + + public function delete() + { + $this->logs[] = array( + 'action' => 'delete', + 'data' => array( + 'bean' => $this->bean + ) + ); + } + + public function after_delete() + { + $this->logs[] = array( + 'action' => 'after_delete', + 'data' => array( + 'bean' => $this->bean + ) + ); + } + + public function getLogs() + { + return $this->logs; + } + + public function getLogActionCount( $action = NULL ) + { + if ( is_null( $action ) ) return count( $this->logs ); + $counter = 0; + foreach( $this->logs as $log ) { + if ( $log['action'] == $action ) $counter ++; + } + return $counter; + } + + public function clearLog() + { + return $this->logs = array(); + } + + public function getDataFromLog( $logIndex = 0, $property ) + { + return $this->logs[$logIndex]['data'][$property]; + } + +} + +class Model_Probe extends DiagnosticModel {}; + +define('REDBEAN_OODBBEAN_CLASS', '\DiagnosticBean'); diff --git a/vendor/gabordemooij/redbean/testing/helpers/functions.php b/vendor/gabordemooij/redbean/testing/helpers/functions.php new file mode 100644 index 000000000..cdde31e7f --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/helpers/functions.php @@ -0,0 +1,513 @@ +" . $text; + } else { + echo "\n" . $text; + } +} + +/** + * Tests whether a === b. The minimalistic core of this little + * unit test framework. + * + * @global integer $tests + * + * @param mixed $a value for A + * @param mixed $b value for B + */ +function asrt( $a, $b ) +{ + if ( $a === $b ) { + global $tests; + + $tests++; + + print( "[" . $tests . "]" ); + } else { + printtext( "FAILED TEST: EXPECTED $b BUT GOT: $a " ); + + fail(); + } +} + +/** + * called when a test is passed. prints the test number to the screen. + */ +function pass() +{ + global $tests; + + $tests++; + + print( "[" . $tests . "]" ); +} + +/** + * called when a test fails. shows debug info and exits. + */ +function fail() +{ + printtext( "FAILED TEST" ); + + debug_print_backtrace(); + + exit( 1 ); +} + +/** + * prints out the name of the current test pack. + * + * @param string $name name of the test pack + */ +function testpack( $name ) +{ + printtext( "\n\tSub testpack: " . $name . " \n\t" ); +} + +/** + * prints out the name of the current test pack. + * + * @param string $name name of the test pack + */ +function maintestpack( $name ) +{ + printtext( "\n\nTestpack: " . $name . " \n\t" ); +} + +/** + * Quickly resolves the formatted table name + */ +function tbl( $table ) +{ + return R::$writer->getFormattedTableName( $table ); +} + +/** + * Quickly resolves the formatted ID + */ +function ID( $table ) +{ + return R::$writer->getIDField( $table ); +} + +/** + * Emulates legacy function for use with older tests. + */ +function set1toNAssoc( $a, \RedBeanPHP\OODBBean $bean1, \RedBeanPHP\OODBBean $bean2 ) +{ + $type = $bean1->getMeta( "type" ); + + $a->clearRelations( $bean2, $type ); + $a->associate( $bean1, $bean2 ); + + if ( count( $a->related( $bean2, $type ) ) === 1 ) { + // return $this; + } else { + throw new \RedBeanPHP\RedException\SQL( "Failed to enforce 1-N Relation for $type " ); + } +} + +/** + * Returns all property values of beans as a + * comma separated string sorted. + * + * @param array $beans beans + * @param string $property name of the property + * + * @return string $values values + */ +function getList( $beans, $property ) +{ + $items = array(); + + foreach ( $beans as $bean ) { + $items[] = $bean->$property; + } + + sort( $items ); + + return implode( ",", $items ); +} + +/** + * Helper function to test IDs + * + * @param array $array array + */ +function testids( $array ) +{ + foreach ( $array as $key => $bean ) { + asrt( intval( $key ), intval( $bean->getID() ) ); + } +} + +/** + * Group modifier function. Tests random modifications + * of groups of beans. For use with tests that test N:1 relation mapping + * features. + * + * @param mixed $book3 book + * @param mixed $quotes quotes + * @param mixed $pictures pictures + * @param mixed $topics topics + */ +function modgr( $book3, $quotes, $pictures, $topics ) +{ + $key = array_rand( $quotes ); + + $quote = $quotes[$key]; + + $keyPic = array_rand( $pictures ); + + $picture = $pictures[$keyPic]; + + $keyTop = array_rand( $topics ); + + $topic = $topics[$keyTop]; + + if ( rand( 0, 1 ) ) { + $f = 0; + + foreach ( $book3->ownQuote as $z ) { + if ( $z->note == $quote->note ) { + $f = 1; + + break; + } + } + if ( !$f ) { + //echo "\n add a quote "; + + $book3->ownQuote[] = $quote; + } + } + + if ( rand( 0, 1 ) ) { + $f = 0; + + foreach ( $book3->ownPicture as $z ) { + if ( $z->note == $picture->note ) { + $f = 1; + + break; + } + } + if ( !$f ) { + // echo "\n add a picture "; + + $book3->ownPicture[] = $picture; + } + } + + if ( rand( 0, 1 ) ) { + $f = 0; + + foreach ( $book3->sharedTopic as $z ) { + if ( $z->note == $topic->note ) { + $f = 1; + + break; + } + } + + if ( !$f ) { + $book3->sharedTopic[] = $topic; + } + } + + if ( rand( 0, 1 ) && count( $book3->ownQuote ) > 0 ) { + $key = array_rand( $book3->ownQuote ); + + unset( $book3->ownQuote[$key] ); + } + + if ( rand( 0, 1 ) && count( $book3->ownPicture ) > 0 ) { + $key = array_rand( $book3->ownPicture ); + + unset( $book3->ownPicture[$key] ); + } + + if ( rand( 0, 1 ) && count( $book3->sharedTopic ) > 0 ) { + $key = array_rand( $book3->sharedTopic ); + + unset( $book3->sharedTopic[$key] ); + } + + if ( rand( 0, 1 ) && count( $book3->ownPicture ) > 0 ) { + $key = array_rand( $book3->ownPicture ); + + $book3->ownPicture[$key]->change = rand( 0, 100 ); + } + + if ( rand( 0, 1 ) && count( $book3->ownQuote ) > 0 ) { + $key = array_rand( $book3->ownQuote ); + + $book3->ownQuote[$key]->change = 'note ch ' . rand( 0, 100 ); + } + + if ( rand( 0, 1 ) && count( $book3->sharedTopic ) > 0 ) { + $key = array_rand( $book3->sharedTopic ); + + $book3->sharedTopic[$key]->change = rand( 0, 100 ); + } +} + +/** + * SetGet function, sets a value in a bean and retrieves it again + * after storage, useful for tests that want to make sure the same value + * that gets in, comes out again. + * + * @param mixed $val the value that needs to be preserved + * + * @return mixed $val the value as returned after storage-retrieval cycle. + */ +function setget( $val ) +{ + R::nuke(); + + $bean = R::dispense( "page" ); + + $bean->prop = $val; + + $id = R::store( $bean ); + + $bean = R::load( "page", $id ); + + return $bean->prop; +} + +/** + * Wrapper function to test BeanCan Server, does the boring + * plumming work. + * + * @param mixed $data Data for JSON-RPC request object + * @param mixed $params Parameters for JSON-RPC request object + * @param string $id Identification of JSON-RPC request to connect to response + * + * @return string $out Output JSON from BeanCan server. + */ +function fakeBeanCanServerRequest( $data, $params = NULL, $id = "1234", $whiteList = 'all' ) +{ + $j = array( + "jsonrpc" => "2.0", + "method" => $data, + "params" => $params, + "id" => $id + ); + + $can = new \RedBeanPHP\Plugin\BeanCan; + + $request = json_encode( $j ); + + $can->setWhitelist( $whiteList ); + + $out = $can->handleJSONRequest( $request ); + + return $out; +} + +/** + * Candy Cane Factory. Produces lots of candy canes. + * + * @return array $canes canes + */ +function candy_canes() +{ + $canes = R::dispense( 'cane', 10 ); + + $i = 0; + + foreach ( $canes as $k => $cane ) { + $canes[$k]->label = 'Cane No. ' . ( $i++ ); + } + + $canes[0]->cane = $canes[1]; + $canes[1]->cane = $canes[4]; + $canes[9]->cane = $canes[4]; + $canes[6]->cane = $canes[4]; + $canes[4]->cane = $canes[7]; + $canes[8]->cane = $canes[7]; + + return $canes; +} + +/** + * Returns an array containing the index names of all + * indexes on the specified table name. + * + * @param $tableNoQ table name without quotes or backticks + * + * @return array + */ +function getIndexes( $tableNoQ ) +{ + $writer = R::getWriter(); + + if ( ( $writer instanceof \RedBeanPHP\QueryWriter\MySQL ) || ( $writer instanceof \RedBeanPHP\QueryWriter\CUBRID ) ) { + $indexes = array(); + $list = R::getAll( "SHOW INDEX FROM `{$tableNoQ}`" ); + foreach( $list as $listItem ) { + $indexes[] = $listItem['Key_name']; + } + return $indexes; + } + + if ( ( $writer instanceof \RedBeanPHP\QueryWriter\SQLiteT ) ) { + $indexes = array(); + $list = R::getAll( " pragma index_list(`{$tableNoQ}`) " ); + foreach( $list as $listItem ) { + $indexes[] = $listItem['name']; + } + return $indexes; + } + + if ( ( $writer instanceof \RedBeanPHP\QueryWriter\PostgreSQL ) ) { + return R::getCol( " SELECT indexname FROM pg_indexes WHERE tablename = '{$tableNoQ}' AND schemaname = 'public' " ); + } + + return array(); +} + +function are_cols_in_unique( $type, $properties ) +{ + sort( $properties ); + $propertyFootprint = implode( ',', $properties ); + $uniques = get_uniques_for_type( $type ); + foreach( $uniques as $unique ) { + sort( $unique ); + $uniqueFootprint = implode( ',', $unique ); + if ( $uniqueFootprint === $propertyFootprint ) return TRUE; + } + return FALSE; +} + +function get_uniques_for_type( $type ) +{ + $list = array(); + $writer = R::getWriter(); + $adapter = R::getDatabaseAdapter(); + global $currentDriver; + switch( $currentDriver ) { + case 'mysql': + $table = $writer->esc( $type, TRUE ); + $columns = $adapter->get(' + SELECT + information_schema.key_column_usage.constraint_name, + information_schema.key_column_usage.column_name + FROM + information_schema.table_constraints + INNER JOIN information_schema.key_column_usage + ON ( + information_schema.table_constraints.constraint_name = information_schema.key_column_usage.constraint_name + AND information_schema.table_constraints.constraint_schema = information_schema.key_column_usage.constraint_schema + AND information_schema.table_constraints.constraint_catalog = information_schema.key_column_usage.constraint_catalog + ) + WHERE + information_schema.table_constraints.table_schema IN (SELECT DATABASE()) + AND information_schema.table_constraints.table_name = ? + AND information_schema.table_constraints.constraint_type = \'UNIQUE\' + ', array( $table ) ); + $uniques = array(); + foreach( $columns as $column ) { + if ( !isset( $uniques[ $column['constraint_name'] ] ) ) $uniques[ $column['constraint_name'] ] = array(); + $uniques[ $column['constraint_name'] ][] = $column['column_name']; + } + $list = $uniques; + break; + case 'pgsql': + $table = $writer->esc( $type, TRUE ); + $columns = $adapter->get(' + SELECT + information_schema.key_column_usage.constraint_name, + information_schema.key_column_usage.column_name + FROM + information_schema.table_constraints + INNER JOIN information_schema.key_column_usage + ON ( + information_schema.table_constraints.constraint_name = information_schema.key_column_usage.constraint_name + AND information_schema.table_constraints.constraint_schema = information_schema.key_column_usage.constraint_schema + AND information_schema.table_constraints.constraint_catalog = information_schema.key_column_usage.constraint_catalog + ) + WHERE + information_schema.table_constraints.table_catalog = current_database() + AND information_schema.key_column_usage.table_schema = ANY( current_schemas( FALSE ) ) + AND information_schema.table_constraints.table_name = ? + AND information_schema.table_constraints.constraint_type = \'UNIQUE\' + ', array( $table ) ); + $uniques = array(); + foreach( $columns as $column ) { + if ( !isset( $uniques[ $column['constraint_name'] ] ) ) $uniques[ $column['constraint_name'] ] = array(); + $uniques[ $column['constraint_name'] ][] = $column['column_name']; + } + $list= $uniques; + break; + case 'sqlite': + $uniques = array(); + $table = $writer->esc( $type, TRUE ); + $indexes = $adapter->get( "PRAGMA index_list({$table})" ); + foreach( $indexes as $index ) { + if ( $index['unique'] == 1 ) { + $info = $adapter->get( "PRAGMA index_info({$index['name']})" ); + if ( !isset( $uniques[$index['name']] ) ) $uniques[$index['name']] = array(); + foreach( $info as $piece ) { + $uniques[$index['name']][] = $piece['name']; + } + } + } + $list = $uniques; + break; + case 'CUBRID': + try { + $sqlCode = $adapter->get("SHOW CREATE TABLE `{$type}`"); + } catch ( \Exception $e ) { + $sqlCode = ''; + } + if (!isset($sqlCode[0])) return array(); + $matches = array(); + preg_match_all('/CONSTRAINT\s+\[([\w_]+)\]\s+UNIQUE\s+KEY\s+\(([^\)]+)\)/', $sqlCode[0]['CREATE TABLE'], $matches); + $list = array(); + if (!isset($matches[0])) return $list; + $max = count($matches[0]); + for($i = 0; $i < $max; $i++) { + $columns = explode(',', $matches[2][$i]); + foreach( $columns as $key => $column ) { + $columns[$key] = trim( $column, '[] '); + } + $list[ $matches[1][$i] ] = $columns; + } + break; + } + return $list; +} diff --git a/vendor/gabordemooij/redbean/testing/notes.txt b/vendor/gabordemooij/redbean/testing/notes.txt new file mode 100644 index 000000000..c3ea81040 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/notes.txt @@ -0,0 +1,8 @@ + +Test notes +========== + +* PostgreSQL tests perform a text-to-money cast test, make sure lc_monetary is set to en_US +in your postgres.conf +* PostgreSQL tests need the ossp extension, to enable this, install the postgres-contrib package and run SQL: CREATE EXTENSION "uuid-ossp"; +* XDebug is NOT required but recommended diff --git a/vendor/gabordemooij/redbean/testing/readme.txt b/vendor/gabordemooij/redbean/testing/readme.txt new file mode 100644 index 000000000..82d6feeda --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/readme.txt @@ -0,0 +1,11 @@ + + +To start testing add PHP Coverage lib: + + +testing/cli/phpcoverage.inc.php +testing/phpcoverage/ + + +Download from: +http://sourceforge.net/projects/phpcoverage/ \ No newline at end of file diff --git a/vendor/j7mbo/twitter-api-php/.gitignore b/vendor/j7mbo/twitter-api-php/.gitignore new file mode 100644 index 000000000..cdb3d2024 --- /dev/null +++ b/vendor/j7mbo/twitter-api-php/.gitignore @@ -0,0 +1,3 @@ +.idea/ +vendor/ +composer.lock \ No newline at end of file diff --git a/vendor/j7mbo/twitter-api-php/.travis.yml b/vendor/j7mbo/twitter-api-php/.travis.yml new file mode 100644 index 000000000..abac42465 --- /dev/null +++ b/vendor/j7mbo/twitter-api-php/.travis.yml @@ -0,0 +1,12 @@ +language: php +php: + - "5.3" + +before_install: + - composer self-update + +before_script: + - composer install + +script: + - phpunit --configuration phpunit.xml \ No newline at end of file diff --git a/vendor/j7mbo/twitter-api-php/README.md b/vendor/j7mbo/twitter-api-php/README.md new file mode 100644 index 000000000..1e7bdaa44 --- /dev/null +++ b/vendor/j7mbo/twitter-api-php/README.md @@ -0,0 +1,99 @@ +twitter-api-php +=============== + +Simple PHP Wrapper for Twitter API v1.1 calls + +[![Total Downloads](https://img.shields.io/packagist/dt/j7mbo/twitter-api-php.svg)](https://packagist.org/packages/j7mbo/twitter-api-php) +[![Build Status](https://travis-ci.org/J7mbo/twitter-api-php.svg?branch=master)](https://travis-ci.org/J7mbo/twitter-api-php) +[![Version](https://badge.fury.io/gh/j7mbo%2Ftwitter-api-php.svg)](https://packagist.org/packages/j7mbo/twitter-api-php) + +**[Changelog](https://github.com/J7mbo/twitter-api-php/wiki/Changelog)** || +**[Examples](https://github.com/J7mbo/twitter-api-php/wiki/Twitter-API-PHP-Wiki)** || +**[Wiki](https://github.com/J7mbo/twitter-api-php/wiki)** + +[Instructions in StackOverflow post here](http://stackoverflow.com/questions/12916539/simplest-php-example-retrieving-user-timeline-with-twitter-api-version-1-1/15314662#15314662) with examples. This post shows you how to get your tokens and more. +If you found it useful, please upvote / leave a comment! :) + +The aim of this class is simple. You need to: + +- Include the class in your PHP code +- [Create a twitter app on the twitter developer site](https://dev.twitter.com/apps/) +- Enable read/write access for your twitter app +- Grab your access tokens from the twitter developer site +- [Choose a twitter API URL to make the request to](https://dev.twitter.com/docs/api/1.1/) +- Choose either GET / POST (depending on the request) +- Choose the fields you want to send with the request (example: `array('screen_name' => 'usernameToBlock')`) + +You really can't get much simpler than that. The above bullet points are an example of how to use the class for a POST request to block a user, and at the bottom is an example of a GET request. + +Installation +------------ + +**Normally:** If you *don't* use composer, don't worry - just include TwitterAPIExchange.php in your application. + +```php +require_once('TwitterAPIExchange.php'); +``` + +**Via Composer:** + +```bash +composer require j7mbo/twitter-api-php +``` + +How To Use +---------- + +#### Set access tokens #### + +```php +$settings = array( + 'oauth_access_token' => "YOUR_OAUTH_ACCESS_TOKEN", + 'oauth_access_token_secret' => "YOUR_OAUTH_ACCESS_TOKEN_SECRET", + 'consumer_key' => "YOUR_CONSUMER_KEY", + 'consumer_secret' => "YOUR_CONSUMER_SECRET" +); +``` + +#### Choose URL and Request Method #### + +```php +$url = 'https://api.twitter.com/1.1/blocks/create.json'; +$requestMethod = 'POST'; +``` + +#### Choose POST fields (or PUT fields if you're using PUT) #### + +```php +$postfields = array( + 'screen_name' => 'usernameToBlock', + 'skip_status' => '1' +); +``` + +#### Perform the request! #### + +```php +$twitter = new TwitterAPIExchange($settings); +echo $twitter->buildOauth($url, $requestMethod) + ->setPostfields($postfields) + ->performRequest(); +``` + +GET Request Example +------------------- + +Set the GET field BEFORE calling buildOauth(); and everything else is the same: + +```php +$url = 'https://api.twitter.com/1.1/followers/ids.json'; +$getfield = '?screen_name=J7mbo'; +$requestMethod = 'GET'; + +$twitter = new TwitterAPIExchange($settings); +echo $twitter->setGetfield($getfield) + ->buildOauth($url, $requestMethod) + ->performRequest(); +``` + +That is it! Really simple, works great with the 1.1 API. Thanks to @lackovic10 and @rivers on SO! diff --git a/vendor/j7mbo/twitter-api-php/TwitterAPIExchange.php b/vendor/j7mbo/twitter-api-php/TwitterAPIExchange.php index 0cd385209..d6e3a585c 100755 --- a/vendor/j7mbo/twitter-api-php/TwitterAPIExchange.php +++ b/vendor/j7mbo/twitter-api-php/TwitterAPIExchange.php @@ -2,9 +2,9 @@ /** * Twitter-API-PHP : Simple PHP wrapper for the v1.1 API - * + * * PHP version 5.3.10 - * + * * @category Awesomeness * @package Twitter-API-PHP * @author James Mallison @@ -59,29 +59,37 @@ class TwitterAPIExchange */ public $requestMethod; + /** + * The HTTP status code from the previous request + * + * @var int + */ + protected $httpStatusCode; + /** * Create the API access object. Requires an array of settings:: * oauth access token, oauth access token secret, consumer key, consumer secret * These are all available by creating your own application on dev.twitter.com * Requires the cURL library * - * @throws \Exception When cURL isn't installed or incorrect settings parameters are provided + * @throws \RuntimeException When cURL isn't loaded + * @throws \InvalidArgumentException When incomplete settings parameters are provided * * @param array $settings */ public function __construct(array $settings) { - if (!in_array('curl', get_loaded_extensions())) + if (!function_exists('curl_init')) { - throw new Exception('You need to install cURL, see: http://curl.haxx.se/docs/install.html'); + throw new RuntimeException('TwitterAPIExchange requires cURL extension to be loaded, see: http://curl.haxx.se/docs/install.html'); } - + if (!isset($settings['oauth_access_token']) || !isset($settings['oauth_access_token_secret']) || !isset($settings['consumer_key']) || !isset($settings['consumer_secret'])) { - throw new Exception('Make sure you are passing in the correct parameters'); + throw new InvalidArgumentException('Incomplete settings passed to TwitterAPIExchange'); } $this->oauth_access_token = $settings['oauth_access_token']; @@ -101,11 +109,11 @@ class TwitterAPIExchange */ public function setPostfields(array $array) { - if (!is_null($this->getGetfield())) - { - throw new Exception('You can only choose get OR post fields.'); + if (!is_null($this->getGetfield())) + { + throw new Exception('You can only choose get OR post fields (post fields include put).'); } - + if (isset($array['status']) && substr($array['status'], 0, 1) === '@') { $array['status'] = sprintf("\0%s", $array['status']); @@ -118,33 +126,34 @@ class TwitterAPIExchange $value = ($value === true) ? 'true' : 'false'; } } - + $this->postfields = $array; - + // rebuild oAuth - if (isset($this->oauth['oauth_signature'])) { + if (isset($this->oauth['oauth_signature'])) + { $this->buildOauth($this->url, $this->requestMethod); } return $this; } - + /** * Set getfield string, example: '?screen_name=J7mbo' - * + * * @param string $string Get key and value pairs as string * * @throws \Exception - * + * * @return \TwitterAPIExchange Instance of self for method chaining */ public function setGetfield($string) { - if (!is_null($this->getPostfields())) - { - throw new Exception('You can only choose get OR post fields.'); + if (!is_null($this->getPostfields())) + { + throw new Exception('You can only choose get OR post / post fields.'); } - + $getfields = preg_replace('/^\?/', '', explode('&', $string)); $params = array(); @@ -157,31 +166,31 @@ class TwitterAPIExchange } } - $this->getfield = '?' . http_build_query($params); - + $this->getfield = '?' . http_build_query($params, '', '&'); + return $this; } - + /** * Get getfield string (simple getter) - * + * * @return string $this->getfields */ public function getGetfield() { return $this->getfield; } - + /** * Get postfields array (simple getter) - * + * * @return array $this->postfields */ public function getPostfields() { return $this->postfields; } - + /** * Build the Oauth object using params set in construct and additionals * passed to this method. For v1.1, see: https://dev.twitter.com/docs/api/1.1 @@ -195,16 +204,16 @@ class TwitterAPIExchange */ public function buildOauth($url, $requestMethod) { - if (!in_array(strtolower($requestMethod), array('post', 'get'))) + if (!in_array(strtolower($requestMethod), array('post', 'get', 'put', 'delete'))) { - throw new Exception('Request method must be either POST or GET'); + throw new Exception('Request method must be either POST, GET or PUT or DELETE'); } - + $consumer_key = $this->consumer_key; $consumer_secret = $this->consumer_secret; $oauth_access_token = $this->oauth_access_token; $oauth_access_token_secret = $this->oauth_access_token_secret; - + $oauth = array( 'oauth_consumer_key' => $consumer_key, 'oauth_nonce' => time(), @@ -213,9 +222,9 @@ class TwitterAPIExchange 'oauth_timestamp' => time(), 'oauth_version' => '1.0' ); - + $getfield = $this->getGetfield(); - + if (!is_null($getfield)) { $getfields = str_replace('?', '', explode('&', $getfield)); @@ -231,7 +240,7 @@ class TwitterAPIExchange } } } - + $postfields = $this->getPostfields(); if (!is_null($postfields)) { @@ -244,22 +253,22 @@ class TwitterAPIExchange $composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret); $oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true)); $oauth['oauth_signature'] = $oauth_signature; - - $this->url = $url; + + $this->url = $url; $this->requestMethod = $requestMethod; - $this->oauth = $oauth; - + $this->oauth = $oauth; + return $this; } - + /** * Perform the actual data retrieval from the API - * + * * @param boolean $return If true, returns data. This is left in for backward compatibility reasons * @param array $curlOptions Additional Curl options for this request * * @throws \Exception - * + * * @return string json If $return param is true, returns json data. */ public function performRequest($return = true, $curlOptions = array()) @@ -274,17 +283,22 @@ class TwitterAPIExchange $getfield = $this->getGetfield(); $postfields = $this->getPostfields(); - $options = array( + if (in_array(strtolower($this->requestMethod), array('put', 'delete'))) + { + $curlOptions[CURLOPT_CUSTOMREQUEST] = $this->requestMethod; + } + + $options = $curlOptions + array( CURLOPT_HTTPHEADER => $header, CURLOPT_HEADER => false, CURLOPT_URL => $this->url, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, - ) + $curlOptions; + ); if (!is_null($postfields)) { - $options[CURLOPT_POSTFIELDS] = http_build_query($postfields); + $options[CURLOPT_POSTFIELDS] = http_build_query($postfields, '', '&'); } else { @@ -298,6 +312,8 @@ class TwitterAPIExchange curl_setopt_array($feed, $options); $json = curl_exec($feed); + $this->httpStatusCode = curl_getinfo($feed, CURLINFO_HTTP_CODE); + if (($error = curl_error($feed)) !== '') { curl_close($feed); @@ -309,17 +325,17 @@ class TwitterAPIExchange return $json; } - + /** * Private method to generate the base string used by cURL - * + * * @param string $baseURI * @param string $method * @param array $params - * + * * @return string Built base string */ - private function buildBaseString($baseURI, $method, $params) + private function buildBaseString($baseURI, $method, $params) { $return = array(); ksort($params); @@ -328,22 +344,22 @@ class TwitterAPIExchange { $return[] = rawurlencode($key) . '=' . rawurlencode($value); } - - return $method . "&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $return)); + + return $method . "&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $return)); } - + /** * Private method to generate authorization header used by cURL - * + * * @param array $oauth Array of oauth data generated by buildOauth() - * + * * @return string $return Header used by cURL for request - */ + */ private function buildAuthorizationHeader(array $oauth) { $return = 'Authorization: OAuth '; $values = array(); - + foreach($oauth as $key => $value) { if (in_array($key, array('oauth_consumer_key', 'oauth_nonce', 'oauth_signature', @@ -351,7 +367,7 @@ class TwitterAPIExchange $values[] = "$key=\"" . rawurlencode($value) . "\""; } } - + $return .= implode(', ', $values); return $return; } @@ -381,4 +397,14 @@ class TwitterAPIExchange return $this->buildOauth($url, $method)->performRequest(true, $curlOptions); } + + /** + * Get the HTTP status code for the previous request + * + * @return integer + */ + public function getHttpStatusCode() + { + return $this->httpStatusCode; + } } diff --git a/vendor/j7mbo/twitter-api-php/composer.json b/vendor/j7mbo/twitter-api-php/composer.json index 0d99c9908..2002abea6 100644 --- a/vendor/j7mbo/twitter-api-php/composer.json +++ b/vendor/j7mbo/twitter-api-php/composer.json @@ -22,7 +22,7 @@ } ], "autoload": { - "files": ["TwitterAPIExchange.php"] + "classmap": ["TwitterAPIExchange.php"] }, "extra": { "branch-alias": { diff --git a/vendor/j7mbo/twitter-api-php/index.php b/vendor/j7mbo/twitter-api-php/index.php new file mode 100755 index 000000000..ab0f79074 --- /dev/null +++ b/vendor/j7mbo/twitter-api-php/index.php @@ -0,0 +1,37 @@ + "", + 'oauth_access_token_secret' => "", + 'consumer_key' => "", + 'consumer_secret' => "" +); + +/** URL for REST request, see: https://dev.twitter.com/docs/api/1.1/ **/ +$url = 'https://api.twitter.com/1.1/blocks/create.json'; +$requestMethod = 'POST'; + +/** POST fields required by the URL above. See relevant docs as above **/ +$postfields = array( + 'screen_name' => 'usernameToBlock', + 'skip_status' => '1' +); + +/** Perform a POST request and echo the response **/ +$twitter = new TwitterAPIExchange($settings); +echo $twitter->buildOauth($url, $requestMethod) + ->setPostfields($postfields) + ->performRequest(); + +/** Perform a GET request and echo the response **/ +/** Note: Set the GET field BEFORE calling buildOauth(); **/ +$url = 'https://api.twitter.com/1.1/followers/ids.json'; +$getfield = '?screen_name=J7mbo'; +$requestMethod = 'GET'; +$twitter = new TwitterAPIExchange($settings); +echo $twitter->setGetfield($getfield) + ->buildOauth($url, $requestMethod) + ->performRequest(); diff --git a/vendor/j7mbo/twitter-api-php/phpunit.xml b/vendor/j7mbo/twitter-api-php/phpunit.xml new file mode 100644 index 000000000..ee5a42bf7 --- /dev/null +++ b/vendor/j7mbo/twitter-api-php/phpunit.xml @@ -0,0 +1,18 @@ + + + + + ./test/ + + + \ No newline at end of file diff --git a/vendor/j7mbo/twitter-api-php/test/TwitterAPIExchangeTest.php b/vendor/j7mbo/twitter-api-php/test/TwitterAPIExchangeTest.php new file mode 100644 index 000000000..24121d63b --- /dev/null +++ b/vendor/j7mbo/twitter-api-php/test/TwitterAPIExchangeTest.php @@ -0,0 +1,338 @@ +getConstants() as $key => $value) + { + $settings[strtolower($key)] = $value; + } + + $this->exchange = new \TwitterAPIExchange($settings); + } + + /** + * GET statuses/mentions_timeline + * + * @see https://dev.twitter.com/rest/reference/get/statuses/mentions_timeline + */ + public function testStatusesMentionsTimeline() + { + $url = 'https://api.twitter.com/1.1/statuses/mentions_timeline.json'; + $method = 'GET'; + $params = '?max_id=595150043381915648'; + + $data = $this->exchange->request($url, $method, $params); + $expected = "@j7php Test mention"; + + $this->assertContains($expected, $data); + } + + /** + * GET statuses/user_timeline + * + * @see https://dev.twitter.com/rest/reference/get/statuses/user_timeline + */ + public function testStatusesUserTimeline() + { + $url = 'https://api.twitter.com/1.1/statuses/user_timeline.json'; + $method = 'GET'; + $params = '?user_id=3232926711'; + + $data = $this->exchange->request($url, $method, $params); + $expected = "Test Tweet"; + + $this->assertContains($expected, $data); + } + + /** + * GET statuses/home_timeline + * + * @see https://dev.twitter.com/rest/reference/get/statuses/home_timeline + */ + public function testStatusesHomeTimeline() + { + $url = 'https://api.twitter.com/1.1/statuses/home_timeline.json'; + $method = 'GET'; + $params = '?user_id=3232926711&max_id=756123701888839681'; + + $data = $this->exchange->request($url, $method, $params); + $expected = "Test Tweet"; + + $this->assertContains($expected, $data); + } + + /** + * GET statuses/retweets_of_me + * + * @see https://dev.twitter.com/rest/reference/get/statuses/retweets_of_me + */ + public function testStatusesRetweetsOfMe() + { + $url = 'https://api.twitter.com/1.1/statuses/retweets_of_me.json'; + $method = 'GET'; + + $data = $this->exchange->request($url, $method); + $expected = 'travis CI and tests'; + + $this->assertContains($expected, $data); + } + + /** + * GET statuses/retweets/:id + * + * @see https://api.twitter.com/1.1/statuses/retweets/:id.json + */ + public function testStatusesRetweetsOfId() + { + $url = 'https://api.twitter.com/1.1/statuses/retweets/595155660494471168.json'; + $method = 'GET'; + + $data = $this->exchange->request($url, $method); + $expected = 'travis CI and tests'; + + $this->assertContains($expected, $data); + } + + /** + * GET Statuses/Show/:id + * + * @see https://dev.twitter.com/rest/reference/get/statuses/show/:id + */ + public function testStatusesShowId() + { + $url = 'https://api.twitter.com/1.1/statuses/show.json'; + $method = 'GET'; + $params = '?id=595155660494471168'; + + $data = $this->exchange->request($url, $method, $params); + $expected = 'travis CI and tests'; + + $this->assertContains($expected, $data); + } + + /** + * POST media/upload + * + * @see https://dev.twitter.com/rest/reference/post/media/upload + * + * @note Uploaded unattached media files will be available for attachment to a tweet for 60 minutes + */ + public function testMediaUpload() + { + $file = file_get_contents(__DIR__ . '/img.png'); + $data = base64_encode($file); + + $url = 'https://upload.twitter.com/1.1/media/upload.json'; + $method = 'POST'; + $params = array( + 'media_data' => $data + ); + + $data = $this->exchange->request($url, $method, $params); + $expected = 'image\/png'; + + $this->assertContains($expected, $data); + + /** Store the media id for later **/ + $data = @json_decode($data, true); + + $this->assertArrayHasKey('media_id', is_array($data) ? $data : array()); + + self::$mediaId = $data['media_id']; + } + + /** + * POST statuses/update + * + * @see https://dev.twitter.com/rest/reference/post/statuses/update + */ + public function testStatusesUpdate() + { + if (!self::$mediaId) + { + $this->fail('Cannot /update status because /upload failed'); + } + + $url = 'https://api.twitter.com/1.1/statuses/update.json'; + $method = 'POST'; + $params = array( + 'status' => 'TEST TWEET TO BE DELETED' . rand(), + 'possibly_sensitive' => false, + 'media_ids' => self::$mediaId + ); + + $data = $this->exchange->request($url, $method, $params); + $expected = 'TEST TWEET TO BE DELETED'; + + $this->assertContains($expected, $data); + + /** Store the tweet id for testStatusesDestroy() **/ + $data = @json_decode($data, true); + + $this->assertArrayHasKey('id_str', is_array($data) ? $data : array()); + + self::$tweetId = $data['id_str']; + + /** We've done this now, yay **/ + self::$mediaId = null; + } + + /** + * POST statuses/destroy/:id + * + * @see https://dev.twitter.com/rest/reference/post/statuses/destroy/:id + */ + public function testStatusesDestroy() + { + if (!self::$tweetId) + { + $this->fail('Cannot /destroy status because /update failed'); + } + + $url = sprintf('https://api.twitter.com/1.1/statuses/destroy/%d.json', self::$tweetId); + $method = 'POST'; + $params = array( + 'id' => self::$tweetId + ); + + $data = $this->exchange->request($url, $method, $params); + $expected = 'TEST TWEET TO BE DELETED'; + + $this->assertContains($expected, $data); + + /** We've done this now, yay **/ + self::$tweetId = null; + } + + /** + * GET search/tweets + * + * @see https://dev.twitter.com/rest/reference/get/search/tweets + */ + public function testCanSearchWithHashTag() + { + $url = 'https://api.twitter.com/1.1/search/tweets.json'; + $method = 'GET'; + $params = '?q=#twitter'; + + $data = $this->exchange->request($url, $method, $params); + $data = (array)@json_decode($data, true); + + $this->assertNotCount(1, $data); + } + + /** + * Test to check that options passed to curl do not cause any issues + */ + public function testAdditionalCurlOptions() + { + $url = 'https://api.twitter.com/1.1/search/tweets.json'; + $method = 'GET'; + $params = '?q=#twitter'; + + $data = $this->exchange->request($url, $method, $params, array(CURLOPT_ENCODING => '')); + $data = (array)@json_decode($data, true); + + $this->assertNotCount(1, $data); + } + + /** + * Apparently users/lookup was not working with a POST + * + * @see https://github.com/J7mbo/twitter-api-php/issues/70 + */ + public function testIssue70() + { + $url = 'https://api.twitter.com/1.1/users/lookup.json'; + $method = 'POST'; + $params = array( + 'screen_name' => 'lifehacker' + ); + + $data = $this->exchange->request($url, $method, $params); + $this->assertContains('created_at', $data); + } + + /** + * Thanks to Sharath at eywamedia for bringint this to my attention + */ + public function testPut() + { + $url = 'https://ads-api.twitter.com/1/accounts/hkk5/campaigns/8zwv'; + $method = 'PUT'; + $params = array ( + 'name' => 'Important', + 'paused' => true + ); + + $data = $this->exchange->request($url, $method, $params); + + /** If we get this back, then it looks like we can support PUT! :-) **/ + $this->assertContains('UNAUTHORIZED_CLIENT_APPLICATION', $data); + } + + public function testDelete() + { + $params = array(); + + // foobaa is sandbox Ads account id + $url = 'https://ads-api-sandbox.twitter.com/1/accounts/foobaa'; + $method = 'DELETE'; + + $data = $this->exchange->request($url, $method, $params); + + $this->assertContains('UNAUTHORIZED_CLIENT_APPLICATION', $data); + } +} diff --git a/vendor/j7mbo/twitter-api-php/test/img.png b/vendor/j7mbo/twitter-api-php/test/img.png new file mode 100644 index 000000000..85f8ce31a Binary files /dev/null and b/vendor/j7mbo/twitter-api-php/test/img.png differ diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Auth.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Auth.php deleted file mode 100644 index 9cce45cc3..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Auth.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @license http://opensource.org/licenses/mit-license.php The MIT License - */ - -namespace Instagram; - -/** - * Auth class - * - * Handles authentication - * - * {@link https://github.com/galen/PHP-Instagram-API#authentication} - * {@link https://github.com/galen/PHP-Instagram-API/blob/master/Examples/_auth.php} - */ -class Auth { - - /** - * Configuration array - * - * Contains a default client and proxy - * - * client_id: These three items are required for authorization - * redirect_uri: URL that the Instagram API shoudl redirect to - * grant_type: Grant type from the Instagram API. Only authorization_code is accepted right now. - * scope: {@link http://instagram.com/developer/auth/#scope} - * display: Pass in "touch" if you'd like your authenticating users to see a mobile-optimized - * version of the authenticate page and the sign-in page. - * - * @var array - * @access protected - */ - protected $config = array( - 'client_id' => '', - 'client_secret' => '', - 'redirect_uri' => '', - 'grant_type' => 'authorization_code', - 'scope' => array( 'basic' ), - 'display' => '' - ); - - /** - * Constructor - * - * @param array $config Configuration array - * @param \Instagram\Net\ClientInterface $client Client object used to connect to the API - * @access public - */ - public function __construct( array $config = null, \Instagram\Net\ClientInterface $client = null ) { - $this->config = (array) $config + $this->config; - $this->proxy = new \Instagram\Core\Proxy( $client ? $client : new \Instagram\Net\CurlClient ); - } - - /** - * Authorize - * - * Redirects the user to the Instagram authorization url - * @access public - */ - public function authorize() { - header( - sprintf( - 'Location:https://api.instagram.com/oauth/authorize/?client_id=%s&redirect_uri=%s&response_type=code&scope=%s', - $this->config['client_id'], - $this->config['redirect_uri'], - implode( '+', $this->config['scope'] ) - ) - ); - exit; - } - - /** - * Get the access token - * - * POSTs to the Instagram API and obtains and access key - * - * @param string $code Code supplied by Instagram - * @return string Returns the access token - * @throws \Instagram\Core\ApiException - * @access public - */ - public function getAccessToken( $code ) { - $post_data = array( - 'client_id' => $this->config['client_id'], - 'client_secret' => $this->config['client_secret'], - 'grant_type' => $this->config['grant_type'], - 'redirect_uri' => $this->config['redirect_uri'], - 'code' => $code - ); - $response = $this->proxy->getAccessToken( $post_data ); - if ( isset( $response->getRawData()->access_token ) ) { - return $response->getRawData()->access_token; - } - throw new \Instagram\Core\ApiException( $response->getErrorMessage(), $response->getErrorCode(), $response->getErrorType() ); - } - - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/CollectionAbstract.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/CollectionAbstract.php deleted file mode 100644 index ae6d9838f..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/CollectionAbstract.php +++ /dev/null @@ -1,208 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Collection; - -/** - * Abstract Collection - * - * All Collections extend this class - */ -abstract class CollectionAbstract implements \IteratorAggregate, \ArrayAccess, \Countable { - - /** - * Holds the pagination data for the collection - * - * @var StdClass - * @access protected - */ - protected $pagination; - - /** - * Holds the data for the collection - * - * @var array - * @access protected - */ - protected $data = array(); - - /** - * Holds the position for the iterator - * - * @var integer - * @access protected - */ - protected $position; - - /** - * Constructor - * - * Sets the data and child object's proxies - * - * @param StdClass $data Data from the API - * @param \Instagram\Core\Proxy $proxy Proxy to pass on to teh collection's objects - * @access public - */ - public function __construct( $raw_data = null, \Instagram\Core\Proxy $proxy = null ) { - if ( $raw_data ) { - $this->setData( $raw_data ); - } - if ( $proxy ) { - $this->setProxies( $proxy ); - } - } - - /** - * Set the collections data - * - * @param StdClass $data Data from the API - * @access public - */ - public abstract function setData( $raw_data ); - - /** - * Get the collection's data - * - * @return StdClass - * @access public - */ - public function getData() { - return $this->data; - } - - /** - * Get a collection item - * - * @param int $position Item to retrieve, starting at 0 - * @return mixed Returns the collection item at the position - * @access public - */ - public function getItem( $position ) { - return isset( $this->data[$position] ) ? $this->data[$position] : null; - } - - /** - * Get a slice of the collection - * - * @param int $offset Where to start the slice - * @param int $length Length of the slice - * @return array Returns a slice of the array - * @access public - */ - public function getSlice( $offset, $length ) { - return array_slice( $this->data, $offset, $length ); - } - - /** - * Add data - * - * Add data from another collection the this collection - * - * @param \Instagram\Collection\CollectionAbstract $object Object to add the data of - * @access public - */ - public function addData( \Instagram\Collection\CollectionAbstract $object ) { - $this->data = array_merge( $this->data, $object->getData() ); - } - - /** - * Convert the collection's objects - * - * Child classes use this to turn the objects into the correct class - * - * @param string $object - * @access protected - */ - protected function convertData( $object ) { - $this->data = array_map( - function( $c ) use( $object ) { - return new $object( $c ); - }, - $this->data - ); - } - - /** - * Set object proxies - * - * Sets all the child object's proxies - * - * @param \Instagram\Core\Proxy $proxy - * @access public - */ - public function setProxies( \Instagram\Core\Proxy $proxy ) { - foreach( $this->data as $object ) { - $object->setProxy( $proxy ); - } - } - - /** - * Implode the collection - * - * Implode the collection into a string - * - * Example - Get a media's tags into a comma delimited string - * - * $media->getTags()->implode( - * function( $t ){ return sprintf( '#%1$s', $t ); } - * ) - * - * @param Closure $callback Function to run on the collection - * @param string $sep Implode separator - * @access public - */ - public function implode( \Closure $callback = null, $sep = ', ' ) { - if ( !count( $this->getData() ) ) { - return null; - } - if ( !$callback ) { - $callback = function( $i ){ return $i->__toString(); }; - } - foreach( $this->getData() as $item ) { - $items[] = $callback( $item ); - } - return implode( $sep, $items ); - } - - /** - * IteratorAggregate - * - * {@link http://us2.php.net/manual/en/class.iteratoraggregate.php} - */ - public function getIterator(){ - return new \ArrayIterator( $this->data ); - } - - /** - * ArrayAccess - * - * {@link http://us2.php.net/manual/en/class.arrayaccess.php} - */ - public function offsetExists( $offset ) { - return isset( $this->data[$offset] ); - } - public function offsetGet( $offset ) { - return $this->data[$offset]; - } - public function offsetSet( $offset, $value ) { - trigger_error( "You can't set collection data"); - } - public function offsetUnset( $offset ) { - trigger_error( "You can't unset collection data" ); - } - - /** - * Countable - * - * {@link http://us2.php.net/manual/en/class.countable.php} - */ - public function count() { - return count( $this->data ); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/CommentCollection.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/CommentCollection.php deleted file mode 100644 index d6a2e31b5..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/CommentCollection.php +++ /dev/null @@ -1,29 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Collection; - -/** - * Comment Collection - * - * Holds a collection of comments - */ -class CommentCollection extends \Instagram\Collection\CollectionAbstract { - - /** - * Set the collection data - * - * @param StdClass $raw_data - * @access public - */ - public function setData( $raw_data ) { - $this->data = $raw_data->data; - $this->convertData( '\Instagram\Comment' ); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/LikedMediaCollection.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/LikedMediaCollection.php deleted file mode 100644 index b76cbcb59..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/LikedMediaCollection.php +++ /dev/null @@ -1,38 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Collection; - -/** - * Liked Media Collection - * - * Holds a collection of liked media - */ -class LikedMediaCollection extends \Instagram\Collection\MediaCollection { - - /** - * Get the next max like ID - * - * @return string - * @access public - */ - public function getNextMaxLikeId() { - return isset( $this->pagination->next_max_like_id ) ? $this->pagination->next_max_like_id : null; - } - - /** - * Get the next max like ID - * - * @return string - * @access public - */ - public function getNext() { - return $this->getNextMaxLikeId(); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/LocationCollection.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/LocationCollection.php deleted file mode 100644 index 82ff99a81..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/LocationCollection.php +++ /dev/null @@ -1,29 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Collection; - -/** - * Comment Collection - * - * Holds a collection of comments - */ -class LocationCollection extends \Instagram\Collection\CollectionAbstract { - - /** - * Set the collection data - * - * @param StdClass $raw_data - * @access public - */ - public function setData( $raw_data ) { - $this->data = $raw_data->data; - $this->convertData( '\Instagram\Location' ); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/MediaCollection.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/MediaCollection.php deleted file mode 100644 index 593ea2e83..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/MediaCollection.php +++ /dev/null @@ -1,67 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Collection; - -/** - * Media Collection - * - * Holds a collection of media - */ -class MediaCollection extends \Instagram\Collection\CollectionAbstract { - - /** - * Set the collection data - * - * @param StdClass $raw_data - * @access public - */ - public function setData( $raw_data ) { - $this->data = $raw_data->data; - $this->pagination = isset( $raw_data->pagination ) ? $raw_data->pagination : null; - $this->convertData( '\Instagram\Media' ); - } - - /** - * Get next max id - * - * Get the next max id for use in pagination - * - * @return string Returns the next max id - * @access public - */ - public function getNextMaxId() { - return isset( $this->pagination->next_max_id ) ? $this->pagination->next_max_id : null; - } - - /** - * Get next url - * - * Get the API url for the next page of media - * You shouldn't need to use this - * - * @return string Returns the next url - * @access public - */ - public function getNextUrl() { - return isset( $this->pagination->next_url ) ? $this->pagination->next_url : null; - } - - /** - * Get next max id - * - * Get the next max id for use in pagination - * - * @return string Returns the next max id - * @access public - */ - public function getNext() { - return $this->getNextMaxId(); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/MediaSearchCollection.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/MediaSearchCollection.php deleted file mode 100644 index e0d2fadfc..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/MediaSearchCollection.php +++ /dev/null @@ -1,62 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Collection; - -/** - * Media Search Collection - * - * Holds a collection of searched media - */ -class MediaSearchCollection extends \Instagram\Collection\CollectionAbstract { - - /** - * Next max timestamp for use in pagination - * - * @var int - * @access protected - */ - protected $next_max_timestamp; - - /** - * Set the collection data - * - * @param StdClass $raw_data - * @access public - */ - public function setData( $raw_data ) { - $this->data = $raw_data->data; - $this->convertData( '\Instagram\Media' ); - $this->next_max_timestamp = count( $this->data ) ? $this->data[ count( $this->data )-1 ]->getCreatedTime() : null; - } - - /** - * Get next max timestamp - * - * Get the next max timestamp for use in pagination - * - * @return string Returns the next max timestamp - * @access public - */ - public function getNextMaxTimeStamp() { - return $this->next_max_timestamp; - } - - /** - * Get next max timestamp - * - * Get the next max timestamp for use in pagination - * - * @return string Returns the next max timestamp - * @access public - */ - public function getNext() { - return $this->getNextMaxTimeStamp(); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/TagCollection.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/TagCollection.php deleted file mode 100644 index 78a8d0fb4..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/TagCollection.php +++ /dev/null @@ -1,48 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Collection; - -/** - * Tag Collection - * - * Holds a collection of tags - */ -class TagCollection extends \Instagram\Collection\CollectionAbstract { - - /** - * Set the collection data - * - * @param StdClass $raw_data - * @access public - */ - public function setData( $raw_data ) { - if ( isset( $raw_data->data ) ) { - $this->data = $raw_data->data; - } - elseif( is_array( $raw_data ) ) { - $this->data = array_map( function( $t ){ return (object)array( 'name' => $t ); }, $raw_data ); - } - $this->convertData( '\Instagram\Tag' ); - } - - /** - * Get an array of tag names - * - * @return array Returns an array of tags - * @access public - */ - public function toArray() { - $tags = array(); - foreach( $this->data as $tag ) { - $tags[] = $tag->getName(); - } - return $tags; - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/TagMediaCollection.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/TagMediaCollection.php deleted file mode 100644 index 269c0c247..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/TagMediaCollection.php +++ /dev/null @@ -1,57 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Collection; - -/** - * Tag Media Collection - * - * Holds a collection of media associated with a tag - */ -class TagMediaCollection extends \Instagram\Collection\MediaCollection { - - /** - * Get min tag id - * - * Get the minimum tag id. - * if you're using the Realtime API and fetch media from /media/recent for Tags, - * you should save the min_tag_id and pass it in next time you hit that endpoint - * in response to a realtime push; you'll receive all media since the last time you checked. - * - * @return string Return the min tag id - * @access public - */ - public function getMinTagId() { - return isset( $this->pagination->min_tag_id ) ? $this->pagination->min_tag_id : null; - } - - /** - * Get next max tag id - * - * Get the next max tag id for use in pagination - * - * @return string Returns the next max tag id - * @access public - */ - public function getNextMaxTagId() { - return isset( $this->pagination->next_max_tag_id ) ? $this->pagination->next_max_tag_id : null; - } - - /** - * Get next max tag id - * - * Get the next max tag id for use in pagination - * - * @return string Returns the next max tag id - * @access public - */ - public function getNext() { - return $this->getNextMaxTagId(); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/UserCollection.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/UserCollection.php deleted file mode 100644 index a558133ba..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Collection/UserCollection.php +++ /dev/null @@ -1,54 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Collection; - -/** - * User Collection - * - * Holds a collection of users - */ -class UserCollection extends \Instagram\Collection\CollectionAbstract { - - /** - * Set the collection data - * - * @param StdClass $raw_data - * @access public - */ - public function setData( $raw_data ) { - $this->data = $raw_data->data; - $this->pagination = isset( $raw_data->pagination ) ? $raw_data->pagination : null; - $this->convertData( '\Instagram\User' ); - } - - /** - * Get next max cursor - * - * Get the next max cursor for use in pagination - * - * @return string Returns the next max cursor - * @access public - */ - public function getNextCursor() { - return isset( $this->pagination->next_cursor ) && !empty( $this->pagination->next_cursor ) ? $this->pagination->next_cursor : null; - } - - /** - * Get next max cursor - * - * Get the next max cursor for use in pagination - * - * @return string Returns the next max cursor - * @access public - */ - public function getNext() { - return $this->getNextCursor(); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Comment.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Comment.php deleted file mode 100644 index 9a658d7c6..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Comment.php +++ /dev/null @@ -1,82 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram; - -use \Instagram\User; - -/** - * Comment class - * - * @see \Instagram\CurrentUser::addMediaComment() - * @see \Instagram\CurrentUser::deleteMediaComment() - * @see \Instagram\Media::getCaption() - * @see \Instagram\Media::getComments() - */ -class Comment extends \Instagram\Core\BaseObjectAbstract { - - /** - * Cached user - * - * @var \Instagram\User - */ - protected $user = null; - - /** - * Get comment creation time - * - * @param $format Time format {@link http://php.net/manual/en/function.date.php} - * @return string Returns the creation time with optional formatting - * @access public - */ - public function getCreatedTime( $format = null ) { - if ( $format ) { - $date = date( $format, $this->data->created_time ); - } - else { - $date = $this->data->created_time; - } - return $date; - } - - /** - * Get the comment text - * - * @access public - * @return string - */ - public function getText() { - return $this->data->text; - } - - /** - * Get the comment's user - * - * @access public - * @return \Instagram\User - */ - public function getUser() { - if ( !$this->user ) { - $this->user = new User( $this->data->from, $this->proxy ); - } - return $this->user; - } - - /** - * Magic toString method - * - * Return the comment text - * - * @access public - * @return string - */ - public function __toString() { - return $this->getText(); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Core/ApiAuthException.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Core/ApiAuthException.php deleted file mode 100644 index b2440749f..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Core/ApiAuthException.php +++ /dev/null @@ -1,18 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Core; - -/** - * API Auth Exception - * - * This exception type will be thrown if the access token you are using is no longer valid. - * - * {@link https://github.com/galen/PHP-Instagram-API/blob/master/Examples/index.php#L39} - */ -class ApiAuthException extends \Instagram\Core\ApiException {} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Core/ApiException.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Core/ApiException.php deleted file mode 100644 index ccb250b42..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Core/ApiException.php +++ /dev/null @@ -1,59 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Core; - -/** - * API Exception - * - * This exception type will be thrown for any API error - * - * {@link https://github.com/galen/PHP-Instagram-API/blob/master/Examples/index.php#L48} - */ -class ApiException extends \Exception { - - /** - * Invalid APU URI - */ - const TYPE_NOT_ALLOWED = 'APINotAllowedError'; - - /** - * Authorization error - */ - const TYPE_OAUTH = 'OAuthAccessTokenException'; - - /** - * Type of error - * - * @var string - */ - protected $type; - - /** - * Constructor - * - * @param string $message Error message - * @param integer $code Error code - * @param string $type Error type - * @param Exception $previous Previous exception - */ - public function __construct( $message = null, $code = 0, $type = null, \Exception $previous = null ) { - $this->type = $type; - parent::__construct( $message, $code, $previous ); - } - - /** - * Get error type - * - * @return string Get teh error type - */ - public function getType() { - return $this->type; - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Core/BaseObjectAbstract.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Core/BaseObjectAbstract.php deleted file mode 100644 index 8d589e874..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Core/BaseObjectAbstract.php +++ /dev/null @@ -1,113 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Core; - -/** - * Base object that all objects extend from - * - * Provides core functionality - */ -abstract class BaseObjectAbstract { - - /** - * Object data - * - * @var StdClass - * @access protected - */ - protected $data; - - /** - * Proxy object that does all the API heavy lifting - * - * @var \Instagram\Core\Proxy - * @access protected - */ - protected $proxy = null; - - /** - * Get the ID returned from the API - * - * @return string - * @access public - */ - public function getId() { - return $this->data->id; - } - - /** - * Get the API ID - * - * Some API objects don't have IDs (tags, some locations ) - * Those objects define their own getId() methods to return a psuedo ID - * Tags = tag name, ID-less locations return null - * - * @return string Returns the ID - * @access public - */ - public function getApiId() { - return $this->getId(); - } - - /** - * Constructor - * - * @param StdClass $data Object's data - * @param \Instagram\Core\Proxy $proxy Object's proxy - * @access public - */ - public function __construct( $data, \Instagram\Core\Proxy $proxy = null ) { - $this->setData( $data ); - $this->proxy = $proxy; - } - - /** - * Set the object's data - * - * @param StdClass $data Object data - * @access public - */ - public function setData( $data ) { - $this->data = $data; - } - - /** - * Get the object's data - * - * @return Stdclass Returns the object's data - * @access public - */ - public function getData() { - return $this->data; - } - - /** - * Magic method to get data - * - * This may be removed in future versions - * - * @param string $var Variable ot get from the data - * @return mixed Returns the variable or null - * @access public - */ - public function __get( $var ) { - return isset( $this->data->$var ) ? $this->data->$var : null; - } - - /** - * Set the object's proxy - * - * @param \Instagram\Core\Proxy $proxy Proxy object - * @access public - */ - public function setProxy( \Instagram\Core\Proxy $proxy ) { - $this->proxy = $proxy; - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Core/Proxy.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Core/Proxy.php deleted file mode 100644 index 22eb5ddb4..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Core/Proxy.php +++ /dev/null @@ -1,564 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Core; - -/** - * Proxy - * - * This class performs all the API calls - * - * It uses the supplied HTTP client as a default (cURL) - * - */ -class Proxy { - - /** - * HTTP Client - * - * @var \Instagram\Net\ClientInterface - * @access protected - */ - protected $client; - - /** - * Instagram access token - * - * @var string - * @access protected - */ - protected $access_token = null; - - /** - * Client ID - * - * @var string - * @access protected - */ - protected $client_id = null; - - /** - * API URL - * - * @var string - * @access protected - */ - protected $api_url = 'https://api.instagram.com/v1'; - - /** - * Constructor - * - * @param \Instagram\Net\ClientInterface $client HTTP Client - * @param string $access_token The access token from authentication - * @access public - */ - public function __construct( \Instagram\Net\ClientInterface $client, $access_token = null ) { - $this->client = $client; - $this->access_token = $access_token; - } - - /** - * Get the access token - * - * @param array $data Auth data - * @return string Returns the access token - */ - public function getAccessToken( array $data ) { - $response = $this->apiCall( - 'post', - 'https://api.instagram.com/oauth/access_token', - $data - ); - return $response; - } - - /** - * Set the access token - * - * @param string $access_token The access token - * @access public - */ - public function setAccessToken( $access_token ) { - $this->access_token = $access_token; - } - - /** - * Set the client ID - * - * @param string $client_id the client ID - * @access public - */ - public function setClientID( $client_id ) { - $this->client_id = $client_id; - } - - /** - * Logout of instagram - * - * This hasn't been implemented by instagram yet - * - * @access public - */ - public function logout() { - $this->client->get( 'https://instagram.com/accounts/logout/', array() ); - } - - /** - * Get the media associated with an object - * - * This function is used by the individual object functions - * getLocationMedia, getTagMedia, atc... - * - * @param string $api_endpoint API endpoint for the object type - * @param string $id Id of the object to get the media for - * @param array $params Extra parameters for the API call - * @return StdClass Returns the raw response - * @access protected - */ - protected function getObjectMedia( $api_endpoint, $id, array $params = null ) { - $response = $this->apiCall( - 'get', - sprintf( '%s/%s/%s/media/recent', $this->api_url, strtolower( $api_endpoint ), $id ), - $params - ); - return $response->getRawData(); - } - - /** - * Get location media - * - * @param string $id Location ID - * @param array $params Extra params to pass to the API - * @return StdClass Returns the location media - * @access public - */ - public function getLocationMedia( $id, array $params = null ) { - return $this->getObjectMedia( 'Locations', $id, $params ); - } - - /** - * Get tag media - * - * @param string $id Location ID - * @param array $params Extra params to pass to the API - * @return StdClass Returns the location media - * @access public - */ - public function getTagMedia( $id, array $params = null ) { - return $this->getObjectMedia( 'Tags', $id, $params ); - } - - /** - * Get user media - * - * @param string $id Location ID - * @param array $params Extra params to pass to the API - * @return StdClass Returns the location media - * @access public - */ - public function getUserMedia( $id, array $params = null ) { - return $this->getObjectMedia( 'Users', $id, $params ); - } - - /** - * Get user - * - * @param string $id User ID - * @return StdClass Returns the user data - * @access public - */ - public function getUser( $id ) { - $response = $this->apiCall( - 'get', - sprintf( '%s/users/%s', $this->api_url, $id ) - ); - return $response->getData(); - } - - /** - * Get a user's follows - * - * @param string $id User's ID - * @param array $params Extra params to pass to the API - * @return StdClass Returns the user's followers - * @access public - */ - public function getUserFollows( $id, array $params = null ) { - $response = $this->apiCall( - 'get', - sprintf( '%s/users/%s/follows', $this->api_url, $id ), - $params - ); - return $response->getRawData(); - } - - /** - * Get a user's followers - * - * @param string $id User's ID - * @param array $params Extra params to pass to the API - * @return StdClass Returns the user's followers - * @access public - */ - public function getUserFollowers( $id, array $params = null ) { - $response = $this->apiCall( - 'get', - sprintf( '%s/users/%s/followed-by', $this->api_url, $id ), - $params - ); - return $response->getRawData(); - } - - /** - * Get media comments - * - * @param string $id Media ID - * @return StdClass Returns the media data - * @access public - */ - public function getMediaComments( $id ) { - $response = $this->apiCall( - 'get', - sprintf( '%s/media/%s/comments', $this->api_url, $id ) - ); - return $response->getRawData(); - } - - /** - * Get media likes - * - * @param string $id Media ID - * @return StdClass Returns the media likes - * @access public - */ - public function getMediaLikes( $id ) { - $response = $this->apiCall( - 'get', - sprintf( '%s/media/%s/likes', $this->api_url, $id ) - ); - return $response->getRawData(); - } - - /** - * Get media comments - * - * @return StdClass Returns the current user data - * @access public - */ - public function getCurrentUser() { - $response = $this->apiCall( - 'get', - sprintf( '%s/users/self', $this->api_url ) - ); - return $response->getData(); - } - - /** - * Get media - * - * @param string $id Media ID - * @return StdClass Returns the media data - * @access public - */ - public function getMedia( $id ) { - $response = $this->apiCall( - 'get', - sprintf( '%s/media/%s', $this->api_url, $id ) - ); - return $response->getData(); - } - - /** - * Get tag - * - * @param string $id Tag ID - * @return StdClass Returns the tag data - * @access public - */ - public function getTag( $tag ) { - $response = $this->apiCall( - 'get', - sprintf( '%s/tags/%s', $this->api_url, $tag ) - ); - return $response->getData(); - } - - /** - * Get location - * - * @param string $id Location ID - * @return StdClass Returns the location data - * @access public - */ - public function getLocation( $id ) { - $response = $this->apiCall( - 'get', - sprintf( '%s/locations/%s', $this->api_url, $id ) - ); - return $response->getData(); - } - - /** - * Search users - * - * @param array $params Search params - * @return array Returns an array of user data - * @access public - */ - public function searchUsers( array $params = null ) { - $response = $this->apiCall( - 'get', - $this->api_url . '/users/search', - $params - ); - return $response->getRawData(); - } - - /** - * Search tags - * - * @param array $params Search params - * @return array Returns an array of tag data - * @access public - */ - public function searchTags( array $params = null ) { - $response = $this->apiCall( - 'get', - $this->api_url . '/tags/search', - $params - ); - return $response->getRawData(); - } - - /** - * Search media - * - * @param array $params Search params - * @return array Returns an array of media data - * @access public - */ - public function searchMedia( array $params = null ) { - $response = $this->apiCall( - 'get', - $this->api_url . '/media/search', - $params - ); - return $response->getRawData(); - } - - /** - * Search locations - * - * @param array $params Search params - * @return array Returns an array of location data - * @access public - */ - public function searchLocations( array $params = null ) { - $response = $this->apiCall( - 'get', - $this->api_url . '/locations/search', - $params - ); - return $response->getRawData(); - } - - /** - * Get popular media - * - * @param array $params Extra params - * @return array Returns an array of popular media data - * @access public - */ - public function getPopularMedia( array $params = null ) { - $response = $this->apiCall( - 'get', - $this->api_url . '/media/popular', - $params - ); - return $response->getRawData(); - } - - /** - * Get the current user's feed - * - * @param array $params Extra params - * @return array Returns an array of media data - * @access public - */ - public function getFeed( array $params = null ) { - $response = $this->apiCall( - 'get', - $this->api_url . '/users/self/feed', - $params - ); - return $response->getRawData(); - } - - /** - * Get the current users follow requests - * - * @param $params Extra params (not used in API, here in case it's added) - * @return array Returns an array of user data - * @access public - */ - public function getFollowRequests( array $params = null ) { - $response = $this->apiCall( - 'get', - $this->api_url . '/users/self/requested-by', - $params - ); - return $response->getRawData(); - } - - /** - * Get the current user's liked media - * - * @param array $params Extra params - * @return array Returns an array of media data - * @access public - */ - public function getLikedMedia( array $params = null ) { - $response = $this->apiCall( - 'get', - $this->api_url . '/users/self/media/liked', - $params - ); - return $response->getRawData(); - } - - /** - * Get a user's relationship to the current user - * - * @param string $user_id User to check relationship for - * @return StdClass Returns the relationship - * @access public - */ - public function getRelationshipToCurrentUser( $user_id ) { - $response = $this->apiCall( - 'get', - $this->api_url . sprintf( '/users/%s/relationship', $user_id ) - ); - return $response->getData(); - } - - /** - * Modify a relationship with the current user - * @param string $user_id User ID of the user to change the relationship for - * @param string $relationship New relationship {@link http://instagram.com/developer/endpoints/relationships/#post_relationship} - * @return StdClass Returns the status - * @access public - */ - public function modifyRelationship( $user_id, $relationship ) { - $response = $this->apiCall( - 'post', - $this->api_url . sprintf( '/users/%s/relationship', $user_id ), - array( 'action' => $relationship ) - ); - return $response->getData(); - } - - /** - * Add a like form the current user on a media - * - * @param string $media_id Media ID to like - * @return StdClass Returns the status - * @access public - */ - public function like( $media_id ) { - $this->apiCall( - 'post', - $this->api_url . sprintf( '/media/%s/likes', $media_id ) - ); - } - - /** - * Delete a like form the current user on a media - * - * @param string $media_id Media ID to unlike - * @return StdClass Returns the status - * @access public - */ - public function unLike( $media_id ) { - $this->apiCall( - 'delete', - $this->api_url . sprintf( '/media/%s/likes', $media_id ) - ); - } - - /** - * Add a comment to a media - * - * @param string $media_id Media ID - * @param string $text Comment text - * @return StdClass Returns the status - * @access public - */ - public function addMediaComment( $media_id, $text ) { - $this->apiCall( - 'post', - $this->api_url . sprintf( '/media/%s/comments', $media_id ), - array( 'text' => $text ) - ); - } - - /** - * Delete a comment from a media - * - * @param string $media_id Media ID - * @param string $comment_id Comment ID to delete - * @return StdClass - * @access public - */ - public function deleteMediaComment( $media_id, $comment_id ) { - $this->apiCall( - 'delete', - $this->api_url . sprintf( '/media/%s/comments/%s', $media_id, $comment_id ) - ); - } - - /** - * Make a call to the API - * - * @param string $method HTTP method to use - * @param string $url URL - * @param array $params API parameters - * @param boolean $throw_exception True to throw exceptoins - * @throws APIException, APIAuthException - * @return \Instagram\Net\ApiResponse Returns teh API response - * @access private - */ - private function apiCall( $method, $url, array $params = null, $throw_exception = true ){ - - $raw_response = $this->client->$method( - $url, - array( - 'access_token' => $this->access_token, - 'client_id' => isset( $params['client_id'] ) ? $params['client_id'] : $this->client_id - ) + (array) $params - ); - - $response = new \Instagram\Net\ApiResponse( $raw_response ); - - if ( !$response->isValid() ) { - if ( $throw_exception ) { - if ( $response->getErrorType() == 'OAuthAccessTokenException' ) { - throw new \Instagram\Core\ApiAuthException( $response->getErrorMessage(), $response->getErrorCode(), $response->getErrorType() ); - } - else { - throw new \Instagram\Core\ApiException( $response->getErrorMessage(), $response->getErrorCode(), $response->getErrorType() ); - } - } - else { - return false; - } - } - return $response; - } - - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/CurrentUser.php b/vendor/php-instagram-api/php-instagram-api/Instagram/CurrentUser.php deleted file mode 100644 index 18a317378..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/CurrentUser.php +++ /dev/null @@ -1,415 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram; - -use \Instagram\Collection\MediaCollection; -use \Instagram\Collection\LikedMediaCollection; -use \Instagram\Collection\UserCollection; - -/** - * Current User - * - * Holds the currently logged in user - * - * @see \Instagram\Instagram->getCurrentUser() - * {@link https://github.com/galen/PHP-Instagram-API/blob/master/Examples/current_user.php} - * {@link http://galengrover.com/projects/instagram/?example=current_user.php} - */ -class CurrentUser extends \Instagram\User { - - /** - * Holds relationship info for the current user - * - * @access protected - * @var array - */ - protected $relationships = array(); - - /** - * Holds liked info for the current user - * - * Current user likes are stored in media objects - * If a media is liked after a media has been fetched the like will not be a part of the media object - * - * @access protected - * @var array - */ - protected $liked = array(); - - /** - * Holds unliked info for the current user - * - * @access protected - * @var array - */ - protected $unliked = array(); - - /** - * Get the API ID - * - * @return string Returns "self" - * @access public - */ - public function getApiId() { - return 'self'; - } - - /** - * Does the current use like a media - * - * @param \Instagram\Media $media Media to query for a like from the current user - * @access public - */ - public function likes( \Instagram\Media $media ) { - return - isset( $this->liked[$media->getId()] ) || - ( - isset( $media->getData()->user_has_liked ) && - (bool)$media->getData()->user_has_liked === true && - !isset( $this->unliked[$media->getId()] ) - ); - } - - /** - * Add like from current user - * - * @param \Instagram\Media|string $media Media to add a like to from the current user - * @access public - */ - public function addLike( $media ) { - if ( $media instanceof \Instagram\Media ) { - $media = $media->getId(); - } - $this->proxy->like( $media ); - unset( $this->unliked[$media] ); - $this->liked[$media] = true; - } - - /** - * Delete like from current user - * - * @param \Instagram\Media|string $media Media to delete a like to from the current user - * @access public - */ - public function deleteLike( $media ) { - if ( $media instanceof \Instagram\Media ) { - $media = $media->getId(); - } - $this->proxy->unLike( $media ); - unset( $this->liked[$media] ); - $this->unliked[$media] = true; - } - - /** - * Add a comment - * - * @param \Instagram\Media|string Media to add a comment to - * @param string $text Comment text - * @access public - */ - public function addMediaComment( $media, $text ) { - if ( $media instanceof \Instagram\Media ) { - $media = $media->getId(); - } - $this->proxy->addMediaComment( $media, $text ); - } - - /** - * Delete a comment - * - * @param \Instagram\Media|string Media to delete a comment from - * @param string $text Comment text - * @access public - */ - public function deleteMediaComment( $media, $comment ) { - if ( $media instanceof \Instagram\Media ) { - $media = $media->getId(); - } - if ( $comment instanceof \Instagram\Comment ) { - $comment = $comment->getId(); - } - $this->proxy->deleteMediaComment( $media, $comment ); - } - - /** - * Update relationship with a user - * - * Internal function that updates relationships - * - * @see \Instagram\CurrentUser::follow - * @see \Instagram\CurrentUser::unFollow - * @see \Instagram\CurrentUser::getRelationship - * @see \Instagram\CurrentUser::approveFollowRequest - * @see \Instagram\CurrentUser::ignoreFollowRequest - * @see \Instagram\CurrentUser::block - * @see \Instagram\CurrentUser::unblock - * - * @param \Instagram\User|string User object or user id whose relationship you'd like to update - * @access protected - */ - protected function updateRelationship( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - if ( !isset( $this->relationships[ $user ] ) ) { - $this->relationships[ $user ] = $this->proxy->getRelationshipToCurrentUser( $user ); - } - } - - /** - * Follow user - * - * @param \Instagram\User|string User object or user id who should be followed - * @return boolean - */ - public function follow( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - $this->updateRelationship( $user ); - $response = $this->proxy->modifyRelationship( $user, 'follow' ); - foreach( $response as $r => $v ) { - $this->relationships[ $user ]->$r = $v; - } - return true; - } - - /** - * Approve follower - * - * @param \Instagram\User|string $user User object or user id who should be approved for following - * @return boolean - */ - public function approveFollowRequest( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - $this->updateRelationship( $user ); - $response = $this->proxy->modifyRelationship( $user, 'approve' ); - foreach( $response as $r => $v ) { - $this->relationships[ $user ]->$r = $v; - } - return true; - } - - /** - * Ignore follower - * - * @param \Instagram\User|string $user User object or user id who should be ignored - * @return boolean - */ - public function ignoreFollowRequest( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - $this->updateRelationship( $user ); - $response = $this->proxy->modifyRelationship( $user, 'ignore' ); - foreach( $response as $r => $v ) { - $this->relationships[ $user ]->$r = $v; - } - return true; - } - - /** - * Unfollow user - * - * @param \Instagram\User|string $user User object or user id who should be unfollowed - * @return boolean - */ - public function unFollow( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - $this->updateRelationship( $user ); - $response = $this->proxy->modifyRelationship( $user, 'unfollow' ); - foreach( $response as $r => $v ) { - $this->relationships[ $user ]->$r = $v; - } - return true; - } - - /** - * Block user - * - * @param \Instagram\User|string $user User object or user id who should be blocked - * @return boolean - */ - public function block( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - $this->updateRelationship( $user ); - $response = $this->proxy->modifyRelationship( $user, 'block' ); - foreach( $response as $r => $v ) { - $this->relationships[ $user ]->$r = $v; - } - return true; - } - - /** - * Unblock user - * - * @param \Instagram\User|string $user User object or user id who should be unblocked - * @return boolean - */ - public function unblock( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - $this->updateRelationship( $user ); - $response = $this->proxy->modifyRelationship( $user, 'unblock' ); - foreach( $response as $r => $v ) { - $this->relationships[ $user ]->$r = $v; - } - return true; - } - - /** - * Check if the current user can view a user - * - * @return bool - * @access public - */ - public function canViewUser( $user_id ) { - $relationship = $this->proxy->getRelationshipToCurrentUser( $user_id ); - if ( $this->getId() == $user_id || !(bool)$relationship->target_user_is_private || $relationship->outgoing_status == 'follows' ) { - return true; - } - return false; - } - - /** - * Get relationship - * - * Get the complete relationship to a user - * - * @param \Instagram\User|string $user User object or user id to get the relationship details of - * @return StdClass - */ - public function getRelationship( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - $this->updateRelationship( $user ); - return $this->relationships[ $user ]; - } - - /** - * Get follow request - * - * Get the users that have requested to follow the current user - * - * @return \Instagram\Collection\UserCollection - */ - public function getFollowRequests() { - return new UserCollection( $this->proxy->getFollowRequests(), $this->proxy ); - } - - /** - * Check outgoing request status - * - * Check if the current user is currently waiting approval of a follow request - * - * @param \Instagram\User|string $user User object or user id to check the status of - * @return boolean - */ - public function isAwaitingFollowApprovalFrom( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - return $this->getRelationship( $user )->outgoing_status == 'requested'; - } - - /** - * Check incoming request status - * - * Check if the current user has been requested to be followed by a user - * - * @param \Instagram\User|string $user User object or user id to check the status of - * @return boolean - */ - public function hasBeenRequestedBy( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - return $this->getRelationship( $user )->incoming_status == 'requested_by'; - } - - /** - * Check following status - * - * Check if the current user is blocking a user - * - * @param \Instagram\User|string $user User object or user id to check the following status of - * @return boolean - */ - public function isBlocking( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - return $this->getRelationship( $user )->incoming_status == 'blocked_by_you'; - } - - /** - * Check following status - * - * Check if hte current user is following a user - * - * @param \Instagram\User|string $user User object or user id to check the following status of - * @return boolean - */ - public function isFollowing( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - return $this->getRelationship( $user )->outgoing_status == 'follows'; - } - - /** - * Check followed by status - * - * Check if the current user is followed by a user - * - * @param \Instagram\User|string $user User object or user id to check the followed by status of - * @return boolean - */ - public function isFollowedBy( $user ) { - if ( $user instanceof \Instagram\User ) { - $user = $user->getId(); - } - return $this->getRelationship( $user )->incoming_status == 'followed_by'; - } - - /** - * Get the current user's feed - * - * This can be paginated with the next_max_id param obtained from MediaCollection->getNext() - * - * @param array $params Optional params to pass to the endpoint - * @return \Instagram\Collection\MediaCollection - * @access public - */ - public function getFeed( array $params = null ) { - return new MediaCollection( $this->proxy->getFeed( $params ), $this->proxy ); - } - - /** - * Get the current user's liked media - * - * This can be paginated with the next_max_like_id param obtained from MediaCollection->getNext() - * - * @param array $params Optional params to pass to the endpoint - * @return \Instagram\Collection\MediaCollection - * @access public - */ - public function getLikedMedia( array $params = null ) { - return new LikedMediaCollection( $this->proxy->getLikedMedia( $params ), $this->proxy ); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Helper.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Helper.php deleted file mode 100644 index c6518f24f..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Helper.php +++ /dev/null @@ -1,90 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram; - -/** - * Helper class - * - * Example: - * - * $tags_closure = function($m){ - * return sprintf( '%s', $m[1], $m[0] ); - * }; - * - * $mentions_closure = function($m){ - * return sprintf( '%s', $m[1], $m[0] ); - * }; - * - * echo \Instagram\Helper::parseTagsAndMentions( $media->getCaption(), $tags_closure, $mentions_closure ) - */ -class Helper { - - /** - * Parse mentions in a string - * - * Finds mentions in a string (@mention) and applies a callback function each one - * - * @param string $text Text to parse - * @param \Closure $callback Function to apply to each mention - * @return string Returns the text after the callback have been applied to each mention - * @access public - */ - public static function parseMentions( $text, \Closure $callback ) { - return preg_replace_callback( '~@(.+?)(?=\b)~', $callback, $text ); - } - - /** - * Parse tags in a string - * - * Finds tags in a string (#username) and applies a callback function each one - * - * @param string $text Text to parse - * @param \Closure $callback Function to apply to each tag - * @return string Returns the text after the callback have been applied to each tag - * @access public - */ - public static function parseTags( $text, \Closure $callback ) { - return preg_replace_callback( '~#(.+?)(?=\b)~', $callback, $text ); - } - - /** - * Parse mentions and tags in a string - * - * Finds mentions and tags in a string (@mention, #tag) and applies a callback function each one - * - * @param string $text Text to parse - * @param \Closure $tags_callback Function to apply to each tag - * @param \Closure $mentions_callback Function to apply to each mention - * @return string Returns the text after the callbacks have been applied to tags and mentions - * @access public - */ - public static function parseTagsAndMentions( $text, \Closure $tags_callback, \Closure $mentions_callback ) { - $text = self::parseTags( $text, $tags_callback ); - $text = self::parseMentions( $text, $mentions_callback ); - return $text; - } - - /** - * Is the comment deletable - * - * Checks if a comment is deletable by checking if the current user posted the comment - * or if the comment was added to one of the current user's media - * - * @param \Instagram\Comment $comment The comment - * @param \Instagram\Media $media The media the comment was added to - * @param \Instagram\CurrentUser $current_user Current user - * @access public - */ - public static function commentIsDeletable( \Instagram\Comment $comment, \Instagram\Media $media, \Instagram\CurrentUser $current_user ) { - return - $comment->getUser()->getId() == $current_user->getId() || - $media->getUser()->getId() == $current_user->getId(); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Instagram.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Instagram.php deleted file mode 100644 index a9829a568..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Instagram.php +++ /dev/null @@ -1,283 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram; - -use \Instagram\Collection\MediaSearchCollection; -use \Instagram\Collection\TagCollection; -use \Instagram\Collection\TagMediaCollection; -use \Instagram\Collection\UserCollection; -use \Instagram\Collection\MediaCollection; -use \Instagram\Collection\LocationCollection; -use \Instagram\CurrentUser; -use \Instagram\User; -use \Instagram\Media; -use \Instagram\Tag; -use \Instagram\Location; - -/** - * Instagram! - * - * All objects are created through this object - */ -class Instagram extends \Instagram\Core\BaseObjectAbstract { - - /** - * Constructor - * - * You can supply a client, proxy, and an access token via the config array - * - * @param string $access_token Instagram access token obtained through authentication - * @param \Instagram\Net\ClientInterface $client Client object used to connect to the API - * @access public - */ - public function __construct( $access_token = null, \Instagram\Net\ClientInterface $client = null ) { - $this->proxy = new \Instagram\Core\Proxy( $client ?: new \Instagram\Net\CurlClient, $access_token ?: null ); - } - - /** - * Set the access token - * - * Most API calls require an access ID - * - * @param string $access_token - * @access public - */ - public function setAccessToken( $access_token ) { - $this->proxy->setAccessToken( $access_token ); - } - - /** - * Set the client ID - * - * Some API calls can be called with only a Client ID - * - * @param string $client_id Client ID - * @access public - */ - public function setClientID( $client_id ) { - $this->proxy->setClientId( $client_id ); - } - - /** - * Logout - * - * This doesn't actually work yet, waiting for Instagram to implement it in their API - * - * @access public - */ - public function logout() { - $this->proxy->logout(); - } - - /** - * Get user - * - * Retrieve a user given his/her ID - * - * @param int $id ID of the user to retrieve - * @return \Instagram\User - * @access public - */ - public function getUser( $id ) { - $user = new User( $this->proxy->getUser( $id ), $this->proxy ); - return $user; - } - - /** - * Get user by Username - * - * Retrieve a user given their username - * - * @param string $username Username of the user to retrieve - * @return \Instagram\User - * @access public - * @throws \Instagram\ApiException - */ - public function getUserByUsername( $username ) { - $user = $this->searchUsers( $username, array( 'count' => 1 ) )->getItem( 0 ); - if ( $user ) { - try { - return $this->getUser( $user->getId() ); - } catch( \Instagram\Core\ApiException $e ) { - if ( $e->getType() == $e::TYPE_NOT_ALLOWED ) { - return $user; - } - } - } - throw new \Instagram\Core\ApiException( 'username not found', 400, 'InvalidUsername' ); - } - - /** - * Check if a user is private - * - * @return bool - * @access public - */ - public function isUserPrivate( $user_id ) { - $relationship = $this->proxy->getRelationshipToCurrentUser( $user_id ); - return (bool)$relationship->target_user_is_private; - } - - /** - * Get media - * - * Retreive a media object given it's ID - * - * @param int $id ID of the media to retrieve - * @return \Instagram\Media - * @access public - */ - public function getMedia( $id ) { - $media = new Media( $this->proxy->getMedia( $id ), $this->proxy ); - return $media; - } - - /** - * Get Tag - * - * @param string $tag Tag to retrieve - * @return \Instagram\Tag - * @access public - */ - public function getTag( $tag ) { - $tag = new Tag( $this->proxy->getTag( $tag ), $this->proxy ); - return $tag; - } - - /** - * Get location - * - * Retreive a location given it's ID - * - * @param int $id ID of the location to retrieve - * @return \Instagram\Location - * @access public - */ - public function getLocation( $id ) { - $location = new Location( $this->proxy->getLocation( $id ), $this->proxy ); - return $location; - } - - /** - * Get current user - * - * Returns the current user wrapped in a CurrentUser object - * - * @return \Instagram\CurrentUser - * @access public - */ - public function getCurrentUser() { - $current_user = new CurrentUser( $this->proxy->getCurrentUser(), $this->proxy ); - return $current_user; - } - - /** - * Get popular media - * - * Returns current popular media - * - * @return \Instagram\Collection\MediaCollection - * @access public - */ - public function getPopularMedia() { - $popular_media = new MediaCollection( $this->proxy->getPopularMedia(), $this->proxy ); - return $popular_media; - } - - /** - * Search users - * - * Search the users by username - * - * @param string $query Search query - * @param array $params Optional params to pass to the endpoint - * @return \Instagram\Collection\UserCollection - * @access public - */ - public function searchUsers( $query, array $params = null ) { - $params = (array)$params; - $params['q'] = $query; - $user_collection = new UserCollection( $this->proxy->searchUsers( $params ), $this->proxy ); - return $user_collection; - } - - /** - * Search Media - * - * Returns media that is a certain distance from a given lat/lng - * - * To specify a distance, pass the distance (in meters) in the $params - * - * Default distance is 1000m - * - * @param float $lat Latitude of the search - * @param float $lng Longitude of the search - * @param array $params Optional params to pass to the endpoint - * @return \Instagram\Collection\MediaSearchCollection - * @access public - */ - public function searchMedia( $lat, $lng, array $params = null ) { - $params = (array)$params; - $params['lat'] = (float)$lat; - $params['lng'] = (float)$lng; - $media_collection = new MediaSearchCollection( $this->proxy->searchMedia( $params ), $this->proxy ); - return $media_collection; - } - - /** - * Search for tags - * - * @param string $query Search query - * @param array $params Optional params to pass to the endpoint - * @return \Instagram\Collection\TagCollection - * @access public - */ - public function searchTags( $query, array $params = null ) { - $params = (array)$params; - $params['q'] = $query; - $tag_collection = new TagCollection( $this->proxy->searchTags( $params ), $this->proxy ); - return $tag_collection; - } - - /** - * Search Locations - * - * Returns locations that are a certain distance from a given lat/lng - * - * To specify a distance, pass the distance (in meters) in the $params - * - * Default distance is 1000m - * - * @param float $lat Latitude of the search - * @param float $lng Longitude of the search - * @param array $params Optional params to pass to the endpoint - * @return \Instagram\LocationCollection - * @access public - */ - public function searchLocations( $lat, $lng, array $params = null ) { - $params = (array)$params; - $params['lat'] = (float)$lat; - $params['lng'] = (float)$lng; - $location_collection = new LocationCollection( $this->proxy->searchLocations( $params ), $this->proxy ); - return $location_collection; - } - - /** - * Get tag media - * - * @param string $tag - * @param array $params Optional params to pass to the endpoint - * @return TagMediaCollection - */ - public function getTagMedia( $tag, array $params = null ) { - $params = (array)$params; - return new TagMediaCollection( $this->proxy->getTagMedia( $tag, $params ), $this->proxy ); - } - -} diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Location.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Location.php deleted file mode 100644 index b74fb917c..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Location.php +++ /dev/null @@ -1,96 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram; - -use \Instagram\Collection\MediaCollection; - -/** - * Location class - * - * Some media has a location associated to it. This location will have an ID and a name. - * Some media has no location associated, but has a lat/lng. These location objects will return null or '' for certain method calls - * - * @see \Instagram\Instagram->getCurrentUser() - * {@link https://github.com/galen/PHP-Instagram-API/blob/master/Examples/location.php} - * {@link http://galengrover.com/projects/instagram/?example=location.php} - */ -class Location extends \Instagram\Core\BaseObjectAbstract { - - /** - * Get location media - * - * Retrieve the recent media posted to a given location - * - * This can be paginated with the next_max_id param obtained from MediaCollection->getNext() - * - * @param array $params Optional params to pass to the endpoint - * @return \Instagram\Collection\MediaCollection - * @access public - */ - public function getMedia( array $params = null ) { - return new MediaCollection( $this->proxy->getLocationMedia( $this->getApiId(), $params ), $this->proxy ); - } - - /** - * Get location ID - * - * @return string|null - * @access public - */ - public function getId() { - return isset( $this->data->id ) ? $this->data->id : null; - } - - /** - * Get location name - * - * @return string|null - * @access public - */ - public function getName() { - return isset( $this->data->name ) ? $this->data->name : null; - } - - /** - * Get location longitude - * - * Get the longitude of the location - * - * @return string|null - * @access public - */ - public function getLat() { - return isset( $this->data->latitude ) && is_float( $this->data->latitude ) ? $this->data->latitude : null; - } - - /** - * Get location latitude - * - * Get the latitude of the location - * - * @return string|null - * @access public - */ - public function getLng() { - return isset( $this->data->longitude ) && is_float( $this->data->longitude ) ? $this->data->longitude : null; - } - - /** - * Magic toString method - * - * Returns the location's name - * - * @return string - * @access public - */ - public function __toString() { - return $this->getName() ? $this->getName() : ''; - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Media.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Media.php deleted file mode 100644 index 7dcadf844..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Media.php +++ /dev/null @@ -1,328 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram; - -use \Instagram\Comment; -use \Instagram\User; -use \Instagram\Location; -use \Instagram\Collection\CommentCollection; -use \Instagram\Collection\TagCollection; -use \Instagram\Collection\UserCollection; - -/** - * Media class - * - * @see \Instagram\Instagram->getLocation() - * {@link https://github.com/galen/PHP-Instagram-API/blob/master/Examples/media.php} - * {@link http://galengrover.com/projects/instagram/?example=media.php} - */ -class Media extends \Instagram\Core\BaseObjectAbstract { - - /** - * User cache - * - * @var \Instagram\User - */ - protected $user = null; - - /** - * Comments cache - * - * @var \Instagram\Collection\CommentCollection - */ - protected $comments = null; - - /** - * Location cache - * - * @var \Instagram\Location - */ - protected $location = null; - - /** - * Tags cache - * - * @var \Instagram\Collection\TagCollection - */ - protected $tags = null; - - /** - * Get the ID - * Get the media type - * - * @return string - * @access public - */ - public function getId() { - return $this->data->id; - } - - /** - * Get the media type - * - * @return string - * @access public - */ - public function getType() { - return $this->data->type; - } - - /** - * Get the thumbnail - * - * @return string - * @access public - */ - public function getThumbnail() { - return $this->data->images->thumbnail; - } - - /** - * Get the standard resolution video - * - * @return string - * @access public - */ - public function getStandardResVideo() { - return $this->data->videos->standard_resolution; - } - - /** - * Get the low resolution video - * - * @return string - * @access public - */ - public function getLowResVideo() { - return $this->data->videos->low_resolution; - } - - /** - * Get the standard resolution image - * - * @return string - * @access public - */ - public function getStandardResImage() { - return $this->data->images->standard_resolution; - } - - /** - * Get the low resolution image - * - * @return string - * @access public - */ - public function getLowResImage() { - return $this->data->images->low_resolution; - } - - /** - * Get the standard resolution image - * - * Alias for getStandardResImage since Instagram added videos - * - * @return string - * @access public - */ - public function getStandardRes() { - return $this->getStandardResImage(); - } - - /** - * Get the low resolution image - * - * Alias for getLowResImage since Instagram added videos - * - * @return string - * @access public - */ - public function getLowRes() { - return $this->getLowResImage(); - } - - /** - * Get the media caption - * - * @return string - * @access public - */ - public function getCaption() { - if ( $this->data->caption ) { - return new Comment( $this->data->caption ); - } - return null; - } - - /** - * Get the created time - * - * @param string $format {@link http://php.net/manual/en/function.date.php} - * @return string - * @access public - */ - public function getCreatedTime( $format = null ) { - if ( $format ) { - $date = date( $format, $this->data->created_time ); - } - else { - $date = $this->data->created_time; - } - return $date; - } - - /** - * Get the user that posted the media - * - * @return \Instagram\User - * @access public - */ - public function getUser() { - if ( !$this->user ) { - $this->user = new User( $this->data->user, $this->proxy ); - } - return $this->user; - } - - /** - * Get media comments - * - * Return all the comments associated with a media - * - * @return \Instagram\CommentCollection - * @access public - */ - public function getComments() { - if ( !$this->comments ) { - $this->comments = new CommentCollection( $this->proxy->getMediaComments( $this->getApiId() ), $this->proxy ); - } - return $this->comments; - } - - /** - * Get the media filter - * - * @return string - * @access public - */ - public function getFilter() { - return $this->data->filter; - } - - /** - * Get the media's tags - * - * @return \Instagram\Collection\TagCollection - * @access public - */ - public function getTags() { - if ( !$this->tags ) { - $this->tags = new TagCollection( $this->data->tags, $this->proxy ); - } - return $this->tags; - } - - /** - * Get the media's link - * - * @return string - * @access public - */ - public function getLink() { - return $this->data->link; - } - - /** - * Get the media's likes count - * - * @return int - * @access public - */ - public function getLikesCount() { - return (int)$this->data->likes->count; - } - - /** - * Get media likes - * - * Media objects contain the first 10 likes. You can get these likes by passing `false` - * to this method. Using the internal likes of a media object cause issues when liking/disliking media. - * - * @param bool $fetch_from_api Query the API or use internal - * @return \Instagram\UserCollection - * @access public - */ - public function getLikes( $fetch_from_api = true ) { - if ( !$fetch_from_api ) { - return new UserCollection( $this->data->likes ); - } - $user_collection = new UserCollection( $this->proxy->getMediaLikes( $this->getApiId() ), $this->proxy ); - $user_collection->setProxies( $this->proxy ); - $this->likes = $user_collection; - return $this->likes; - } - - /** - * Get location status - * - * Will return true if any location data is associated with the media - * - * @return bool - * @access public - */ - public function hasLocation() { - return isset( $this->data->location->latitude ) && isset( $this->data->location->longitude ); - } - - /** - * Get location status - * - * Will return true if the media has a named location attached to it - * - * Some media only has lat/lng data - * - * @return bool - * @access public - */ - public function hasNamedLocation() { - return isset( $this->data->location->id ); - } - - /** - * Get the location - * - * Returns the location associated with the media or null if no location data is available - * - * @param bool $force_fetch Don't use the cache - * @return \Instagram\Location|null - * @access public - */ - public function getLocation( $force_fetch = false ) { - if ( !$this->hasLocation() ) { - return null; - } - if ( !$this->location || (bool)$force_fetch ) { - $this->location = new Location( $this->data->location, isset( $this->data->location->id ) ? $this->proxy : null ); - } - return $this->location; - } - - /** - * Magic toString method - * - * Returns the media's thumbnail url - * - * @return string - * @access public - */ - public function __toString() { - return $this->getThumbnail()->url; - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Net/ApiResponse.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Net/ApiResponse.php deleted file mode 100644 index d23eb6804..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Net/ApiResponse.php +++ /dev/null @@ -1,151 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Net; - -/** - * API Response - * - * Holds the API response - */ -class ApiResponse { - - /** - * Response - * - * This is the response from the API - * - * @var StdClass - * @access protected - */ - protected $response; - - /** - * Constructor - * - * @param $raw_response Response from teh API - * @access public - */ - public function __construct( $raw_response ){ - $this->response = json_decode( $raw_response ); - if ( !$this->isValidApiResponse() ) { - $this->response = new \StdClass; - $this->response->meta = new \StdClass; - $this->response->meta->error_type = 'UnknownAPiError'; - $this->response->meta->code = 555; - $this->response->meta->error_message = 'Unknown error'; - } - } - - /** - * Is Valid - * - * Returns true if the API returned an error, otherwise false - * - * @return boolean - * @access public - */ - public function isValid() { - return - $this->response instanceof \StdClass && - !isset( $this->response->meta->error_type ) && - !isset( $this->response->error_type ); - } - /** - * Is Valid API Response - * - * Returns true if the response was a valid response from the API, otherwise false - * - * @return boolean - * @access public - */ - public function isValidApiResponse() { - return $this->response instanceof \StdClass; - } - - /** - * Get the response data - * - * @return mixed Return the response's data or null - * @access public - */ - public function getData() { - return isset( $this->response->data ) ? $this->response->data : null; - } - - /** - * Get the raw response - * - * @return mixed Returns the response or null - * @access public - */ - public function getRawData() { - return isset( $this->response ) ? $this->response : null; - } - - - - /** - * Get the response's error message - * - * @return mixed Returns the error message or null - * @access public - */ - public function getErrorMessage() { - if ( isset( $this->response->error_message ) ) { - return $this->response->error_message; - } - if( isset( $this->response->meta->error_message ) ) { - return $this->response->meta->error_message; - } - return null; - } - - /** - * Get the error code - * - * @return mixed Returns the error code or null - * @access public - */ - public function getErrorCode() { - if ( isset( $this->response->code ) ) { - return $this->response->code; - } - if( isset( $this->response->meta->code ) ) { - return $this->response->meta->code; - } - return null; - } - - /** - * Get the error type - * - * @return mixed Returns the error type or null - * @access public - */ - public function getErrorType() { - if ( isset( $this->response->error_type ) ) { - return $this->response->error_type; - } - if( isset( $this->response->meta->error_type ) ) { - return $this->response->meta->error_type; - } - return null; - } - - /** - * Magic to string method - * - * @return string Return the json encoded response - * @access public - */ - public function __toString() { - return json_encode( $this->response ); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Net/ClientInterface.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Net/ClientInterface.php deleted file mode 100644 index a0444b0b7..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Net/ClientInterface.php +++ /dev/null @@ -1,25 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Net; - -/** - * Client Interface - * - * All clients must implement this interface - * - * The 4 http functions just need to return the raw data from the API - */ -interface ClientInterface { - - function get( $url, array $data = null ); - function post( $url, array $data = null ); - function put( $url, array $data = null ); - function delete( $url, array $data = null ); - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Net/CurlClient.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Net/CurlClient.php deleted file mode 100644 index 90bf7b89b..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Net/CurlClient.php +++ /dev/null @@ -1,120 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram\Net; - -/** - * Curl Client - * - * Uses curl to access the API - */ -class CurlClient implements ClientInterface { - - /** - * Curl Resource - * - * @var curl resource - */ - protected $curl = null; - - /** - * Constructor - * - * Initializes the curl object - */ - function __construct(){ - $this->initializeCurl(); - } - - /** - * GET - * - * @param string $url URL to send get request to - * @param array $data GET data - * @return \Instagram\Net\Response - * @access public - */ - public function get( $url, array $data = null ){ - curl_setopt( $this->curl, CURLOPT_CUSTOMREQUEST, 'GET' ); - curl_setopt( $this->curl, CURLOPT_URL, sprintf( "%s?%s", $url, http_build_query( $data ) ) ); - return $this->fetch(); - } - - /** - * POST - * - * @param string $url URL to send post request to - * @param array $data POST data - * @return \Instagram\Net\Response - * @access public - */ - public function post( $url, array $data = null ) { - curl_setopt( $this->curl, CURLOPT_CUSTOMREQUEST, 'POST' ); - curl_setopt( $this->curl, CURLOPT_URL, $url ); - curl_setopt( $this->curl, CURLOPT_POSTFIELDS, http_build_query( $data ) ); - return $this->fetch(); - } - - /** - * PUT - * - * @param string $url URL to send put request to - * @param array $data PUT data - * @return \Instagram\Net\Response - * @access public - */ - public function put( $url, array $data = null ){ - curl_setopt( $this->curl, CURLOPT_CUSTOMREQUEST, 'PUT' ); - } - - /** - * DELETE - * - * @param string $url URL to send delete request to - * @param array $data DELETE data - * @return \Instagram\Net\Response - * @access public - */ - public function delete( $url, array $data = null ){ - curl_setopt( $this->curl, CURLOPT_URL, sprintf( "%s?%s", $url, http_build_query( $data ) ) ); - curl_setopt( $this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE' ); - return $this->fetch(); - } - - /** - * Initialize curl - * - * Sets initial parameters on the curl object - * - * @access protected - */ - protected function initializeCurl() { - $this->curl = curl_init(); - curl_setopt( $this->curl, CURLOPT_RETURNTRANSFER, true ); - curl_setopt( $this->curl, CURLOPT_SSL_VERIFYPEER, false ); - } - - /** - * Fetch - * - * Execute the curl object - * - * @return StdClass - * @access protected - * @throws \Instagram\Core\ApiException - */ - protected function fetch() { - $raw_response = curl_exec( $this->curl ); - $error = curl_error( $this->curl ); - if ( $error ) { - throw new \Instagram\Core\ApiException( $error, 666, 'CurlError' ); - } - return $raw_response; - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/Tag.php b/vendor/php-instagram-api/php-instagram-api/Instagram/Tag.php deleted file mode 100644 index e95618cb8..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/Tag.php +++ /dev/null @@ -1,81 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram; - -use \Instagram\Collection\TagMediaCollection; - -/** - * Tag class - * - * @see \Instagram\Instagram->getTag() - * {@link https://github.com/galen/PHP-Instagram-API/blob/master/Examples/tag.php} - * {@link http://galengrover.com/projects/instagram/?example=tag.php} - */ -class Tag extends \Instagram\Core\BaseObjectAbstract { - - /** - * Get tag media - * - * Retrieve the recent media posted with this tag - * - * This can be paginated with the next_max_id param obtained from MediaCollection->getNext() - * - * @param array $params Optional params to pass to the endpoint - * @return \Instagram\Collection\MediaCollection - * @access public - */ - public function getMedia( array $params = null ) { - return new TagMediaCollection( $this->proxy->getTagMedia( $this->getApiId(), $params ), $this->proxy ); - } - - /** - * Get media count - * - * @return int - * @access public - */ - public function getMediaCount() { - return (int)$this->data->media_count; - } - - /** - * Get tag name - * - * @return string - * @access public - */ - public function getName() { - return $this->data->name; - } - - /** - * Get ID - * - * The ID for a tag is it's name, so return the name - * - * @return string - * @access public - */ - public function getId() { - return $this->getName(); - } - - /** - * Magic toString method - * - * Return the tag name - * - * @return string - * @access public - */ - public function __toString() { - return $this->getName(); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/Instagram/User.php b/vendor/php-instagram-api/php-instagram-api/Instagram/User.php deleted file mode 100644 index 353fcf321..000000000 --- a/vendor/php-instagram-api/php-instagram-api/Instagram/User.php +++ /dev/null @@ -1,188 +0,0 @@ - -* @license http://opensource.org/licenses/mit-license.php The MIT License -*/ - -namespace Instagram; - -use \Instagram\Collection\MediaCollection; -use \Instagram\Collection\UserCollection; - -/** - * User class - * - * @see \Instagram\Instagram->getUser() - * {@link https://github.com/galen/PHP-Instagram-API/blob/master/Examples/user.php} - * {@link http://galengrover.com/projects/instagram/?example=user.php} - */ -class User extends \Instagram\Core\BaseObjectAbstract { - - /** - * Get the user's username - * - * @return string - * @access public - */ - public function getUserName() { - return $this->data->username; - } - - /** - * Get the user's full name - * - * @return string|null - * @access public - */ - public function getFullName() { - return isset( $this->data->full_name ) ? $this->data->full_name : null; - } - - /** - * Get the user's profile picture - * - * @return string - * @access public - */ - public function getProfilePicture() { - return $this->data->profile_picture; - } - - /** - * Get the user's biography - * - * @return string - * @access public - */ - public function getBio() { - return $this->data->bio; - } - - /** - * Get the user's website - * - * @return string - * @access public - */ - public function getWebsite() { - return $this->data->website; - } - - /** - * Get the user's counts - * - * @return StdClass|null - * @access public - */ - public function getCounts() { - if ( !$this->isCompleteUser() ) { - $this->updateData(); - } - return isset( $this->data->counts ) ? $this->data->counts : null; - } - - /** - * Get the user's following count - * - * @return int - * @access public - */ - public function getFollowsCount() { - return (int)$this->getCounts()->follows; - } - - /** - * Get the user's followers count - * - * @return int - * @access public - */ - public function getFollowersCount() { - return (int)$this->getCounts()->followed_by; - } - - /** - * Get the user's media count - * - * @return int - * @access public - */ - public function getMediaCount() { - return (int)$this->getCounts()->media; - } - - /** - * Update user data - * - * Sometimes user object are incomplete. For instance when getting a media object's comments - * the users associated with the comments won't have all their data - * - * @access public - */ - public function updateData() { - $this->setData( $this->proxy->getUser( $this->getApiId() ) ); - } - - /** - * Return if the user is complete - * - * @see User::updateData() - * - * @return bool - * @access protected - */ - protected function isCompleteUser() { - return isset( $this->data->counts ); - } - - /** - * Get the user's media - * - * This can be paginated with the next_max_id param obtained from MediaCollection->getNext() - * - * @return\Instagram\Collection\MediaCollection - * @access public - */ - public function getMedia( array $params = null ) { - return new MediaCollection( $this->proxy->getUserMedia( $this->getApiId(), $params ), $this->proxy ); - } - - /** - * Get the users that the user follows - * - * This can be paginated with the next_cursor param obtained from UserCollection->getNext() - * - * @return\Instagram\Collection\UserCollection - * @access public - */ - public function getFollows( array $params = null ) { - return new UserCollection( $this->proxy->getUserFollows( $this->getApiId(), $params ), $this->proxy ); - } - - /** - * Get the user's that follow this user - * - * This can be paginated with the next_cursor param obtained from UserCollection->getNext() - * - * @return\Instagram\Collection\UserCollection - * @access public - */ - public function getFollowers( array $params = null ) { - return new UserCollection( $this->proxy->getUserFollowers( $this->getApiId(), $params ), $this->proxy ); - } - - /** - * Magic toString method - * - * Get the user's username - * - * @return\Instagram\Collection\Collection - * @access public - */ - public function __toString() { - return $this->getUserName(); - } - -} \ No newline at end of file diff --git a/vendor/php-instagram-api/php-instagram-api/composer.json b/vendor/php-instagram-api/php-instagram-api/composer.json deleted file mode 100644 index 7613a4ae1..000000000 --- a/vendor/php-instagram-api/php-instagram-api/composer.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "php-instagram-api/php-instagram-api", - "type": "library", - "description": "PHP Instagram API for PHP 5.3+", - "keywords": ["instagram"], - "homepage": "https://github.com/galen/PHP-Instagram-API", - "license": "MIT", - "authors": [ - { - "name": "Galen Grover", - "email": "galenjr@gmail.com", - "homepage": "http://www.galengrover.com", - "role": "Developer" - } - ], - "require": { - "php": ">=5.3.0" - }, - "autoload": { - "psr-0": { - "Instagram": "." - } - } -} \ No newline at end of file diff --git a/vendor/phpdocumentor/reflection-docblock/.gitignore b/vendor/phpdocumentor/reflection-docblock/.gitignore new file mode 100644 index 000000000..3ce5adbbd --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/.gitignore @@ -0,0 +1,2 @@ +.idea +vendor diff --git a/vendor/phpdocumentor/reflection-docblock/.travis.yml b/vendor/phpdocumentor/reflection-docblock/.travis.yml new file mode 100644 index 000000000..eef782c42 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/.travis.yml @@ -0,0 +1,32 @@ +language: php +php: + - 5.3.3 + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + - hhvm-nightly + +matrix: + allow_failures: + - php: hhvm + - php: hhvm-nightly + +script: + - vendor/bin/phpunit + +before_script: + - sudo apt-get -qq update > /dev/null + - phpenv rehash > /dev/null + - composer selfupdate --quiet + - composer install --no-interaction --prefer-source --dev + - vendor/bin/phpunit + - composer update --no-interaction --prefer-source --dev + +notifications: + irc: "irc.freenode.org#phpdocumentor" + email: + - mike.vanriel@naenius.com + - ashnazg@php.net + - boen.robot@gmail.com diff --git a/vendor/phpdocumentor/reflection-docblock/README.md b/vendor/phpdocumentor/reflection-docblock/README.md new file mode 100644 index 000000000..6405d1a10 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/README.md @@ -0,0 +1,57 @@ +The ReflectionDocBlock Component [![Build Status](https://secure.travis-ci.org/phpDocumentor/ReflectionDocBlock.png)](https://travis-ci.org/phpDocumentor/ReflectionDocBlock) +================================ + +Introduction +------------ + +The ReflectionDocBlock component of phpDocumentor provides a DocBlock parser +that is 100% compatible with the [PHPDoc standard](http://phpdoc.org/docs/latest). + +With this component, a library can provide support for annotations via DocBlocks +or otherwise retrieve information that is embedded in a DocBlock. + +> **Note**: *this is a core component of phpDocumentor and is constantly being +> optimized for performance.* + +Installation +------------ + +You can install the component in the following ways: + +* Use the official Github repository (https://github.com/phpDocumentor/ReflectionDocBlock) +* Via Composer (http://packagist.org/packages/phpdocumentor/reflection-docblock) + +Usage +----- + +The ReflectionDocBlock component is designed to work in an identical fashion to +PHP's own Reflection extension (http://php.net/manual/en/book.reflection.php). + +Parsing can be initiated by instantiating the +`\phpDocumentor\Reflection\DocBlock()` class and passing it a string containing +a DocBlock (including asterisks) or by passing an object supporting the +`getDocComment()` method. + +> *Examples of objects having the `getDocComment()` method are the +> `ReflectionClass` and the `ReflectionMethod` classes of the PHP +> Reflection extension* + +Example: + + $class = new ReflectionClass('MyClass'); + $phpdoc = new \phpDocumentor\Reflection\DocBlock($class); + +or + + $docblock = <<=5.3.3" + }, + "require-dev": { + "athletic/athletic": "~0.1.6", + "phpmd/phpmd": "1.5.*", + "phpunit/phpunit": ">=3.7", + "satooshi/php-coveralls": "~0.6", + "squizlabs/php_codesniffer": "1.4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "LazyMap\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/", + "role": "Developer" + } + ], + "description": "A library that provides lazy instantiation logic for a map of objects", + "homepage": "https://github.com/Ocramius/LazyMap", + "keywords": [ + "lazy", + "lazy instantiation", + "lazy loading", + "map", + "service location" + ], + "time": "2013-11-09 22:30:54" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "6d196af48e8c100a3ae881940123e693da5a9217" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6d196af48e8c100a3ae881940123e693da5a9217", + "reference": "6d196af48e8c100a3ae881940123e693da5a9217", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3.1", + "phpunit/php-text-template": "~1.2.0", + "phpunit/php-token-stream": "~1.2.2", + "sebastian/environment": "~1.0.0", + "sebastian/version": "~1.0.3" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4.0.14" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "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": "2014-08-06 06:39:42" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "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": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2013-10-10 15:34:57" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2014-01-30 17:20:04" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "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": "2013-08-02 07:42:54" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", + "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2014-03-03 05:10:30" + }, + { + "name": "phpunit/phpunit", + "version": "4.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "a33fa68ece9f8c68589bfc2da8d2794e27b820bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a33fa68ece9f8c68589bfc2da8d2794e27b820bc", + "reference": "a33fa68ece9f8c68589bfc2da8d2794e27b820bc", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": "~2.0", + "phpunit/php-file-iterator": "~1.3.1", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0.2", + "phpunit/phpunit-mock-objects": "~2.2", + "sebastian/comparator": "~1.0", + "sebastian/diff": "~1.1", + "sebastian/environment": "~1.0", + "sebastian/exporter": "~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.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2014-08-18 05:12:30" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "42e589e08bc86e3e9bdf20d385e948347788505b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/42e589e08bc86e3e9bdf20d385e948347788505b", + "reference": "42e589e08bc86e3e9bdf20d385e948347788505b", + "shasum": "" + }, + "require": { + "ocramius/instantiator": "~1.0", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "4.2.*@dev" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "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": "2014-08-02 13:50:58" + }, + { + "name": "sebastian/comparator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", + "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.1", + "sebastian/exporter": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.1" + }, + "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", + "role": "lead" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2014-05-02 07:05:58" + }, + { + "name": "sebastian/diff", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", + "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "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", + "role": "lead" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2013-08-03 16:46:33" + }, + { + "name": "sebastian/environment", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/79517609ec01139cd7e9fded0dd7ce08c952ef6a", + "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "4.0.*@dev" + }, + "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", + "role": "lead" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2014-02-18 16:17:19" + }, + { + "name": "sebastian/exporter", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", + "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "4.0.*@dev" + }, + "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", + "role": "lead" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net", + "role": "Lead" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2014-02-16 08:26:31" + }, + { + "name": "sebastian/version", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "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": "2014-03-07 15:35:33" + }, + { + "name": "symfony/yaml", + "version": "v2.5.3", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f", + "reference": "5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2014-08-05 09:00:40" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "platform": { + "php": ">=5.3.3" + }, + "platform-dev": [] +} diff --git a/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist b/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist new file mode 100644 index 000000000..f67ad2a20 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/phpunit.xml.dist @@ -0,0 +1,14 @@ + + + + + + ./tests/ + + + + + ./src/ + + + diff --git a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Type/Collection.php b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Type/Collection.php index 90ead3ff4..327819c2c 100644 --- a/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Type/Collection.php +++ b/vendor/phpdocumentor/reflection-docblock/src/phpDocumentor/Reflection/DocBlock/Type/Collection.php @@ -161,7 +161,8 @@ class Collection extends \ArrayObject $namespace_aliases = $this->context->getNamespaceAliases(); // if the first segment is not an alias; prepend namespace name and // return - if (!isset($namespace_aliases[$type_parts[0]])) { + if (!isset($namespace_aliases[$type_parts[0]]) && + !isset($namespace_aliases[strstr($type_parts[0], '::', true)])) { $namespace = $this->context->getNamespace(); if ('' !== $namespace) { $namespace .= self::OPERATOR_NAMESPACE; @@ -169,6 +170,12 @@ class Collection extends \ArrayObject return self::OPERATOR_NAMESPACE . $namespace . $type; } + if (strpos($type_parts[0], '::')) { + $type_parts[] = strstr($type_parts[0], '::'); + $type_parts[0] = $namespace_aliases[strstr($type_parts[0], '::', true)]; + return implode('', $type_parts); + } + $type_parts[0] = $namespace_aliases[$type_parts[0]]; $type = implode(self::OPERATOR_NAMESPACE, $type_parts); } diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/DescriptionTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/DescriptionTest.php new file mode 100644 index 000000000..a6ca7b37e --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/DescriptionTest.php @@ -0,0 +1,245 @@ + + * @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; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Description + * + * @author Vasil Rangelov + * @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 + */ +class DescriptionTest extends \PHPUnit_Framework_TestCase +{ + public function testConstruct() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(1, $parsedContents); + $this->assertSame($fixture, $parsedContents[0]); + } + + public function testInlineTagParsing() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + $this->assertSame('This is text for a ', $parsedContents[0]); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag\LinkTag', + $parsedContents[1] + ); + $this->assertSame( + ' that uses inline +tags.', + $parsedContents[2] + ); + } + + public function testInlineTagAtStartParsing() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + + $this->assertSame('', $parsedContents[0]); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag\LinkTag', + $parsedContents[1] + ); + $this->assertSame( + ' is text for a description that uses inline +tags.', + $parsedContents[2] + ); + } + + public function testNestedInlineTagParsing() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + + $this->assertSame( + 'This is text for a description with ', + $parsedContents[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $parsedContents[1] + ); + $this->assertSame('.', $parsedContents[2]); + + $parsedDescription = $parsedContents[1]->getParsedDescription(); + $this->assertCount(3, $parsedDescription); + $this->assertSame("inline tag with\n", $parsedDescription[0]); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag\LinkTag', + $parsedDescription[1] + ); + $this->assertSame(' in it', $parsedDescription[2]); + } + + public function testLiteralOpeningDelimiter() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(1, $parsedContents); + $this->assertSame($fixture, $parsedContents[0]); + } + + public function testNestedLiteralOpeningDelimiter() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + $this->assertSame( + 'This is text for a description containing ', + $parsedContents[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $parsedContents[1] + ); + $this->assertSame('.', $parsedContents[2]); + + $this->assertSame( + array('inline tag that has { that +is literal'), + $parsedContents[1]->getParsedDescription() + ); + } + + public function testLiteralClosingDelimiter() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(1, $parsedContents); + $this->assertSame( + 'This is text for a description with } that is not a tag.', + $parsedContents[0] + ); + } + + public function testNestedLiteralClosingDelimiter() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + $this->assertSame( + 'This is text for a description with ', + $parsedContents[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $parsedContents[1] + ); + $this->assertSame('.', $parsedContents[2]); + + $this->assertSame( + array('inline tag with } that is not an +inline tag'), + $parsedContents[1]->getParsedDescription() + ); + } + + public function testInlineTagEscapingSequence() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(1, $parsedContents); + $this->assertSame( + 'This is text for a description with literal {@link}.', + $parsedContents[0] + ); + } + + public function testNestedInlineTagEscapingSequence() + { + $fixture = <<assertSame($fixture, $object->getContents()); + + $parsedContents = $object->getParsedContents(); + $this->assertCount(3, $parsedContents); + $this->assertSame( + 'This is text for a description with an ', + $parsedContents[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $parsedContents[1] + ); + $this->assertSame('.', $parsedContents[2]); + + $this->assertSame( + array('inline tag with literal +{@link} in it'), + $parsedContents[1]->getParsedDescription() + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/CoversTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/CoversTagTest.php new file mode 100644 index 000000000..ff257aa19 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/CoversTagTest.php @@ -0,0 +1,86 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\CoversTag + * + * @author Daniel O'Connor + * @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 + */ +class CoversTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\CoversTag can create + * a link for the covers doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exReference + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\CoversTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exReference + ) { + $tag = new CoversTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exReference, $tag->getReference()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exReference + return array( + array( + 'covers', + 'Foo::bar()', + 'Foo::bar()', + '', + 'Foo::bar()' + ), + array( + 'covers', + 'Foo::bar() Testing', + 'Foo::bar() Testing', + 'Testing', + 'Foo::bar()', + ), + array( + 'covers', + 'Foo::bar() Testing comments', + 'Foo::bar() Testing comments', + 'Testing comments', + 'Foo::bar()', + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTagTest.php new file mode 100644 index 000000000..7a75e79ce --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTagTest.php @@ -0,0 +1,115 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag + * + * @author Vasil Rangelov + * @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 + */ +class DeprecatedTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\LinkTag can create + * a link for the @deprecated doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exDescription + * @param string $exVersion + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exVersion + ) { + $tag = new DeprecatedTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exVersion, $tag->getVersion()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exVersion + return array( + array( + 'deprecated', + '1.0 First release.', + '1.0 First release.', + 'First release.', + '1.0' + ), + array( + 'deprecated', + "1.0\nFirst release.", + "1.0\nFirst release.", + 'First release.', + '1.0' + ), + array( + 'deprecated', + "1.0\nFirst\nrelease.", + "1.0\nFirst\nrelease.", + "First\nrelease.", + '1.0' + ), + array( + 'deprecated', + 'Unfinished release', + 'Unfinished release', + 'Unfinished release', + '' + ), + array( + 'deprecated', + '1.0', + '1.0', + '', + '1.0' + ), + array( + 'deprecated', + 'GIT: $Id$', + 'GIT: $Id$', + '', + 'GIT: $Id$' + ), + array( + 'deprecated', + 'GIT: $Id$ Dev build', + 'GIT: $Id$ Dev build', + 'Dev build', + 'GIT: $Id$' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ExampleTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ExampleTagTest.php new file mode 100644 index 000000000..519a61b3a --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ExampleTagTest.php @@ -0,0 +1,203 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\ExampleTag + * + * @author Vasil Rangelov + * @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 + */ +class ExampleTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\SourceTag can + * understand the @source DocBlock. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exStartingLine + * @param string $exLineCount + * @param string $exFilepath + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\ExampleTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exStartingLine, + $exLineCount, + $exFilePath + ) { + $tag = new ExampleTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exStartingLine, $tag->getStartingLine()); + $this->assertEquals($exLineCount, $tag->getLineCount()); + $this->assertEquals($exFilePath, $tag->getFilePath()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, + // $content, + // $exContent, + // $exDescription, + // $exStartingLine, + // $exLineCount, + // $exFilePath + return array( + array( + 'example', + 'file.php', + 'file.php', + '', + 1, + null, + 'file.php' + ), + array( + 'example', + 'Testing comments', + 'Testing comments', + 'comments', + 1, + null, + 'Testing' + ), + array( + 'example', + 'file.php 2 Testing', + 'file.php 2 Testing', + 'Testing', + 2, + null, + 'file.php' + ), + array( + 'example', + 'file.php 2 3 Testing comments', + 'file.php 2 3 Testing comments', + 'Testing comments', + 2, + 3, + 'file.php' + ), + array( + 'example', + 'file.php 2 -1 Testing comments', + 'file.php 2 -1 Testing comments', + '-1 Testing comments', + 2, + null, + 'file.php' + ), + array( + 'example', + 'file.php -1 1 Testing comments', + 'file.php -1 1 Testing comments', + '-1 1 Testing comments', + 1, + null, + 'file.php' + ), + array( + 'example', + '"file with spaces.php" Testing comments', + '"file with spaces.php" Testing comments', + 'Testing comments', + 1, + null, + 'file with spaces.php' + ), + array( + 'example', + '"file with spaces.php" 2 Testing comments', + '"file with spaces.php" 2 Testing comments', + 'Testing comments', + 2, + null, + 'file with spaces.php' + ), + array( + 'example', + '"file with spaces.php" 2 3 Testing comments', + '"file with spaces.php" 2 3 Testing comments', + 'Testing comments', + 2, + 3, + 'file with spaces.php' + ), + array( + 'example', + '"file with spaces.php" 2 -3 Testing comments', + '"file with spaces.php" 2 -3 Testing comments', + '-3 Testing comments', + 2, + null, + 'file with spaces.php' + ), + array( + 'example', + '"file with spaces.php" -2 3 Testing comments', + '"file with spaces.php" -2 3 Testing comments', + '-2 3 Testing comments', + 1, + null, + 'file with spaces.php' + ), + array( + 'example', + 'file%20with%20spaces.php Testing comments', + 'file%20with%20spaces.php Testing comments', + 'Testing comments', + 1, + null, + 'file with spaces.php' + ), + array( + 'example', + 'folder/file%20with%20spaces.php Testing comments', + 'folder/file%20with%20spaces.php Testing comments', + 'Testing comments', + 1, + null, + 'folder/file with spaces.php' + ), + array( + 'example', + 'http://example.com/file%20with%20spaces.php Testing comments', + 'http://example.com/file%20with%20spaces.php Testing comments', + 'Testing comments', + 1, + null, + 'http://example.com/file%20with%20spaces.php' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/LinkTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/LinkTagTest.php new file mode 100644 index 000000000..0c64ed086 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/LinkTagTest.php @@ -0,0 +1,87 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\LinkTag + * + * @author Ben Selby + * @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 + */ +class LinkTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\LinkTag can create + * a link for the @link doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exDescription + * @param string $exLink + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\LinkTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exLink + ) { + $tag = new LinkTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exLink, $tag->getLink()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exLink + return array( + array( + 'link', + 'http://www.phpdoc.org/', + 'http://www.phpdoc.org/', + 'http://www.phpdoc.org/', + 'http://www.phpdoc.org/' + ), + array( + 'link', + 'http://www.phpdoc.org/ Testing', + 'http://www.phpdoc.org/ Testing', + 'Testing', + 'http://www.phpdoc.org/' + ), + array( + 'link', + 'http://www.phpdoc.org/ Testing comments', + 'http://www.phpdoc.org/ Testing comments', + 'Testing comments', + 'http://www.phpdoc.org/' + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/MethodTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/MethodTagTest.php new file mode 100644 index 000000000..efc3a15b5 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/MethodTagTest.php @@ -0,0 +1,146 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\MethodTag + * + * @author Mike van Riel + * @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 + */ +class MethodTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * @param string $signature The signature to test. + * @param bool $valid Whether the given signature is expected to + * be valid. + * @param string $expected_name The method name that is expected from this + * signature. + * @param string $expected_return The return type that is expected from this + * signature. + * @param bool $paramCount Number of parameters in the signature. + * @param string $description The short description mentioned in the + * signature. + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\MethodTag + * @dataProvider getTestSignatures + * + * @return void + */ + public function testConstruct( + $signature, + $valid, + $expected_name, + $expected_return, + $expected_isStatic, + $paramCount, + $description + ) { + ob_start(); + $tag = new MethodTag('method', $signature); + $stdout = ob_get_clean(); + + $this->assertSame( + $valid, + empty($stdout), + 'No error should have been output if the signature is valid' + ); + + if (!$valid) { + return; + } + + $this->assertEquals($expected_name, $tag->getMethodName()); + $this->assertEquals($expected_return, $tag->getType()); + $this->assertEquals($description, $tag->getDescription()); + $this->assertEquals($expected_isStatic, $tag->isStatic()); + $this->assertCount($paramCount, $tag->getArguments()); + } + + public function getTestSignatures() + { + return array( + // TODO: Verify this case +// array( +// 'foo', +// false, 'foo', '', false, 0, '' +// ), + array( + 'foo()', + true, 'foo', 'void', false, 0, '' + ), + array( + 'foo() description', + true, 'foo', 'void', false, 0, 'description' + ), + array( + 'int foo()', + true, 'foo', 'int', false, 0, '' + ), + array( + 'int foo() description', + true, 'foo', 'int', false, 0, 'description' + ), + array( + 'int foo($a, $b)', + true, 'foo', 'int', false, 2, '' + ), + array( + 'int foo() foo(int $a, int $b)', + true, 'foo', 'int', false, 2, '' + ), + array( + 'int foo(int $a, int $b)', + true, 'foo', 'int', false, 2, '' + ), + array( + 'null|int foo(int $a, int $b)', + true, 'foo', 'null|int', false, 2, '' + ), + array( + 'int foo(null|int $a, int $b)', + true, 'foo', 'int', false, 2, '' + ), + array( + '\Exception foo() foo(Exception $a, Exception $b)', + true, 'foo', '\Exception', false, 2, '' + ), + array( + 'int foo() foo(Exception $a, Exception $b) description', + true, 'foo', 'int', false, 2, 'description' + ), + array( + 'int foo() foo(\Exception $a, \Exception $b) description', + true, 'foo', 'int', false, 2, 'description' + ), + array( + 'void()', + true, 'void', 'void', false, 0, '' + ), + array( + 'static foo()', + true, 'foo', 'static', false, 0, '' + ), + array( + 'static void foo()', + true, 'foo', 'void', true, 0, '' + ), + array( + 'static static foo()', + true, 'foo', 'static', true, 0, '' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ParamTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ParamTagTest.php new file mode 100644 index 000000000..0e05382fa --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ParamTagTest.php @@ -0,0 +1,118 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\ParamTag + * + * @author Mike van Riel + * @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 + */ +class ParamTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\ParamTag can + * understand the @param DocBlock. + * + * @param string $type + * @param string $content + * @param string $extractedType + * @param string $extractedTypes + * @param string $extractedVarName + * @param string $extractedDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\ParamTag + * @dataProvider provideDataForConstructor + * + * @return void + */ + public function testConstructorParsesInputsIntoCorrectFields( + $type, + $content, + $extractedType, + $extractedTypes, + $extractedVarName, + $extractedDescription + ) { + $tag = new ParamTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($extractedType, $tag->getType()); + $this->assertEquals($extractedTypes, $tag->getTypes()); + $this->assertEquals($extractedVarName, $tag->getVariableName()); + $this->assertEquals($extractedDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParsesInputsIntoCorrectFields() + * + * @return array + */ + public function provideDataForConstructor() + { + return array( + array('param', 'int', 'int', array('int'), '', ''), + array('param', '$bob', '', array(), '$bob', ''), + array( + 'param', + 'int Number of bobs', + 'int', + array('int'), + '', + 'Number of bobs' + ), + array( + 'param', + 'int $bob', + 'int', + array('int'), + '$bob', + '' + ), + array( + 'param', + 'int $bob Number of bobs', + 'int', + array('int'), + '$bob', + 'Number of bobs' + ), + array( + 'param', + "int Description \n on multiple lines", + 'int', + array('int'), + '', + "Description \n on multiple lines" + ), + array( + 'param', + "int \n\$bob Variable name on a new line", + 'int', + array('int'), + '$bob', + "Variable name on a new line" + ), + array( + 'param', + "\nint \$bob Type on a new line", + 'int', + array('int'), + '$bob', + "Type on a new line" + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ReturnTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ReturnTagTest.php new file mode 100644 index 000000000..9e2aec0d1 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ReturnTagTest.php @@ -0,0 +1,102 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\ReturnTag + * + * @author Mike van Riel + * @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 + */ +class ReturnTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\ReturnTag can + * understand the @return DocBlock. + * + * @param string $type + * @param string $content + * @param string $extractedType + * @param string $extractedTypes + * @param string $extractedDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\ReturnTag + * @dataProvider provideDataForConstructor + * + * @return void + */ + public function testConstructorParsesInputsIntoCorrectFields( + $type, + $content, + $extractedType, + $extractedTypes, + $extractedDescription + ) { + $tag = new ReturnTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($extractedType, $tag->getType()); + $this->assertEquals($extractedTypes, $tag->getTypes()); + $this->assertEquals($extractedDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParsesInputsIntoCorrectFields() + * + * @return array + */ + public function provideDataForConstructor() + { + return array( + array('return', '', '', array(), ''), + array('return', 'int', 'int', array('int'), ''), + array( + 'return', + 'int Number of Bobs', + 'int', + array('int'), + 'Number of Bobs' + ), + array( + 'return', + 'int|double Number of Bobs', + 'int|double', + array('int', 'double'), + 'Number of Bobs' + ), + array( + 'return', + "int Number of \n Bobs", + 'int', + array('int'), + "Number of \n Bobs" + ), + array( + 'return', + " int Number of Bobs", + 'int', + array('int'), + "Number of Bobs" + ), + array( + 'return', + "int\nNumber of Bobs", + 'int', + array('int'), + "Number of Bobs" + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SeeTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SeeTagTest.php new file mode 100644 index 000000000..6829b0460 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SeeTagTest.php @@ -0,0 +1,86 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\SeeTag + * + * @author Daniel O'Connor + * @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 + */ +class SeeTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the phpDocumentor_Reflection_DocBlock_Tag_See can create a link + * for the @see doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exReference + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\SeeTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exReference + ) { + $tag = new SeeTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exReference, $tag->getReference()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exReference + return array( + array( + 'see', + 'Foo::bar()', + 'Foo::bar()', + '', + 'Foo::bar()' + ), + array( + 'see', + 'Foo::bar() Testing', + 'Foo::bar() Testing', + 'Testing', + 'Foo::bar()', + ), + array( + 'see', + 'Foo::bar() Testing comments', + 'Foo::bar() Testing comments', + 'Testing comments', + 'Foo::bar()', + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SinceTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SinceTagTest.php new file mode 100644 index 000000000..8caf25d1c --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SinceTagTest.php @@ -0,0 +1,115 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\SinceTag + * + * @author Vasil Rangelov + * @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 + */ +class SinceTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\LinkTag can create + * a link for the @since doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exDescription + * @param string $exVersion + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\SinceTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exVersion + ) { + $tag = new SinceTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exVersion, $tag->getVersion()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exVersion + return array( + array( + 'since', + '1.0 First release.', + '1.0 First release.', + 'First release.', + '1.0' + ), + array( + 'since', + "1.0\nFirst release.", + "1.0\nFirst release.", + 'First release.', + '1.0' + ), + array( + 'since', + "1.0\nFirst\nrelease.", + "1.0\nFirst\nrelease.", + "First\nrelease.", + '1.0' + ), + array( + 'since', + 'Unfinished release', + 'Unfinished release', + 'Unfinished release', + '' + ), + array( + 'since', + '1.0', + '1.0', + '', + '1.0' + ), + array( + 'since', + 'GIT: $Id$', + 'GIT: $Id$', + '', + 'GIT: $Id$' + ), + array( + 'since', + 'GIT: $Id$ Dev build', + 'GIT: $Id$ Dev build', + 'Dev build', + 'GIT: $Id$' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SourceTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SourceTagTest.php new file mode 100644 index 000000000..2a40e0aa3 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/SourceTagTest.php @@ -0,0 +1,116 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\SourceTag + * + * @author Vasil Rangelov + * @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 + */ +class SourceTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\SourceTag can + * understand the @source DocBlock. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exStartingLine + * @param string $exLineCount + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\SourceTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exStartingLine, + $exLineCount + ) { + $tag = new SourceTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exStartingLine, $tag->getStartingLine()); + $this->assertEquals($exLineCount, $tag->getLineCount()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exStartingLine, $exLineCount + return array( + array( + 'source', + '2', + '2', + '', + 2, + null + ), + array( + 'source', + 'Testing', + 'Testing', + 'Testing', + 1, + null + ), + array( + 'source', + '2 Testing', + '2 Testing', + 'Testing', + 2, + null + ), + array( + 'source', + '2 3 Testing comments', + '2 3 Testing comments', + 'Testing comments', + 2, + 3 + ), + array( + 'source', + '2 -1 Testing comments', + '2 -1 Testing comments', + '-1 Testing comments', + 2, + null + ), + array( + 'source', + '-1 1 Testing comments', + '-1 1 Testing comments', + '-1 1 Testing comments', + 1, + null + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTagTest.php new file mode 100644 index 000000000..3c669d558 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTagTest.php @@ -0,0 +1,102 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\ThrowsTag + * + * @author Mike van Riel + * @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 + */ +class ThrowsTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag can + * understand the @throws DocBlock. + * + * @param string $type + * @param string $content + * @param string $extractedType + * @param string $extractedTypes + * @param string $extractedDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag + * @dataProvider provideDataForConstructor + * + * @return void + */ + public function testConstructorParsesInputsIntoCorrectFields( + $type, + $content, + $extractedType, + $extractedTypes, + $extractedDescription + ) { + $tag = new ThrowsTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($extractedType, $tag->getType()); + $this->assertEquals($extractedTypes, $tag->getTypes()); + $this->assertEquals($extractedDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParsesInputsIntoCorrectFields() + * + * @return array + */ + public function provideDataForConstructor() + { + return array( + array('throws', '', '', array(), ''), + array('throws', 'int', 'int', array('int'), ''), + array( + 'throws', + 'int Number of Bobs', + 'int', + array('int'), + 'Number of Bobs' + ), + array( + 'throws', + 'int|double Number of Bobs', + 'int|double', + array('int', 'double'), + 'Number of Bobs' + ), + array( + 'throws', + "int Number of \n Bobs", + 'int', + array('int'), + "Number of \n Bobs" + ), + array( + 'throws', + " int Number of Bobs", + 'int', + array('int'), + "Number of Bobs" + ), + array( + 'throws', + "int\nNumber of Bobs", + 'int', + array('int'), + "Number of Bobs" + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/UsesTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/UsesTagTest.php new file mode 100644 index 000000000..45868d73e --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/UsesTagTest.php @@ -0,0 +1,86 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\UsesTag + * + * @author Daniel O'Connor + * @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 + */ +class UsesTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\UsesTag can create + * a link for the @uses doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exReference + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\UsesTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exReference + ) { + $tag = new UsesTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exReference, $tag->getReference()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exReference + return array( + array( + 'uses', + 'Foo::bar()', + 'Foo::bar()', + '', + 'Foo::bar()' + ), + array( + 'uses', + 'Foo::bar() Testing', + 'Foo::bar() Testing', + 'Testing', + 'Foo::bar()', + ), + array( + 'uses', + 'Foo::bar() Testing comments', + 'Foo::bar() Testing comments', + 'Testing comments', + 'Foo::bar()', + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VarTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VarTagTest.php new file mode 100644 index 000000000..9ae2aa5f7 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VarTagTest.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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\VarTag + * + * @author Daniel O'Connor + * @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 + */ +class VarTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\VarTag can + * understand the @var doc block. + * + * @param string $type + * @param string $content + * @param string $exType + * @param string $exVariable + * @param string $exDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\VarTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exType, + $exVariable, + $exDescription + ) { + $tag = new VarTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exType, $tag->getType()); + $this->assertEquals($exVariable, $tag->getVariableName()); + $this->assertEquals($exDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exType, $exVariable, $exDescription + return array( + array( + 'var', + 'int', + 'int', + '', + '' + ), + array( + 'var', + 'int $bob', + 'int', + '$bob', + '' + ), + array( + 'var', + 'int $bob Number of bobs', + 'int', + '$bob', + 'Number of bobs' + ), + array( + 'var', + '', + '', + '', + '' + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VersionTagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VersionTagTest.php new file mode 100644 index 000000000..e145386d4 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Tag/VersionTagTest.php @@ -0,0 +1,115 @@ + + * @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\Tag; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\VersionTag + * + * @author Vasil Rangelov + * @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 + */ +class VersionTagTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\LinkTag can create + * a link for the @version doc block. + * + * @param string $type + * @param string $content + * @param string $exContent + * @param string $exDescription + * @param string $exVersion + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag\VersionTag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exContent, + $exDescription, + $exVersion + ) { + $tag = new VersionTag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($exContent, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + $this->assertEquals($exVersion, $tag->getVersion()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exContent, $exDescription, $exVersion + return array( + array( + 'version', + '1.0 First release.', + '1.0 First release.', + 'First release.', + '1.0' + ), + array( + 'version', + "1.0\nFirst release.", + "1.0\nFirst release.", + 'First release.', + '1.0' + ), + array( + 'version', + "1.0\nFirst\nrelease.", + "1.0\nFirst\nrelease.", + "First\nrelease.", + '1.0' + ), + array( + 'version', + 'Unfinished release', + 'Unfinished release', + 'Unfinished release', + '' + ), + array( + 'version', + '1.0', + '1.0', + '', + '1.0' + ), + array( + 'version', + 'GIT: $Id$', + 'GIT: $Id$', + '', + 'GIT: $Id$' + ), + array( + 'version', + 'GIT: $Id$ Dev build', + 'GIT: $Id$ Dev build', + 'Dev build', + 'GIT: $Id$' + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/TagTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/TagTest.php new file mode 100644 index 000000000..9e873ecb5 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/TagTest.php @@ -0,0 +1,313 @@ + + * @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; + +use phpDocumentor\Reflection\DocBlock; +use phpDocumentor\Reflection\DocBlock\Context; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Tag\VarTag + * + * @author Daniel O'Connor + * @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 + */ +class TagTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @expectedException \InvalidArgumentException + * + * @return void + */ + public function testInvalidTagLine() + { + Tag::createInstance('Invalid tag line'); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * + * @return void + */ + public function testTagHandlerUnregistration() + { + $currentHandler = __NAMESPACE__ . '\Tag\VarTag'; + $tagPreUnreg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPreUnreg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreUnreg + ); + + Tag::registerTagHandler('var', null); + + $tagPostUnreg = Tag::createInstance('@var mixed'); + $this->assertNotInstanceOf( + $currentHandler, + $tagPostUnreg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostUnreg + ); + + Tag::registerTagHandler('var', $currentHandler); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * + * @return void + */ + public function testTagHandlerCorrectRegistration() + { + if (0 == ini_get('allow_url_include')) { + $this->markTestSkipped('"data" URIs for includes are required.'); + } + $currentHandler = __NAMESPACE__ . '\Tag\VarTag'; + $tagPreReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPreReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + + include 'data:text/plain;base64,'. base64_encode( +<<assertTrue(Tag::registerTagHandler('var', '\MyTagHandler')); + + $tagPostReg = Tag::createInstance('@var mixed'); + $this->assertNotInstanceOf( + $currentHandler, + $tagPostReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + $this->assertInstanceOf( + '\MyTagHandler', + $tagPostReg + ); + + $this->assertTrue(Tag::registerTagHandler('var', $currentHandler)); + } + + /** + * @depends testTagHandlerCorrectRegistration + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * @covers \phpDocumentor\Reflection\DocBlock\Tag::createInstance + * + * @return void + */ + public function testNamespacedTagHandlerCorrectRegistration() + { + $tagPreReg = Tag::createInstance('@T something'); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + $this->assertNotInstanceOf( + '\MyTagHandler', + $tagPreReg + ); + + $this->assertTrue( + Tag::registerTagHandler('\MyNamespace\MyTag', '\MyTagHandler') + ); + + $tagPostReg = Tag::createInstance( + '@T something', + new DocBlock( + '', + new Context('', array('T' => '\MyNamespace\MyTag')) + ) + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + $this->assertInstanceOf( + '\MyTagHandler', + $tagPostReg + ); + + $this->assertTrue( + Tag::registerTagHandler('\MyNamespace\MyTag', null) + ); + } + + /** + * @depends testTagHandlerCorrectRegistration + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * @covers \phpDocumentor\Reflection\DocBlock\Tag::createInstance + * + * @return void + */ + public function testNamespacedTagHandlerIncorrectRegistration() + { + $tagPreReg = Tag::createInstance('@T something'); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + $this->assertNotInstanceOf( + '\MyTagHandler', + $tagPreReg + ); + + $this->assertFalse( + Tag::registerTagHandler('MyNamespace\MyTag', '\MyTagHandler') + ); + + $tagPostReg = Tag::createInstance( + '@T something', + new DocBlock( + '', + new Context('', array('T' => '\MyNamespace\MyTag')) + ) + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + $this->assertNotInstanceOf( + '\MyTagHandler', + $tagPostReg + ); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * + * @return void + */ + public function testNonExistentTagHandlerRegistration() + { + $currentHandler = __NAMESPACE__ . '\Tag\VarTag'; + $tagPreReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPreReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + + $this->assertFalse(Tag::registerTagHandler('var', 'Non existent')); + + $tagPostReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPostReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock\Tag::registerTagHandler + * + * @return void + */ + public function testIncompatibleTagHandlerRegistration() + { + $currentHandler = __NAMESPACE__ . '\Tag\VarTag'; + $tagPreReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPreReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPreReg + ); + + $this->assertFalse( + Tag::registerTagHandler('var', __NAMESPACE__ . '\TagTest') + ); + + $tagPostReg = Tag::createInstance('@var mixed'); + $this->assertInstanceOf( + $currentHandler, + $tagPostReg + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\Tag', + $tagPostReg + ); + } + + /** + * Test that the \phpDocumentor\Reflection\DocBlock\Tag\VarTag can + * understand the @var doc block. + * + * @param string $type + * @param string $content + * @param string $exDescription + * + * @covers \phpDocumentor\Reflection\DocBlock\Tag + * @dataProvider provideDataForConstuctor + * + * @return void + */ + public function testConstructorParesInputsIntoCorrectFields( + $type, + $content, + $exDescription + ) { + $tag = new Tag($type, $content); + + $this->assertEquals($type, $tag->getName()); + $this->assertEquals($content, $tag->getContent()); + $this->assertEquals($exDescription, $tag->getDescription()); + } + + /** + * Data provider for testConstructorParesInputsIntoCorrectFields + * + * @return array + */ + public function provideDataForConstuctor() + { + // $type, $content, $exDescription + return array( + array( + 'unknown', + 'some content', + 'some content', + ), + array( + 'unknown', + '', + '', + ) + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Type/CollectionTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Type/CollectionTest.php new file mode 100644 index 000000000..383a6c01f --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlock/Type/CollectionTest.php @@ -0,0 +1,253 @@ + + * @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\Type; + +use phpDocumentor\Reflection\DocBlock\Context; + +/** + * Test class for \phpDocumentor\Reflection\DocBlock\Type\Collection + * + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection + * + * @author Mike van Riel + * @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 + */ +class CollectionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::__construct + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::getContext + * + * @return void + */ + public function testConstruct() + { + $collection = new Collection(); + $this->assertCount(0, $collection); + $this->assertEquals('', $collection->getContext()->getNamespace()); + $this->assertCount(0, $collection->getContext()->getNamespaceAliases()); + } + + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::__construct + * + * @return void + */ + public function testConstructWithTypes() + { + $collection = new Collection(array('integer', 'string')); + $this->assertCount(2, $collection); + } + + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::__construct + * + * @return void + */ + public function testConstructWithNamespace() + { + $collection = new Collection(array(), new Context('\My\Space')); + $this->assertEquals('My\Space', $collection->getContext()->getNamespace()); + + $collection = new Collection(array(), new Context('My\Space')); + $this->assertEquals('My\Space', $collection->getContext()->getNamespace()); + + $collection = new Collection(array(), null); + $this->assertEquals('', $collection->getContext()->getNamespace()); + } + + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::__construct + * + * @return void + */ + public function testConstructWithNamespaceAliases() + { + $fixture = array('a' => 'b'); + $collection = new Collection(array(), new Context(null, $fixture)); + $this->assertEquals( + array('a' => '\b'), + $collection->getContext()->getNamespaceAliases() + ); + } + + /** + * @param string $fixture + * @param array $expected + * + * @dataProvider provideTypesToExpand + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::add + * + * @return void + */ + public function testAdd($fixture, $expected) + { + $collection = new Collection( + array(), + new Context('\My\Space', array('Alias' => '\My\Space\Aliasing')) + ); + $collection->add($fixture); + + $this->assertSame($expected, $collection->getArrayCopy()); + } + + /** + * @param string $fixture + * @param array $expected + * + * @dataProvider provideTypesToExpandWithoutNamespace + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::add + * + * @return void + */ + public function testAddWithoutNamespace($fixture, $expected) + { + $collection = new Collection( + array(), + new Context(null, array('Alias' => '\My\Space\Aliasing')) + ); + $collection->add($fixture); + + $this->assertSame($expected, $collection->getArrayCopy()); + } + + /** + * @param string $fixture + * @param array $expected + * + * @dataProvider provideTypesToExpandWithPropertyOrMethod + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::add + * + * @return void + */ + public function testAddMethodsAndProperties($fixture, $expected) + { + $collection = new Collection( + array(), + new Context(null, array('LinkDescriptor' => '\phpDocumentor\LinkDescriptor')) + ); + $collection->add($fixture); + + $this->assertSame($expected, $collection->getArrayCopy()); + } + + /** + * @covers phpDocumentor\Reflection\DocBlock\Type\Collection::add + * @expectedException InvalidArgumentException + * + * @return void + */ + public function testAddWithInvalidArgument() + { + $collection = new Collection(); + $collection->add(array()); + } + + /** + * Returns the types and their expected values to test the retrieval of + * types. + * + * @param string $method Name of the method consuming this data provider. + * @param string $namespace Name of the namespace to user as basis. + * + * @return string[] + */ + public function provideTypesToExpand($method, $namespace = '\My\Space\\') + { + return array( + array('', array()), + array(' ', array()), + array('int', array('int')), + array('int ', array('int')), + array('string', array('string')), + array('DocBlock', array($namespace.'DocBlock')), + array('DocBlock[]', array($namespace.'DocBlock[]')), + array(' DocBlock ', array($namespace.'DocBlock')), + array('\My\Space\DocBlock', array('\My\Space\DocBlock')), + array('Alias\DocBlock', array('\My\Space\Aliasing\DocBlock')), + array( + 'DocBlock|Tag', + array($namespace .'DocBlock', $namespace .'Tag') + ), + array( + 'DocBlock|null', + array($namespace.'DocBlock', 'null') + ), + array( + '\My\Space\DocBlock|Tag', + array('\My\Space\DocBlock', $namespace.'Tag') + ), + array( + 'DocBlock[]|null', + array($namespace.'DocBlock[]', 'null') + ), + array( + 'DocBlock[]|int[]', + array($namespace.'DocBlock[]', 'int[]') + ), + array( + 'LinkDescriptor::setLink()', + array($namespace.'LinkDescriptor::setLink()') + ), + array( + 'Alias\LinkDescriptor::setLink()', + array('\My\Space\Aliasing\LinkDescriptor::setLink()') + ), + ); + } + + /** + * Returns the types and their expected values to test the retrieval of + * types when no namespace is available. + * + * @param string $method Name of the method consuming this data provider. + * + * @return string[] + */ + public function provideTypesToExpandWithoutNamespace($method) + { + return $this->provideTypesToExpand($method, '\\'); + } + + /** + * Returns the method and property types and their expected values to test + * the retrieval of types. + * + * @param string $method Name of the method consuming this data provider. + * + * @return string[] + */ + public function provideTypesToExpandWithPropertyOrMethod($method) + { + return array( + array( + 'LinkDescriptor::setLink()', + array('\phpDocumentor\LinkDescriptor::setLink()') + ), + array( + 'phpDocumentor\LinkDescriptor::setLink()', + array('\phpDocumentor\LinkDescriptor::setLink()') + ), + array( + 'LinkDescriptor::$link', + array('\phpDocumentor\LinkDescriptor::$link') + ), + array( + 'phpDocumentor\LinkDescriptor::$link', + array('\phpDocumentor\LinkDescriptor::$link') + ), + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlockTest.php b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlockTest.php new file mode 100644 index 000000000..30eedfc58 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/tests/phpDocumentor/Reflection/DocBlockTest.php @@ -0,0 +1,337 @@ + + * @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; + +use phpDocumentor\Reflection\DocBlock\Context; +use phpDocumentor\Reflection\DocBlock\Location; +use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag; + +/** + * Test class for phpDocumentor\Reflection\DocBlock + * + * @author Mike van Riel + * @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 + */ +class DocBlockTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers \phpDocumentor\Reflection\DocBlock + * + * @return void + */ + public function testConstruct() + { + $fixture = << '\phpDocumentor')), + new Location(2) + ); + $this->assertEquals( + 'This is a short description', + $object->getShortDescription() + ); + $this->assertEquals( + 'This is a long description', + $object->getLongDescription()->getContents() + ); + $this->assertCount(2, $object->getTags()); + $this->assertTrue($object->hasTag('see')); + $this->assertTrue($object->hasTag('return')); + $this->assertFalse($object->hasTag('category')); + + $this->assertSame('MyNamespace', $object->getContext()->getNamespace()); + $this->assertSame( + array('PHPDoc' => '\phpDocumentor'), + $object->getContext()->getNamespaceAliases() + ); + $this->assertSame(2, $object->getLocation()->getLineNumber()); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::splitDocBlock + * + * @return void + */ + public function testConstructWithTagsOnly() + { + $fixture = <<assertEquals('', $object->getShortDescription()); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertCount(2, $object->getTags()); + $this->assertTrue($object->hasTag('see')); + $this->assertTrue($object->hasTag('return')); + $this->assertFalse($object->hasTag('category')); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::isTemplateStart + */ + public function testIfStartOfTemplateIsDiscovered() + { + $fixture = <<assertEquals('', $object->getShortDescription()); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertCount(2, $object->getTags()); + $this->assertTrue($object->hasTag('see')); + $this->assertTrue($object->hasTag('return')); + $this->assertFalse($object->hasTag('category')); + $this->assertTrue($object->isTemplateStart()); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::isTemplateEnd + */ + public function testIfEndOfTemplateIsDiscovered() + { + $fixture = <<assertEquals('', $object->getShortDescription()); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertTrue($object->isTemplateEnd()); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::cleanInput + * + * @return void + */ + public function testConstructOneLiner() + { + $fixture = '/** Short description and nothing more. */'; + $object = new DocBlock($fixture); + $this->assertEquals( + 'Short description and nothing more.', + $object->getShortDescription() + ); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertCount(0, $object->getTags()); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::__construct + * + * @return void + */ + public function testConstructFromReflector() + { + $object = new DocBlock(new \ReflectionClass($this)); + $this->assertEquals( + 'Test class for phpDocumentor\Reflection\DocBlock', + $object->getShortDescription() + ); + $this->assertEquals('', $object->getLongDescription()->getContents()); + $this->assertCount(4, $object->getTags()); + $this->assertTrue($object->hasTag('author')); + $this->assertTrue($object->hasTag('copyright')); + $this->assertTrue($object->hasTag('license')); + $this->assertTrue($object->hasTag('link')); + $this->assertFalse($object->hasTag('category')); + } + + /** + * @expectedException \InvalidArgumentException + * + * @return void + */ + public function testExceptionOnInvalidObject() + { + new DocBlock($this); + } + + public function testDotSeperation() + { + $fixture = <<assertEquals( + 'This is a short description.', + $object->getShortDescription() + ); + $this->assertEquals( + "This is a long description.\nThis is a continuation of the long " + ."description.", + $object->getLongDescription()->getContents() + ); + } + + /** + * @covers \phpDocumentor\Reflection\DocBlock::parseTags + * @expectedException \LogicException + * + * @return void + */ + public function testInvalidTagBlock() + { + if (0 == ini_get('allow_url_include')) { + $this->markTestSkipped('"data" URIs for includes are required.'); + } + + include 'data:text/plain;base64,'. base64_encode( + <<assertEquals( + 'This is a short description.', + $object->getShortDescription() + ); + $this->assertEquals( + 'This is a long description.', + $object->getLongDescription()->getContents() + ); + $tags = $object->getTags(); + $this->assertCount(2, $tags); + $this->assertTrue($object->hasTag('method')); + $this->assertTrue($object->hasTag('Method')); + $this->assertInstanceOf( + __NAMESPACE__ . '\DocBlock\Tag\MethodTag', + $tags[0] + ); + $this->assertInstanceOf( + __NAMESPACE__ . '\DocBlock\Tag', + $tags[1] + ); + $this->assertNotInstanceOf( + __NAMESPACE__ . '\DocBlock\Tag\MethodTag', + $tags[1] + ); + } + + /** + * @depends testConstructFromReflector + * @covers \phpDocumentor\Reflection\DocBlock::getTagsByName + * + * @return void + */ + public function testGetTagsByNameZeroAndOneMatch() + { + $object = new DocBlock(new \ReflectionClass($this)); + $this->assertEmpty($object->getTagsByName('category')); + $this->assertCount(1, $object->getTagsByName('author')); + } + + /** + * @depends testConstructWithTagsOnly + * @covers \phpDocumentor\Reflection\DocBlock::parseTags + * + * @return void + */ + public function testParseMultilineTag() + { + $fixture = <<assertCount(1, $object->getTags()); + } + + /** + * @depends testConstructWithTagsOnly + * @covers \phpDocumentor\Reflection\DocBlock::parseTags + * + * @return void + */ + public function testParseMultilineTagWithLineBreaks() + { + $fixture = <<assertCount(1, $tags = $object->getTags()); + /** @var ReturnTag $tag */ + $tag = reset($tags); + $this->assertEquals("Content on\n multiple lines.\n\n One more, after the break.", $tag->getDescription()); + } + + /** + * @depends testConstructWithTagsOnly + * @covers \phpDocumentor\Reflection\DocBlock::getTagsByName + * + * @return void + */ + public function testGetTagsByNameMultipleMatch() + { + $fixture = <<assertEmpty($object->getTagsByName('category')); + $this->assertCount(1, $object->getTagsByName('return')); + $this->assertCount(2, $object->getTagsByName('param')); + } +} diff --git a/vendor/phpunit/phpunit/.gitattributes b/vendor/phpunit/phpunit/.gitattributes new file mode 100644 index 000000000..278ace47a --- /dev/null +++ b/vendor/phpunit/phpunit/.gitattributes @@ -0,0 +1,4 @@ +/build export-ignore + +*.php diff=php + diff --git a/vendor/phpunit/phpunit/.gitignore b/vendor/phpunit/phpunit/.gitignore new file mode 100644 index 000000000..8caea62d6 --- /dev/null +++ b/vendor/phpunit/phpunit/.gitignore @@ -0,0 +1,16 @@ +/.ant_targets +/.idea +/build/documentation +/build/logfiles +/build/phar +/build/phpdox +/build/*.phar +/build/*.phar.asc +/tests/TextUI/*.diff +/tests/TextUI/*.exp +/tests/TextUI/*.log +/tests/TextUI/*.out +/tests/TextUI/*.php +/cache.properties +/composer.lock +/vendor diff --git a/vendor/phpunit/phpunit/.php_cs b/vendor/phpunit/phpunit/.php_cs new file mode 100644 index 000000000..e0d5fd6e9 --- /dev/null +++ b/vendor/phpunit/phpunit/.php_cs @@ -0,0 +1,69 @@ +files() + ->in('build') + ->in('src') + ->in('tests') + ->name('*.php') + ->name('*.phpt'); + +return Symfony\CS\Config\Config::create() + ->level(\Symfony\CS\FixerInterface::NONE_LEVEL) + ->fixers( + array( + 'align_double_arrow', + 'align_equals', + 'braces', + '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', + 'long_array_syntax', + '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_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/phpunit/phpunit/.travis.yml b/vendor/phpunit/phpunit/.travis.yml new file mode 100644 index 000000000..a0d6bebd3 --- /dev/null +++ b/vendor/phpunit/phpunit/.travis.yml @@ -0,0 +1,34 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + +env: + matrix: + - DEPENDENCIES="high" + - DEPENDENCIES="low" + +sudo: false + +before_install: + - composer self-update + - composer clear-cache + +install: + - if [[ "$DEPENDENCIES" = 'high' ]]; then travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable; fi + - if [[ "$DEPENDENCIES" = 'low' ]]; then travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable --prefer-lowest; fi + +script: + - ./phpunit + - ./phpunit --configuration ./build/travis-ci-fail.xml > /dev/null; if [ $? -eq 0 ]; then echo "SHOULD FAIL"; false; else echo "fail checked"; fi; + - xmllint --noout --schema phpunit.xsd phpunit.xml + - xmllint --noout --schema phpunit.xsd tests/_files/configuration.xml + - xmllint --noout --schema phpunit.xsd tests/_files/configuration_empty.xml + - xmllint --noout --schema phpunit.xsd tests/_files/configuration_xinclude.xml -xinclude + +notifications: + email: false + diff --git a/vendor/phpunit/phpunit/CODE_OF_CONDUCT.md b/vendor/phpunit/phpunit/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..d39d536c6 --- /dev/null +++ b/vendor/phpunit/phpunit/CODE_OF_CONDUCT.md @@ -0,0 +1,28 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic + addresses, without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project maintainer at sebastian@phpunit.de. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident. + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.3.0, available at [http://contributor-covenant.org/version/1/3/0/][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/3/0/ diff --git a/vendor/phpunit/phpunit/CONTRIBUTING.md b/vendor/phpunit/phpunit/CONTRIBUTING.md new file mode 100644 index 000000000..fea001aee --- /dev/null +++ b/vendor/phpunit/phpunit/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# Contributing to PHPUnit + +## Contributor Code of Conduct + +Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. + +## Workflow + +* Fork the project. +* Make your bug fix or feature addition. +* Add tests for it. This is important so we don't break it in a future version unintentionally. +* Send a pull request. Bonus points for topic branches. + +Please make sure that you have [set up your user name and email address](http://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup) for use with Git. Strings such as `silly nick name ` look really stupid in the commit history of a project. + +Pull requests for bug fixes must be based on the current stable branch whereas pull requests for new features must be based on the `master` branch. + +We are trying to keep backwards compatibility breaks in PHPUnit to an absolute minimum. Please take this into account when proposing changes. + +Due to time constraints, we are not always able to respond as quickly as we would like. Please do not take delays personal and feel free to remind us if you feel that we forgot to respond. + +## Coding Guidelines + +This project comes with a configuration file for [php-cs-fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) (`.php_cs`) that you can use to (re)format your sourcecode for compliance with this project's coding guidelines: + +```bash +$ wget http://get.sensiolabs.org/php-cs-fixer.phar + +$ php php-cs-fixer.phar fix +``` + +## Using PHPUnit from a Git checkout + +The following commands can be used to perform the initial checkout of PHPUnit: + +```bash +$ git clone git://github.com/sebastianbergmann/phpunit.git + +$ cd phpunit +``` + +Retrieve PHPUnit's dependencies using [Composer](https://getcomposer.org/): + +```bash +$ composer install +``` + +The `phpunit` script can be used to invoke the PHPUnit test runner: + +```bash +$ ./phpunit --version +``` + +## Reporting issues + +Please use the most specific issue tracker to search for existing tickets and to open new tickets: + +* [General problems](https://github.com/sebastianbergmann/phpunit/issues) +* [Code Coverage](https://github.com/sebastianbergmann/php-code-coverage/issues) +* [Stub and Mock Objects](https://github.com/sebastianbergmann/phpunit-mock-objects/issues) +* [DbUnit](https://github.com/sebastianbergmann/dbunit/issues) +* [PHPUnit_Selenium](https://github.com/sebastianbergmann/phpunit-selenium/issues) +* [Documentation](https://github.com/sebastianbergmann/phpunit-documentation/issues) +* [Website](https://github.com/sebastianbergmann/phpunit-website/issues) + diff --git a/vendor/phpunit/phpunit/ChangeLog-4.0.md b/vendor/phpunit/phpunit/ChangeLog-4.0.md new file mode 100644 index 000000000..dc71b0174 --- /dev/null +++ b/vendor/phpunit/phpunit/ChangeLog-4.0.md @@ -0,0 +1,176 @@ +# Changes in PHPUnit 4.0 + +All notable changes of the PHPUnit 4.0 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.0.20] - 2014-05-02 + +### Fixed + +* Fixed [#1242](https://github.com/sebastianbergmann/phpunit/issues/1242): `--self-update` uses OpenSSL API that is deprecated in PHP 5.6 + +## [4.0.19] - 2014-04-30 + +### Fixed + +* Fixed [#1193](https://github.com/sebastianbergmann/phpunit/issues/1193): Process isolation does not work correctly when PHPUnit is used from PHAR +* Fixed a BC break related to comparing `DOMNode` objects that was introduced in PHPUnit 4.0.18 + +## [4.0.18] - 2014-04-29 + +### Fixed + +* Fixed [#1218](https://github.com/sebastianbergmann/phpunit/issues/1218): `--self-update` destroys symlink + +## [4.0.17] - 2014-04-21 + +### Changed + +* [Display a message that the PEAR installation method is no longer supported when PHPUnit was installed using the PEAR Installer](https://github.com/sebastianbergmann/phpunit/commit/70b02c6be0176ab8ad3d3c9ec97480556c5dd63b) + +## [4.0.16] - 2014-04-20 + +### Fixed + +* [Fixed handling of the `--report-useless-tests`, `--strict-coverage`, `--disallow-test-output`, and `--enforce-time-limit` options](https://github.com/sebastianbergmann/phpunit/commit/38baa9670711adedfe44ef24a33b568f61f3f045) + +## [4.0.15] - 2014-04-16 + +New release of PHPUnit as PHAR and PEAR package with updated dependencies + +## [4.0.14] - 2014-03-28 + +New release of PHPUnit as PHAR and PEAR package with updated dependencies + +## [4.0.13] - 2014-03-26 + +New release of PHPUnit as PHAR and PEAR package with updated dependencies + +## [4.0.12] - 2014-03-20 + +### Changed + +* [Use blacklist from PHP_CodeCoverage](https://github.com/sebastianbergmann/phpunit/commit/16152ba4b8d0104ce34f60cb71b2b982ba84c898) + +## [4.0.11] - 2014-03-18 + +### Fixed + +* [Fixed unintended autoloader invokation triggered by the `@beforeClass` and `@afterClass` annotations](https://github.com/sebastianbergmann/phpunit/commit/f12e10fddc3ccbddb652a04d9036aeb5a6d54bff) + +## [4.0.10] - 2014-03-18 + +New release of PHPUnit as PHAR and PEAR package with updated dependencies (most notably a [fix](https://github.com/sebastianbergmann/phpunit-mock-objects/commit/c5e6274b8f2bf983cf883bb375cf44f99aff200e) in the mock object generator that caused a [performance regression](https://github.com/sebastianbergmann/phpunit/issues/1187)) + +## [4.0.9] - 2014-03-17 + +### Changed + +* Optimized the search for the `@before`, `@after`, `@beforeClass` and `@afterClass` annotations +* Optimized the usage of `SebastianBergmann\Environment\Runtime::canCollectCodeCoverage()` + +### Fixed + +* The "No code coverage will be generated." message was displayed even when code coverage reporting was not requested + +## [4.0.8] - 2014-03-17 + +### Fixed + +* Fixed [#1186](https://github.com/sebastianbergmann/phpunit/issues/1186): `@before` and `@after` methods are not called in `@dataProvider` methods + +## [4.0.7] - 2014-03-12 + +### Fixed + +* Removed dependency on `phpunit/dbunit` in `composer.json` that was unintentionally added in PHPUnit 4.0.6 + +## [4.0.6] - 2014-03-11 + +New release of PHPUnit as PHAR and PEAR package with updated dependencies + +## [4.0.5] - 2014-03-10 + +New release of PHPUnit as PHAR and PEAR package with updated dependencies + +## [4.0.4] - 2014-03-08 + +### Fixed + +* Fixed stacktrace filtering when PHPUnit is used from a PHAR + +## [4.0.3] - 2014-03-07 + +New release of PHPUnit as PHAR and PEAR package with updated dependencies + +## [4.0.2] - 2014-03-07 + +### Fixed + +* Fixed an issue related to displaying PHPUnit's version number + +## [4.0.1] - 2014-03-07 + +### Fixed + +* Fixed collection of code coverage data for tests that use a data provider + +## [4.0.0] - 2014-03-07 + +### Added + +* Implemented #382: Added the `$options` parameter to `PHPUnit_Framework_TestCase::getMockFromWsdl()` for configuring the `SoapClient` +* Implemented #628: Added `PHPUnit_Framework_Assert::countOf(), a shortcut to get a `PHPUnit_Framework_Constraint_Count` instance +* Implemented #711: `coverage-text` now has an XML `showOnlySummary` option +* Implemented #719: The `--stderr` switch now respects `--colors` and `--debug` +* Implemented #746: Allow identity checking for non-object types in all asserts that depend on `TraversableContains` +* Implemented #758: Show a proper stack trace when @expectedException fails due to a unexpected exception being thrown +* Implemented #773: Recursive and repeated arrays are more gracefully when comparison differences are exported +* Implemented #813: Added `@before`, `@after`, `@beforeClass` and `@afterClass` annotations +* Implemented #834: Added the `@requires OS` annotation +* Implemented #835: Printers that extend `PHPUnit_TextUI_ResultPrinter` should have similar construction +* Implemented #838: Added a base test listener +* Implemented #859: Added PHP label validation to attribute assertions +* Implemented #869: Added support for the adjacent sibling selector (+) to `PHPUnit_Util_XML::findNodes()` +* Implemented #871: Add Comparator for DateTime objects +* Implemented #877: Added new HTML5 tags to `PHPUnit_Util_XML::findNodes()` +* Added `--coverage-crap4j` switch to generate code coverage report in Crap4J XML format +* `assertCount()`, `assertNotCount()`, `assertSameSize()`, and `assertNotSameSize()` now support all objects that implement the `Traversable` interface + +### Changed + +* A test will now fail in strict mode when it uses the `@covers` annotation and code that is not expected to be covered is executed +* All relative paths in a configuration file are now resolved relative to that configuration file + +### Fixed + +* Fixed #240: XML strings are escaped by removing invalid characters +* Fixed #261: `setUp()` and `setUpBeforeClass()` are run before filters are applied +* Fixed #541: Excluded groups are counted towards total number of tests being executed +* Fixed #789: PHP INI settings would not be passed to child processes +* Fixed #806: Array references are now properly displayed in error output +* Fixed #808: Resources are now reported as `resource(13) of type (stream)` instead of `NULL` +* Fixed #873: PHPUnit suppresses exceptions thrown outside of test case function +* Fixed: `phpt` test cases now use the correct php binary when executed through wrapper scripts + +[4.0.20]: https://github.com/sebastianbergmann/phpunit/compare/4.0.19...4.0.20 +[4.0.19]: https://github.com/sebastianbergmann/phpunit/compare/4.0.18...4.0.19 +[4.0.18]: https://github.com/sebastianbergmann/phpunit/compare/4.0.17...4.0.18 +[4.0.17]: https://github.com/sebastianbergmann/phpunit/compare/4.0.16...4.0.17 +[4.0.16]: https://github.com/sebastianbergmann/phpunit/compare/4.0.15...4.0.16 +[4.0.15]: https://github.com/sebastianbergmann/phpunit/compare/4.0.14...4.0.15 +[4.0.14]: https://github.com/sebastianbergmann/phpunit/compare/4.0.13...4.0.14 +[4.0.13]: https://github.com/sebastianbergmann/phpunit/compare/4.0.12...4.0.13 +[4.0.12]: https://github.com/sebastianbergmann/phpunit/compare/4.0.11...4.0.12 +[4.0.11]: https://github.com/sebastianbergmann/phpunit/compare/4.0.10...4.0.11 +[4.0.10]: https://github.com/sebastianbergmann/phpunit/compare/4.0.9...4.0.10 +[4.0.9]: https://github.com/sebastianbergmann/phpunit/compare/4.0.8...4.0.9 +[4.0.8]: https://github.com/sebastianbergmann/phpunit/compare/4.0.7...4.0.8 +[4.0.7]: https://github.com/sebastianbergmann/phpunit/compare/4.0.6...4.0.7 +[4.0.6]: https://github.com/sebastianbergmann/phpunit/compare/4.0.5...4.0.6 +[4.0.5]: https://github.com/sebastianbergmann/phpunit/compare/4.0.4...4.0.5 +[4.0.4]: https://github.com/sebastianbergmann/phpunit/compare/4.0.3...4.0.4 +[4.0.3]: https://github.com/sebastianbergmann/phpunit/compare/4.0.2...4.0.3 +[4.0.2]: https://github.com/sebastianbergmann/phpunit/compare/4.0.1...4.0.2 +[4.0.1]: https://github.com/sebastianbergmann/phpunit/compare/4.0.0...4.0.1 +[4.0.0]: https://github.com/sebastianbergmann/phpunit/compare/3.7...4.0.0 + diff --git a/vendor/phpunit/phpunit/ChangeLog-4.1.md b/vendor/phpunit/phpunit/ChangeLog-4.1.md new file mode 100644 index 000000000..d7f10a74f --- /dev/null +++ b/vendor/phpunit/phpunit/ChangeLog-4.1.md @@ -0,0 +1,73 @@ +# Changes in PHPUnit 4.1 + +All notable changes of the PHPUnit 4.1 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.1.6] - 2014-08-17 + +### Fixed + +* Fixed [#1380](https://github.com/sebastianbergmann/phpunit/issues/1380): `assertMatch()` returns `Unexpected end tag : hr` +* Fixed [#1390](https://github.com/sebastianbergmann/phpunit/issues/1390): Licensing issue with third-party components bundled in PHAR distribution + +## [4.1.5] - 2014-08-07 + +### Changed + +* Implemented [#1330](https://github.com/sebastianbergmann/phpunit/issues/1330): Allow non-ambiguous shortened long options + +### Fixed + +* Fixed [#529](https://github.com/sebastianbergmann/phpunit/issues/529): Tests missed in execution when another test extends from it +* Fixed [#1149](https://github.com/sebastianbergmann/phpunit/issues/1149): Test swallows output buffer when run in a separate process +* Fixed [#1336](https://github.com/sebastianbergmann/phpunit/issues/1336): Problem in process isolation with global variables that contain an object which contains a string which contains multiple backslashes +* Fixed [#1337](https://github.com/sebastianbergmann/phpunit/issues/1337): Data Provider with `\` at the end of the name breaks with process isolation +* Fixed [#1345](https://github.com/sebastianbergmann/phpunit/issues/1345): Process isolation blocks infinitely upon fatal error in child process +* Fixed [#1354](https://github.com/sebastianbergmann/phpunit/issues/1354): PHPUnit test suite fails on Windows +* Fixed [#1369](https://github.com/sebastianbergmann/phpunit/issues/1369): Performance of `TestSuite::addTestFile()` and missing documentation +* Fixed [#1374](https://github.com/sebastianbergmann/phpunit/issues/1374): `tearDown()` is called despite unmet requirements + +## [4.1.4] - 2014-07-18 + +### Fixed + +* Fixed [#1265](https://github.com/sebastianbergmann/phpunit/issues/1265): `PHPUnit_Runner_StandardTestSuiteLoader` could not be configured as loader +* Fixed [#1311](https://github.com/sebastianbergmann/phpunit/issues/1311): Incomplete XML Schema for PHPUnit XML configuration file +* Fixed [#1314](https://github.com/sebastianbergmann/phpunit/issues/1314): Bug in configuration parser + +## [4.1.3] - 2014-06-11 + +New release of PHPUnit as PHP Archive (PHAR) with updated dependencies + +## [4.1.2] - 2014-06-07 + +New release of PHPUnit as PHP Archive (PHAR) with updated dependencies + +## [4.1.1] - 2014-05-24 + +### Added + +* Added `--selfupdate` alias for `--self-update` + +### Changed + +* Improved the fix for [#1133](https://github.com/sebastianbergmann/phpunit/issues/1133) + +### Fixed + +* Fixed the constructor argument for `SebastianBergmann\Version` + +## [4.1.0] - 2014-05-02 + +### Changed + +* The code to compare PHP values for equality (in `assertEquals()`, for instance) has been factored out into a [separate component](https://github.com/sebastianbergmann/comparator) +* [The mock object generator is now created lazily](https://github.com/sebastianbergmann/phpunit/pull/1165) + +[4.1.6]: https://github.com/sebastianbergmann/phpunit/compare/4.1.5...4.1.6 +[4.1.5]: https://github.com/sebastianbergmann/phpunit/compare/4.1.4...4.1.5 +[4.1.4]: https://github.com/sebastianbergmann/phpunit/compare/4.1.3...4.1.4 +[4.1.3]: https://github.com/sebastianbergmann/phpunit/compare/4.1.2...4.1.3 +[4.1.2]: https://github.com/sebastianbergmann/phpunit/compare/4.1.1...4.1.2 +[4.1.1]: https://github.com/sebastianbergmann/phpunit/compare/4.1.0...4.1.1 +[4.1.0]: https://github.com/sebastianbergmann/phpunit/compare/4.0...4.1.0 + diff --git a/vendor/phpunit/phpunit/ChangeLog-4.2.md b/vendor/phpunit/phpunit/ChangeLog-4.2.md new file mode 100644 index 000000000..0d902b74b --- /dev/null +++ b/vendor/phpunit/phpunit/ChangeLog-4.2.md @@ -0,0 +1,56 @@ +# Changes in PHPUnit 4.2 + +All notable changes of the PHPUnit 4.2 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.2.5] - 2014-09-06 + +New release of PHPUnit as PHP Archive (PHAR) with updated dependencies + +## [4.2.4] - 2014-08-31 + +### Fixed + +* Fixed [#1413](https://github.com/sebastianbergmann/phpunit/issues/1413): `assertCount()` hangs in infinite loop on HHVM + +## [4.2.3] - 2014-08-28 + +### Fixed + +* Fixed [#1403](https://github.com/sebastianbergmann/phpunit/issues/1403): `phpunit --self-update` does not work + +## [4.2.2] - 2014-08-18 + +### Fixed + +* Fixed [#1399](https://github.com/sebastianbergmann/phpunit/issues/1399): `enforceTimeLimit` configuration option is not handled + +## [4.2.1] - 2014-08-17 + +### Fixed + +* Fixed [#1380](https://github.com/sebastianbergmann/phpunit/issues/1380): `assertMatch()` returns `Unexpected end tag : hr` +* Fixed [#1390](https://github.com/sebastianbergmann/phpunit/issues/1390): Licensing issue with third-party components bundled in PHAR distribution + +## [4.2.0] - 2014-08-08 + +### Added + +* Tests annotated with `@todo` will now be reported as risky when the `--disallow-todo-tests` option is used or `beStrictAboutTodoAnnotatedTests=true` is set in the configuration file +* The `atLeast()` and `atMost()` invocation count matchers were added + +### Changed + +* `trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);` is used now to indicate that a PHPUnit API method is deprecated; the old "system" for deprecating methods has been removed +* The PHP Archive (PHAR) distribution of PHPUnit can now be used as a library; `include()`ing or `require()`ing it will not execute the CLI test runner + +### Deprecated + +* The `assertTag()` and `assertSelect*()` assertion methods have been deprecated in favor of the [phpunit-dom-assertions](https://github.com/phpunit/phpunit-dom-assertions) extension; these methods will be removed in PHPUnit 5.0 + +[4.2.5]: https://github.com/sebastianbergmann/phpunit/compare/4.2.4...4.2.5 +[4.2.4]: https://github.com/sebastianbergmann/phpunit/compare/4.2.3...4.2.4 +[4.2.3]: https://github.com/sebastianbergmann/phpunit/compare/4.2.2...4.2.3 +[4.2.2]: https://github.com/sebastianbergmann/phpunit/compare/4.2.1...4.2.2 +[4.2.1]: https://github.com/sebastianbergmann/phpunit/compare/4.2.0...4.2.1 +[4.2.0]: https://github.com/sebastianbergmann/phpunit/compare/4.1...4.2.0 + diff --git a/vendor/phpunit/phpunit/ChangeLog-4.3.md b/vendor/phpunit/phpunit/ChangeLog-4.3.md new file mode 100644 index 000000000..99c2826e2 --- /dev/null +++ b/vendor/phpunit/phpunit/ChangeLog-4.3.md @@ -0,0 +1,54 @@ +# Changes in PHPUnit 4.3 + +All notable changes of the PHPUnit 4.3 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.3.5] - 2014-11-11 + +### Changed + +* Merged [#1484](https://github.com/sebastianbergmann/phpunit/issues/1484): Removed `lazymap` from blacklist as it is not longer used +* Merged [#1489](https://github.com/sebastianbergmann/phpunit/issues/1489): Do not send output from tests in process isolation when testing output + +## [4.3.4] - 2014-10-22 + +### Fixed + +* Fixed [#1428](https://github.com/sebastianbergmann/phpunit/issues/1428): Issue with Composer dependencies +* Fixed [#1447](https://github.com/sebastianbergmann/phpunit/issues/1447): PHPT tests treat line endings inconsistently + +## [4.3.3] - 2014-10-16 + +### Fixed + +* Fixed [#1471](https://github.com/sebastianbergmann/phpunit/issues/1471): Output made while test is running is printed although `expectOutputString()` is used when an assertion fails + +## [4.3.2] - 2014-10-16 + +### Fixed + +* Fixed [#1468](https://github.com/sebastianbergmann/phpunit/issues/1468): Incomplete and `@todo` annotated tests are counted twice + +## [4.3.1] - 2014-10-06 + +New release of PHPUnit as PHP Archive (PHAR) with updated dependencies + +## [4.3.0] - 2014-10-03 + +### Added + +* Merged [#1358](https://github.com/sebastianbergmann/phpunit/issues/1358): Implement `@expectedExceptionMessageRegExp` annotation +* Merged [#1360](https://github.com/sebastianbergmann/phpunit/issues/1360): Allow a test to identify whether it runs in isolation + +### Fixed + +* Fixed [#1216](https://github.com/sebastianbergmann/phpunit/issues/1216): Bootstrap does not have global variables set when `--bootstrap` is specified on commandline +* Fixed [#1351](https://github.com/sebastianbergmann/phpunit/issues/1351): `TestResult` object contains serialized test class upon test failure/exception in process isolation +* Fixed [#1437](https://github.com/sebastianbergmann/phpunit/issues/1437): Risky test messages mask failures + +[4.3.5]: https://github.com/sebastianbergmann/phpunit/compare/4.3.4...4.3.5 +[4.3.4]: https://github.com/sebastianbergmann/phpunit/compare/4.3.3...4.3.4 +[4.3.3]: https://github.com/sebastianbergmann/phpunit/compare/4.3.2...4.3.3 +[4.3.2]: https://github.com/sebastianbergmann/phpunit/compare/4.3.1...4.3.2 +[4.3.1]: https://github.com/sebastianbergmann/phpunit/compare/4.3.0...4.3.1 +[4.3.0]: https://github.com/sebastianbergmann/phpunit/compare/4.2...4.3.0 + diff --git a/vendor/phpunit/phpunit/ChangeLog-4.4.md b/vendor/phpunit/phpunit/ChangeLog-4.4.md new file mode 100644 index 000000000..312af5ae7 --- /dev/null +++ b/vendor/phpunit/phpunit/ChangeLog-4.4.md @@ -0,0 +1,57 @@ +# Changes in PHPUnit 4.4 + +All notable changes of the PHPUnit 4.4 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.4.5] - 2015-01-27 + +### Fixed + +* Fixed [#1592](https://github.com/sebastianbergmann/phpunit/issues/1592): Incorrect dependency information + +## [4.4.4] - 2015-01-24 + +### Fixed + +* Fixed [#1587](https://github.com/sebastianbergmann/phpunit/issues/1587): Class `SebastianBergmann\Exporter\Context` not found + +## [4.4.3] - 2015-01-24 + +New PHAR release due to updated dependencies + +## [4.4.2] - 2015-01-17 + +### Changed + +* Merged [#1573](https://github.com/sebastianbergmann/phpunit/issues/1573): Updates for the XSD for PHPUnit XML configuration + +### Fixed + +* Merged [#1567](https://github.com/sebastianbergmann/phpunit/issues/1567): `coverage-crap4j` missing in XSD for PHPUnit XML configuration +* Fixed [#1570](https://github.com/sebastianbergmann/phpunit/issues/1570): Test that prints output is marked as failure and not as risky when `--disallow-test-output` is used +* Fixed `--stderr` with `--tap` or `--testdox` options + +## [4.4.1] - 2014-12-28 + +### Changed + +* Merged [#1528](https://github.com/sebastianbergmann/phpunit/issues/1528): Add `expectedCount()` to `toString()` return value + +## [4.4.0] - 2014-12-05 + +### Added + +* Merged [#1371](https://github.com/sebastianbergmann/phpunit/issues/1371): Implement `assertArraySubset()` assertion +* Merged [#1439](https://github.com/sebastianbergmann/phpunit/issues/1439): Add support for `double` to `assertInternalType()` + +### Changed + +* Merged [#1427](https://github.com/sebastianbergmann/phpunit/issues/1427): Improve failure output for tests when provided data is binary +* Merged [#1458](https://github.com/sebastianbergmann/phpunit/issues/1458): Only enable colors when PHPUnit is run on a console (and output is not sent to a file) + +[4.4.5]: https://github.com/sebastianbergmann/phpunit/compare/4.4.4...4.4.5 +[4.4.4]: https://github.com/sebastianbergmann/phpunit/compare/4.4.3...4.4.4 +[4.4.3]: https://github.com/sebastianbergmann/phpunit/compare/4.4.2...4.4.3 +[4.4.2]: https://github.com/sebastianbergmann/phpunit/compare/4.4.1...4.4.2 +[4.4.1]: https://github.com/sebastianbergmann/phpunit/compare/4.4.0...4.4.1 +[4.4.0]: https://github.com/sebastianbergmann/phpunit/compare/4.3...4.4.0 + diff --git a/vendor/phpunit/phpunit/ChangeLog-4.5.md b/vendor/phpunit/phpunit/ChangeLog-4.5.md new file mode 100644 index 000000000..2313de10e --- /dev/null +++ b/vendor/phpunit/phpunit/ChangeLog-4.5.md @@ -0,0 +1,28 @@ +# Changes in PHPUnit 4.5 + +All notable changes of the PHPUnit 4.5 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.5.1] - 2015-03-29 + +## [4.5.0] - 2015-02-05 + +### Added + +* Added out-of-the-box support for [Prophecy](https://github.com/phpspec/prophecy) +* Implemented [#137](https://github.com/sebastianbergmann/phpunit/issues/137): Add support for variable number of tests shown per line in default result printer + +### Changed + +* Merged [#1478](https://github.com/sebastianbergmann/phpunit/issues/1478): Improve the performance of `PHPUnit_Framework_Constraint_IsEqual` (which is used by `assertEquals()`, for instance) for the most common case + +### Deprecated + +* [Deprecated](https://github.com/sebastianbergmann/phpunit/commit/7abe7796f77b13fdf3cfc506fb987d6c2ab477f5) the `--strict` commandline option and the XML configuration's `strict` attribute + +### Fixed + +* Fixed [#1474](https://github.com/sebastianbergmann/phpunit/issues/1474): Allow the registration of custom comparators for `assertEquals()` et al. (again) + +[4.5.1]: https://github.com/sebastianbergmann/phpunit/compare/4.5.0...4.5.1 +[4.5.0]: https://github.com/sebastianbergmann/phpunit/compare/4.4...4.5.0 + diff --git a/vendor/phpunit/phpunit/ChangeLog-4.6.md b/vendor/phpunit/phpunit/ChangeLog-4.6.md new file mode 100644 index 000000000..3571634a1 --- /dev/null +++ b/vendor/phpunit/phpunit/ChangeLog-4.6.md @@ -0,0 +1,95 @@ +# Changes in PHPUnit 4.6 + +All notable changes of the PHPUnit 4.6 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.6.10] - 2015-06-03 + +### Changed + +* Merged [#1693](https://github.com/sebastianbergmann/phpunit/pull/1693): Improved API documentation +* Merged [#1706](https://github.com/sebastianbergmann/phpunit/pull/1706): Avoid hard-coded URI to `phpunit.xsd` +* Merged [#1725](https://github.com/sebastianbergmann/phpunit/pull/1725): Update phpDox XSD URI +* Merged [#1735](https://github.com/sebastianbergmann/phpunit/pull/1735): Mute `chdir()` failures in XInclude handling of XML configuration file +* Merged [#1736](https://github.com/sebastianbergmann/phpunit/pull/1736): Verify that phar file can be overwritten before attempting self update + +### Fixed + +* Fixed [#1737](https://github.com/sebastianbergmann/phpunit/issues/1737): Confusing output from `--testdox` for empty test class + +## [4.6.9] - 2015-05-29 + +### Fixed + +* Fixed [#1731](https://github.com/sebastianbergmann/phpunit/issues/1731): `.` after failure count has no background color when `--colors` is used + +## [4.6.8] - 2015-05-28 + +New PHAR release due to updated dependencies + +## [4.6.7] - 2015-05-25 + +New PHAR release due to updated dependencies + +## [4.6.6] - 2015-04-29 + +### Fixed + +* Fixed [#1684](https://github.com/sebastianbergmann/phpunit/issues/1684): PHAR does not work on HHVM + +## [4.6.5] - 2015-04-29 + +* Fixed [#1677](https://github.com/sebastianbergmann/phpunit/issues/1677): Number of risky tests not printed when there are failing tests +* Fixed [#1688](https://github.com/sebastianbergmann/phpunit/issues/1688): Self-Update operation does not work due to outdated SSL certificate + +## [4.6.4] - 2015-04-11 + +### Changed + +* The default list of blacklisted classes is now always passed to PHP_CodeCoverage + +## [4.6.3] - 2015-04-11 + +### Changed + +* Updated the default list of blacklisted classes + +## [4.6.2] - 2015-04-07 + +### Fixed + +* Fixed [#1667](https://github.com/sebastianbergmann/phpunit/issues/1667): Loading `src/Framework/Assert/Functions.php` by default causes collisions + +## [4.6.1] - 2015-04-03 + +### Fixed + +* Fixed [#1665](https://github.com/sebastianbergmann/phpunit/issues/1665): PHPUnit 4.6.0 PHAR does not work when renamed to `phpunit` + +## [4.6.0] - 2015-04-03 + +### Added + +* Added the `--strict-global-state` command-line option and the `beStrictAboutChangesToGlobalState` configuration setting for enabling a check that global variabes, super-global variables, and static attributes in user-defined classes are not modified during a test +* Merged [#1527](https://github.com/sebastianbergmann/phpunit/issues/1527) and [#1529](https://github.com/sebastianbergmann/phpunit/issues/1529): Allow to define options for displaying colors + +### Changed + +* Merged [#1528](https://github.com/sebastianbergmann/phpunit/issues/1528): Improve message when `PHPUnit_Framework_Constraint_Count` is used with logical operators + +### Fixed + +* Merged [#1537](https://github.com/sebastianbergmann/phpunit/issues/1537): Fix problem of `--stderr` with `--tap` and `--testdox` +* Fixed [#1599](https://github.com/sebastianbergmann/phpunit/issues/1599): The PHAR build of PHPUnit no longer uses an autoloader to load PHPUnit's own classes and instead statically loads all classes on startup + +[4.6.10]: https://github.com/sebastianbergmann/phpunit/compare/4.6.9...4.6.10 +[4.6.9]: https://github.com/sebastianbergmann/phpunit/compare/4.6.8...4.6.9 +[4.6.8]: https://github.com/sebastianbergmann/phpunit/compare/4.6.7...4.6.8 +[4.6.7]: https://github.com/sebastianbergmann/phpunit/compare/4.6.6...4.6.7 +[4.6.6]: https://github.com/sebastianbergmann/phpunit/compare/4.6.5...4.6.6 +[4.6.5]: https://github.com/sebastianbergmann/phpunit/compare/4.6.4...4.6.5 +[4.6.4]: https://github.com/sebastianbergmann/phpunit/compare/4.6.3...4.6.4 +[4.6.3]: https://github.com/sebastianbergmann/phpunit/compare/4.6.2...4.6.3 +[4.6.2]: https://github.com/sebastianbergmann/phpunit/compare/4.6.1...4.6.2 +[4.6.1]: https://github.com/sebastianbergmann/phpunit/compare/4.6.0...4.6.1 +[4.6.0]: https://github.com/sebastianbergmann/phpunit/compare/4.5...4.6.0 + diff --git a/vendor/phpunit/phpunit/ChangeLog-4.7.md b/vendor/phpunit/phpunit/ChangeLog-4.7.md new file mode 100644 index 000000000..948c12749 --- /dev/null +++ b/vendor/phpunit/phpunit/ChangeLog-4.7.md @@ -0,0 +1,71 @@ +# Changes in PHPUnit 4.7 + +All notable changes of the PHPUnit 4.7 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.7.7] - 2015-07-13 + +New PHAR release due to updated dependencies + +## [4.7.6] - 2015-06-30 + +### Fixed + +* Fixed [#1681](https://github.com/sebastianbergmann/phpunit/issues/1681): Code Coverage filter configuration is not passed to child processes +* Fixed [#1692](https://github.com/sebastianbergmann/phpunit/issues/1692): Clean up `PHPUnit_Extensions_RepeatedTest` after refactoring +* Fixed [#1763](https://github.com/sebastianbergmann/phpunit/issues/1763): `@before` and `@after` annotations do not work when inherited + +## [4.7.5] - 2015-06-21 + +### Fixed + +* Fixed [#490](https://github.com/sebastianbergmann/phpunit/issues/490): Ensure that a test can only be one of `@small`, `@medium`, or `@large`. +* Fixed [#1704](https://github.com/sebastianbergmann/phpunit/issues/1704): Output printed during test missing when using TAP + +## [4.7.4] - 2015-06-18 + +### Changed + +* The `PHPUnit_Framework_Constraint_IsType` constraint now knows about the `real` type (which is an alias for `float`) +* Various work on compatibility with PHP 7 + +### Fixed + +* Fixed [#1749](https://github.com/sebastianbergmann/phpunit/issues/1749): `stopOnError` configuration setting does not work + +## [4.7.3] - 2015-06-11 + +### Fixed + +* Fixed [#1317](https://github.com/sebastianbergmann/phpunit/issues/1317): JUnit XML logfiles does not contain warnings +* Fixed an [issue](https://github.com/sebastianbergmann/php-code-coverage/issues/347) where the warning that no whitelist is used is displayed when it should not + +## [4.7.2] - 2015-06-06 + +New PHAR release due to updated dependencies + +## [4.7.1] - 2015-06-05 + +New PHAR release due to updated dependencies + +## [4.7.0] - 2015-06-05 + +### Added + +* Merged [#1718](https://github.com/sebastianbergmann/phpunit/issues/1718): Support for `--INI--` section in PHPT tests + +### Changed + +* Tests not annotated with `@small`, `@medium`, or `@large` are no longer treated as being annotated with `@small` +* In verbose mode, the test runner now prints information about the PHP runtime +* To be consistent with the printing of PHP runtime information, the configuration file used is only printed in verbose mode +* A warning is now printed when code coverage data is collected but no whitelist is configured + +[4.7.7]: https://github.com/sebastianbergmann/phpunit/compare/4.7.6...4.7.7 +[4.7.6]: https://github.com/sebastianbergmann/phpunit/compare/4.7.5...4.7.6 +[4.7.5]: https://github.com/sebastianbergmann/phpunit/compare/4.7.4...4.7.5 +[4.7.4]: https://github.com/sebastianbergmann/phpunit/compare/4.7.3...4.7.4 +[4.7.3]: https://github.com/sebastianbergmann/phpunit/compare/4.7.2...4.7.3 +[4.7.2]: https://github.com/sebastianbergmann/phpunit/compare/4.7.1...4.7.2 +[4.7.1]: https://github.com/sebastianbergmann/phpunit/compare/4.7.0...4.7.1 +[4.7.0]: https://github.com/sebastianbergmann/phpunit/compare/4.6...4.7.0 + diff --git a/vendor/phpunit/phpunit/ChangeLog-4.8.md b/vendor/phpunit/phpunit/ChangeLog-4.8.md new file mode 100644 index 000000000..fee9ed22c --- /dev/null +++ b/vendor/phpunit/phpunit/ChangeLog-4.8.md @@ -0,0 +1,293 @@ +# Changes in PHPUnit 4.8 + +All notable changes of the PHPUnit 4.8 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [4.8.36] - 2017-06-21 + +### Added + +* Added `PHPUnit\Framework\AssertionFailedError`, `PHPUnit\Framework\Test`, and `PHPUnit\Framework\TestSuite` to the forward compatibility layer for PHPUnit 6 + +## [4.8.35] - 2017-02-06 + +### Added + +* Backported the forward compatibility layer for PHPUnit 6 from PHPUnit 5 so that `PHPUnit\Framework\TestCase` can be used instead of `PHPUnit_Framework_TestCase` + +## [4.8.34] - 2017-01-26 + +* Fixed [#2447](https://github.com/sebastianbergmann/phpunit/issues/2447): Reverted backwards incompatible change to handling of boolean environment variable values specified in XML + +## [4.8.33] - 2017-01-25 + +### Fixed + +* Fixed [#1983](https://github.com/sebastianbergmann/phpunit/pull/1983): Tests with `@expectedException` annotation cannot be skipped +* Fixed [#2275](https://github.com/sebastianbergmann/phpunit/pull/2275): Invalid UTF-8 characters can lead to missing output +* Fixed [#2331](https://github.com/sebastianbergmann/phpunit/issues/2331): Boolean environment variable values specified in XML get mangled +* Fixed [#2392](https://github.com/sebastianbergmann/phpunit/issues/2392): Empty (but valid) data provider should skip the test +* Fixed [#2431](https://github.com/sebastianbergmann/phpunit/issues/2431): `assertArraySubset()` does not support `ArrayAccess` + +## [4.8.32] - 2017-01-22 + +### Fixed + +* Fixed [#2428](https://github.com/sebastianbergmann/phpunit/pull/2428): Nested arrays specificied in XML configuration file are not handled correctly + +## [4.8.31] - 2016-12-09 + +### Fixed + +* Fixed [#2384](https://github.com/sebastianbergmann/phpunit/pull/2384): Handle `PHPUnit_Framework_Exception` correctly when expecting exceptions + +## [4.8.30] - 2016-12-02 + +### Fixed + +* Fixed [#2367](https://github.com/sebastianbergmann/phpunit/pull/2367): Bug in `PHPUnit_Util_Test::parseAnnotationContent()` +* Fixed [#2375](https://github.com/sebastianbergmann/phpunit/issues/2375): Invalid regular expression for `--filter` causes PHP warning + +## [4.8.29] - 2016-11-20 + +### Changed + +* Bumped the required version of `sebastian/comparator` + +## [4.8.28] - 2016-11-14 + +### Fixed + +* Improved the fix for [#1955](https://github.com/sebastianbergmann/phpunit/issues/1955): Process isolation fails when running tests with `phpdbg -qrr` + +## [4.8.27] - 2016-07-21 + +### Fixed + +* Fixed [#1968](https://github.com/sebastianbergmann/phpunit/issues/1968): Invalid data sets are not handled correctly for `@testWith` annotation + +## [4.8.26] - 2016-05-17 + +### Fixed + +* Fixed [phpunit-mock-objects/#301](https://github.com/sebastianbergmann/phpunit-mock-objects/issues/301): `PHPUnit_Framework_MockObject_MockBuilder::getMock()` calls `PHPUnit_Framework_TestCase::getMock()` with more arguments than accepted + +## [4.8.25] - 2016-05-10 + +### Fixed + +* Fixed [#2112](https://github.com/sebastianbergmann/phpunit/issues/2112): Output is html entity encoded when ran through `phpdbg` +* Fixed [#2158](https://github.com/sebastianbergmann/phpunit/issues/2158): Failure to run tests in separate processes if a file included into main process contains constant definition + +## [4.8.24] - 2016-03-14 + +### Fixed + +* Fixed [#1959](https://github.com/sebastianbergmann/phpunit/issues/1959): Prophecy errors are not handled correctly +* Fixed [#2039](https://github.com/sebastianbergmann/phpunit/issues/2039): TestDox does not handle snake_case test methods properly +* Fixed [#2109](https://github.com/sebastianbergmann/phpunit/issues/2109): Process isolation leaks global variable + +## [4.8.23] - 2016-02-11 + +### Fixed + +* Fixed [#2072](https://github.com/sebastianbergmann/phpunit/issues/2072): Paths in XML configuration file were not handled correctly when they have whitespace around them + +## [4.8.22] - 2016-02-02 + +### Fixed + +* Fixed [#2050](https://github.com/sebastianbergmann/phpunit/issues/2050): `PHPUnit_Util_XML::load()` raises exception with empty message when XML string is empty +* Fixed a bug in `PHPUnit_Runner_Version::series()` + +## [4.8.21] - 2015-12-12 + +### Changed + +* Reverted the changes introduced in PHPUnit 4.8.20 as the only thing the new version constraint in `composer.json` achieved was locking PHP 7 users to PHPUnit 4.8.19 + +## [4.8.20] - 2015-12-10 + +### Changed + +* Changed PHP version constraint in `composer.json` to prevent installing PHPUnit 4.8 on PHP 7 +* `phpunit.phar` will now refuse to work on PHP 7 + +## [4.8.19] - 2015-11-30 + +### Fixed + +* Fixed [#1955](https://github.com/sebastianbergmann/phpunit/issues/1955): Process isolation fails when running tests with `phpdbg -qrr` + +## [4.8.18] - 2015-11-11 + +### Changed + +* DbUnit 1.4 is bundled again in the PHAR distribution + +## [4.8.17] - 2015-11-10 + +### Fixed + +* Fixed [#1935](https://github.com/sebastianbergmann/phpunit/issues/1935): `PHP_CodeCoverage_Exception` not handled properly +* Fixed [#1948](https://github.com/sebastianbergmann/phpunit/issues/1948): Unable to use PHAR due to unsupported signature error + +### Changed + +* DbUnit >= 2.0.2 is now bundled in the PHAR distribution + +## [4.8.16] - 2015-10-23 + +### Added + +* Implemented [#1925](https://github.com/sebastianbergmann/phpunit/issues/1925): Provide a library-only PHAR + +## [4.8.15] - 2015-10-22 + +### Fixed + +* The backup of global state is now properly restored when changes to global state are disallowed +* The `__PHPUNIT_PHAR__` constant is now properly set when the PHPUnit PHAR is used as a library + +## [4.8.14] - 2015-10-17 + +### Fixed + +* Fixed [#1892](https://github.com/sebastianbergmann/phpunit/issues/1892): `--coverage-text` does not honor color settings + +## [4.8.13] - 2015-10-14 + +### Added + +* Added the `--self-upgrade` commandline switch for upgrading a PHPUnit PHAR to the latest version + +### Changed + +* The `--self-update` commandline switch now updates a PHPUnit PHAR to the latest version within the same release series + +## [4.8.12] - 2015-10-12 + +### Changed + +* Merged [#1893](https://github.com/sebastianbergmann/phpunit/issues/1893): Removed workaround for phpab bug + +## [4.8.11] - 2015-10-07 + +### Fixed + +* Merged [#1885](https://github.com/sebastianbergmann/phpunit/issues/1885): Fixed handling of PHP configuration settings for process isolation +* Fixed [#1857](https://github.com/sebastianbergmann/phpunit/issues/1857): `@covers` and `@uses` should only take a single word +* Fixed [#1879](https://github.com/sebastianbergmann/phpunit/issues/1879): `assertEqualXMLStructure()` cannot compare nodes with an ID +* Fixed [#1898](https://github.com/sebastianbergmann/phpunit/issues/1898): `@covers` and `@uses` cannot be used for namespaced functions +* Fixed [#1901](https://github.com/sebastianbergmann/phpunit/issues/1901): `--self-update` updates to PHPUnit 5, even on PHP < 5.6 + +## [4.8.10] - 2015-10-01 + +### Fixed + +* Merged [#1884](https://github.com/sebastianbergmann/phpunit/issues/1884): Avoid passing `Error` to `onNotSuccessfulTest()` on PHP 7 + +## [4.8.9] - 2015-09-20 + +### Fixed + +* Fixed regression introduced in PHPUnit 4.8.8 + +## [4.8.8] - 2015-09-19 + +### Fixed + +* Fixed [#1860](https://github.com/sebastianbergmann/phpunit/issues/1860): Not well-formed XML strings are always considered equal by `PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString()` + +## [4.8.7] - 2015-09-14 + +New PHAR release due to updated dependencies + +## [4.8.6] - 2015-08-24 + +### Fixed + +* Fixed [#1835](https://github.com/sebastianbergmann/phpunit/issues/1835): Skipped test reported as errored since PHPUnit 4.7.4 + +## [4.8.5] - 2015-08-19 + +### Fixed + +* Fixed [#1831](https://github.com/sebastianbergmann/phpunit/issues/1831): PHAR manifest is missing + +## [4.8.4] - 2015-08-15 + +### Fixed + +* Fixed [#1823](https://github.com/sebastianbergmann/phpunit/issues/1823): Columns attribute in XML configuration file is ignored + +## [4.8.3] - 2015-08-10 + +### Changed + +* PHPUnit now exits early during bootstrap when an unsupported version of PHP is used + +## [4.8.2] - 2015-08-07 + +### Fixed + +* Fixed [#1816](https://github.com/sebastianbergmann/phpunit/issues/1816): PHPUnit 4.8.1 shows "4.8.0" as version number + +## [4.8.1] - 2015-08-07 + +### Fixed + +* Fixed [#1815](https://github.com/sebastianbergmann/phpunit/issues/1815): `phpunit --self-update` does not work in PHPUnit 4.8.0 + +## [4.8.0] - 2015-08-07 + +### Added + +* Added `--check-version` commandline switch to check whether the current version of PHPUnit is used (PHAR only) +* Added `--no-coverage` commandline switch to ignore code coverage configuration from the configuration file +* Implemented [#1663](https://github.com/sebastianbergmann/phpunit/issues/1663): The Crap4J report's threshold is now configurable +* Merged [#1728](https://github.com/sebastianbergmann/phpunit/issues/1728): Implemented the `@testWith` annotation as "syntactic sugar" for data providers +* Merged [#1739](https://github.com/sebastianbergmann/phpunit/issues/1739): Added support to the commandline test runner for using options after arguments + +### Changed + +* Made the argument check of `assertContains()` and `assertNotContains()` more strict to prevent undefined behavior such as [#1808](https://github.com/sebastianbergmann/phpunit/issues/1808) +* Changed the name of the default group from `__nogroup__` to `default` + +[4.8.36]: https://github.com/sebastianbergmann/phpunit/compare/4.8.35...4.8.36 +[4.8.35]: https://github.com/sebastianbergmann/phpunit/compare/4.8.34...4.8.35 +[4.8.34]: https://github.com/sebastianbergmann/phpunit/compare/4.8.33...4.8.34 +[4.8.33]: https://github.com/sebastianbergmann/phpunit/compare/4.8.32...4.8.33 +[4.8.32]: https://github.com/sebastianbergmann/phpunit/compare/4.8.31...4.8.32 +[4.8.31]: https://github.com/sebastianbergmann/phpunit/compare/4.8.30...4.8.31 +[4.8.30]: https://github.com/sebastianbergmann/phpunit/compare/4.8.29...4.8.30 +[4.8.29]: https://github.com/sebastianbergmann/phpunit/compare/4.8.28...4.8.29 +[4.8.28]: https://github.com/sebastianbergmann/phpunit/compare/4.8.27...4.8.28 +[4.8.27]: https://github.com/sebastianbergmann/phpunit/compare/4.8.26...4.8.27 +[4.8.26]: https://github.com/sebastianbergmann/phpunit/compare/4.8.25...4.8.26 +[4.8.25]: https://github.com/sebastianbergmann/phpunit/compare/4.8.24...4.8.25 +[4.8.24]: https://github.com/sebastianbergmann/phpunit/compare/4.8.23...4.8.24 +[4.8.23]: https://github.com/sebastianbergmann/phpunit/compare/4.8.22...4.8.23 +[4.8.22]: https://github.com/sebastianbergmann/phpunit/compare/4.8.21...4.8.22 +[4.8.21]: https://github.com/sebastianbergmann/phpunit/compare/4.8.20...4.8.21 +[4.8.20]: https://github.com/sebastianbergmann/phpunit/compare/4.8.19...4.8.20 +[4.8.19]: https://github.com/sebastianbergmann/phpunit/compare/4.8.18...4.8.19 +[4.8.18]: https://github.com/sebastianbergmann/phpunit/compare/4.8.17...4.8.18 +[4.8.17]: https://github.com/sebastianbergmann/phpunit/compare/4.8.16...4.8.17 +[4.8.16]: https://github.com/sebastianbergmann/phpunit/compare/4.8.15...4.8.16 +[4.8.15]: https://github.com/sebastianbergmann/phpunit/compare/4.8.14...4.8.15 +[4.8.14]: https://github.com/sebastianbergmann/phpunit/compare/4.8.13...4.8.14 +[4.8.13]: https://github.com/sebastianbergmann/phpunit/compare/4.8.12...4.8.13 +[4.8.12]: https://github.com/sebastianbergmann/phpunit/compare/4.8.11...4.8.12 +[4.8.11]: https://github.com/sebastianbergmann/phpunit/compare/4.8.10...4.8.11 +[4.8.10]: https://github.com/sebastianbergmann/phpunit/compare/4.8.9...4.8.10 +[4.8.9]: https://github.com/sebastianbergmann/phpunit/compare/4.8.8...4.8.9 +[4.8.8]: https://github.com/sebastianbergmann/phpunit/compare/4.8.7...4.8.8 +[4.8.7]: https://github.com/sebastianbergmann/phpunit/compare/4.8.6...4.8.7 +[4.8.6]: https://github.com/sebastianbergmann/phpunit/compare/4.8.5...4.8.6 +[4.8.5]: https://github.com/sebastianbergmann/phpunit/compare/4.8.4...4.8.5 +[4.8.4]: https://github.com/sebastianbergmann/phpunit/compare/4.8.3...4.8.4 +[4.8.3]: https://github.com/sebastianbergmann/phpunit/compare/4.8.2...4.8.3 +[4.8.2]: https://github.com/sebastianbergmann/phpunit/compare/4.8.1...4.8.2 +[4.8.1]: https://github.com/sebastianbergmann/phpunit/compare/4.8.0...4.8.1 +[4.8.0]: https://github.com/sebastianbergmann/phpunit/compare/4.7...4.8.0 + diff --git a/vendor/phpunit/phpunit/README.md b/vendor/phpunit/phpunit/README.md new file mode 100644 index 000000000..53a10145a --- /dev/null +++ b/vendor/phpunit/phpunit/README.md @@ -0,0 +1,46 @@ +# PHPUnit + +PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. + +[![Latest Stable Version](https://img.shields.io/packagist/v/phpunit/phpunit.svg?style=flat-square)](https://packagist.org/packages/phpunit/phpunit) +[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%205.3.3-8892BF.svg?style=flat-square)](https://php.net/) +[![Build Status](https://img.shields.io/travis/sebastianbergmann/phpunit/4.8.svg?style=flat-square)](https://phpunit.de/build-status.html) + +## Installation + +We distribute a [PHP Archive (PHAR)](https://php.net/phar) that has all required (as well as some optional) dependencies of PHPUnit bundled in a single file: + +```bash +$ wget https://phar.phpunit.de/phpunit.phar + +$ chmod +x phpunit.phar + +$ mv phpunit.phar /usr/local/bin/phpunit +``` + +You can also immediately use the PHAR after you have downloaded it, of course: + +```bash +$ wget https://phar.phpunit.de/phpunit.phar + +$ php phpunit.phar +``` + +Alternatively, you may use [Composer](https://getcomposer.org/) to download and install PHPUnit as well as its dependencies. Please refer to the [documentation](https://phpunit.de/documentation.html) for details on how to do this. + +## Contribute + +Please refer to [CONTRIBUTING.md](https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md) for information on how to contribute to PHPUnit and its related projects. + +## List of Contributors + +Thanks to everyone who has contributed to PHPUnit! You can find a detailed list of contributors on every PHPUnit related package on GitHub. This list shows only the major components: + +* [PHPUnit](https://github.com/sebastianbergmann/phpunit/graphs/contributors) +* [PHP_CodeCoverage](https://github.com/sebastianbergmann/php-code-coverage/graphs/contributors) +* [PHPUnit_MockObject](https://github.com/sebastianbergmann/phpunit-mock-objects/graphs/contributors) + +A very special thanks to everyone who has contributed to the documentation and helps maintain the translations: + +* [PHPUnit Documentation](https://github.com/sebastianbergmann/phpunit-documentation/graphs/contributors) + diff --git a/vendor/phpunit/phpunit/build.xml b/vendor/phpunit/phpunit/build.xml new file mode 100644 index 000000000..0ad414634 --- /dev/null +++ b/vendor/phpunit/phpunit/build.xml @@ -0,0 +1,379 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/phpunit/phpunit.xml b/vendor/phpunit/phpunit/phpunit.xml new file mode 100644 index 000000000..ad6baa866 --- /dev/null +++ b/vendor/phpunit/phpunit/phpunit.xml @@ -0,0 +1,34 @@ + + + + + tests/Framework + tests/Extensions + tests/Runner + tests/Util + + + + tests/TextUI + tests/Regression + + + + + + src + + src/Framework/Assert/Functions.php + + + + + + + + + diff --git a/vendor/phpunit/phpunit/phpunit.xsd b/vendor/phpunit/phpunit/phpunit.xsd new file mode 100644 index 000000000..7c6d04ff3 --- /dev/null +++ b/vendor/phpunit/phpunit/phpunit.xsd @@ -0,0 +1,264 @@ + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 4.8 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php new file mode 100644 index 000000000..d0cbe72c5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PHPUnit\Framework; + +use PHPUnit_Framework_AssertionFailedError; + +class AssertionFailedError extends PHPUnit_Framework_AssertionFailedError +{ +} diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/Test.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/Test.php new file mode 100644 index 000000000..ce98526d7 --- /dev/null +++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/Test.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PHPUnit\Framework; + +use PHPUnit_Framework_Test; + +interface Test extends PHPUnit_Framework_Test +{ +} diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php new file mode 100644 index 000000000..535bbbedb --- /dev/null +++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PHPUnit\Framework; + +use PHPUnit_Framework_TestSuite; + +class TestSuite extends PHPUnit_Framework_TestSuite +{ +} diff --git a/vendor/phpunit/phpunit/src/Runner/Version.php b/vendor/phpunit/phpunit/src/Runner/Version.php index e1a6e78d7..45a79fc83 100644 --- a/vendor/phpunit/phpunit/src/Runner/Version.php +++ b/vendor/phpunit/phpunit/src/Runner/Version.php @@ -32,7 +32,7 @@ class PHPUnit_Runner_Version } if (self::$version === null) { - $version = new Version('4.8.35', dirname(dirname(__DIR__))); + $version = new Version('4.8.36', dirname(dirname(__DIR__))); self::$version = $version->getVersion(); } diff --git a/vendor/phpunit/phpunit/tests/Extensions/PhptTestCaseTest.php b/vendor/phpunit/phpunit/tests/Extensions/PhptTestCaseTest.php new file mode 100644 index 000000000..819f9d29f --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Extensions/PhptTestCaseTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +class Extensions_PhptTestCaseTest extends \PHPUnit_Framework_TestCase +{ + public function testParseIniSection() + { + $phptTestCase = new PhpTestCaseProxy(__FILE__); + $settings = $phptTestCase->parseIniSection("foo=1\nbar = 2\rbaz = 3\r\nempty=\nignore"); + + $expected = array( + 'foo=1', + 'bar = 2', + 'baz = 3', + 'empty=', + 'ignore', + ); + + $this->assertEquals($expected, $settings); + } +} + +class PhpTestCaseProxy extends PHPUnit_Extensions_PhptTestCase +{ + public function parseIniSection($content) + { + return parent::parseIniSection($content); + } +} diff --git a/vendor/phpunit/phpunit/tests/Extensions/RepeatedTestTest.php b/vendor/phpunit/phpunit/tests/Extensions/RepeatedTestTest.php new file mode 100644 index 000000000..de83fb5fe --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Extensions/RepeatedTestTest.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 2.0.0 + * @covers PHPUnit_Extensions_RepeatedTest + */ +class Extensions_RepeatedTestTest extends PHPUnit_Framework_TestCase +{ + protected $suite; + + public function __construct() + { + $this->suite = new PHPUnit_Framework_TestSuite; + + $this->suite->addTest(new Success); + $this->suite->addTest(new Success); + } + + public function testRepeatedOnce() + { + $test = new PHPUnit_Extensions_RepeatedTest($this->suite, 1); + $this->assertEquals(2, count($test)); + + $result = $test->run(); + $this->assertEquals(2, count($result)); + } + + public function testRepeatedMoreThanOnce() + { + $test = new PHPUnit_Extensions_RepeatedTest($this->suite, 3); + $this->assertEquals(6, count($test)); + + $result = $test->run(); + $this->assertEquals(6, count($result)); + } + + public function testRepeatedZero() + { + $test = new PHPUnit_Extensions_RepeatedTest($this->suite, 0); + $this->assertEquals(0, count($test)); + + $result = $test->run(); + $this->assertEquals(0, count($result)); + } + + public function testRepeatedNegative() + { + try { + $test = new PHPUnit_Extensions_RepeatedTest($this->suite, -1); + } catch (Exception $e) { + return; + } + + $this->fail('Should throw an Exception'); + } +} diff --git a/vendor/phpunit/phpunit/tests/Fail/fail.phpt b/vendor/phpunit/phpunit/tests/Fail/fail.phpt new file mode 100644 index 000000000..b88454fdf --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Fail/fail.phpt @@ -0,0 +1,5 @@ +--TEST-- +// This test intentionally fails and it is checked by Travis. +--FILE-- +--EXPECTF-- +unexpected diff --git a/vendor/phpunit/phpunit/tests/Framework/AssertTest.php b/vendor/phpunit/phpunit/tests/Framework/AssertTest.php new file mode 100644 index 000000000..940335e80 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/AssertTest.php @@ -0,0 +1,4135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 2.0.0 + */ +class Framework_AssertTest extends PHPUnit_Framework_TestCase +{ + /** + * @var string + */ + private $filesDirectory; + + protected function setUp() + { + $this->filesDirectory = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR; + } + + /** + * @covers PHPUnit_Framework_Assert::fail + */ + public function testFail() + { + try { + $this->fail(); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + throw new PHPUnit_Framework_AssertionFailedError('Fail did not throw fail exception'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContains + */ + public function testAssertSplObjectStorageContainsObject() + { + $a = new stdClass; + $b = new stdClass; + $c = new SplObjectStorage; + $c->attach($a); + + $this->assertContains($a, $c); + + try { + $this->assertContains($b, $c); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContains + */ + public function testAssertArrayContainsObject() + { + $a = new stdClass; + $b = new stdClass; + + $this->assertContains($a, array($a)); + + try { + $this->assertContains($a, array($b)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContains + */ + public function testAssertArrayContainsString() + { + $this->assertContains('foo', array('foo')); + + try { + $this->assertContains('foo', array('bar')); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContains + */ + public function testAssertArrayContainsNonObject() + { + $this->assertContains('foo', array(true)); + + try { + $this->assertContains('foo', array(true), '', false, true, true); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContainsOnlyInstancesOf + */ + public function testAssertContainsOnlyInstancesOf() + { + $test = array( + new Book(), + new Book + ); + $this->assertContainsOnlyInstancesOf('Book', $test); + $this->assertContainsOnlyInstancesOf('stdClass', array(new stdClass())); + + $test2 = array( + new Author('Test') + ); + try { + $this->assertContainsOnlyInstancesOf('Book', $test2); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayHasKey + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertArrayHasKeyThrowsExceptionForInvalidFirstArgument() + { + $this->assertArrayHasKey(null, array()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayHasKey + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertArrayHasKeyThrowsExceptionForInvalidSecondArgument() + { + $this->assertArrayHasKey(0, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayHasKey + */ + public function testAssertArrayHasIntegerKey() + { + $this->assertArrayHasKey(0, array('foo')); + + try { + $this->assertArrayHasKey(1, array('foo')); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArraySubset + * @covers PHPUnit_Framework_Constraint_ArraySubset + */ + public function testAssertArraySubset() + { + $array = array( + 'a' => 'item a', + 'b' => 'item b', + 'c' => array('a2' => 'item a2', 'b2' => 'item b2'), + 'd' => array('a2' => array('a3' => 'item a3', 'b3' => 'item b3')) + ); + + $this->assertArraySubset(array('a' => 'item a', 'c' => array('a2' => 'item a2')), $array); + $this->assertArraySubset(array('a' => 'item a', 'd' => array('a2' => array('b3' => 'item b3'))), $array); + + $arrayAccessData = new ArrayObject($array); + + $this->assertArraySubset(array('a' => 'item a', 'c' => array('a2' => 'item a2')), $arrayAccessData); + $this->assertArraySubset(array('a' => 'item a', 'd' => array('a2' => array('b3' => 'item b3'))), $arrayAccessData); + + try { + $this->assertArraySubset(array('a' => 'bad value'), $array); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + } + + try { + $this->assertArraySubset(array('d' => array('a2' => array('bad index' => 'item b3'))), $array); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArraySubset + * @covers PHPUnit_Framework_Constraint_ArraySubset + */ + public function testAssertArraySubsetWithDeepNestedArrays() + { + $array = array( + 'path' => array( + 'to' => array( + 'the' => array( + 'cake' => 'is a lie' + ) + ) + ) + ); + + $this->assertArraySubset(array('path' => array()), $array); + $this->assertArraySubset(array('path' => array('to' => array())), $array); + $this->assertArraySubset(array('path' => array('to' => array('the' => array()))), $array); + $this->assertArraySubset(array('path' => array('to' => array('the' => array('cake' => 'is a lie')))), $array); + + try { + $this->assertArraySubset(array('path' => array('to' => array('the' => array('cake' => 'is not a lie')))), $array); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArraySubset + * @covers PHPUnit_Framework_Constraint_ArraySubset + */ + public function testAssertArraySubsetWithNoStrictCheckAndObjects() + { + $obj = new \stdClass; + $reference = &$obj; + $array = array('a' => $obj); + + $this->assertArraySubset(array('a' => $reference), $array); + $this->assertArraySubset(array('a' => new \stdClass), $array); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArraySubset + * @covers PHPUnit_Framework_Constraint_ArraySubset + */ + public function testAssertArraySubsetWithStrictCheckAndObjects() + { + $obj = new \stdClass; + $reference = &$obj; + $array = array('a' => $obj); + + $this->assertArraySubset(array('a' => $reference), $array, true); + + try { + $this->assertArraySubset(array('a' => new \stdClass), $array, true); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail('Strict recursive array check fail.'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArraySubset + * @covers PHPUnit_Framework_Constraint_ArraySubset + * @expectedException PHPUnit_Framework_Exception + * @expectedExceptionMessage array or ArrayAccess + * @dataProvider assertArraySubsetInvalidArgumentProvider + */ + public function testAssertArraySubsetRaisesExceptionForInvalidArguments($partial, $subject) + { + $this->assertArraySubset($partial, $subject); + } + + /** + * @return array + */ + public function assertArraySubsetInvalidArgumentProvider() + { + return array( + array(false, array()), + array(array(), false), + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayNotHasKey + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertArrayNotHasKeyThrowsExceptionForInvalidFirstArgument() + { + $this->assertArrayNotHasKey(null, array()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayNotHasKey + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertArrayNotHasKeyThrowsExceptionForInvalidSecondArgument() + { + $this->assertArrayNotHasKey(0, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayNotHasKey + */ + public function testAssertArrayNotHasIntegerKey() + { + $this->assertArrayNotHasKey(1, array('foo')); + + try { + $this->assertArrayNotHasKey(0, array('foo')); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayHasKey + */ + public function testAssertArrayHasStringKey() + { + $this->assertArrayHasKey('foo', array('foo' => 'bar')); + + try { + $this->assertArrayHasKey('bar', array('foo' => 'bar')); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayNotHasKey + */ + public function testAssertArrayNotHasStringKey() + { + $this->assertArrayNotHasKey('bar', array('foo' => 'bar')); + + try { + $this->assertArrayNotHasKey('foo', array('foo' => 'bar')); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayHasKey + */ + public function testAssertArrayHasKeyAcceptsArrayObjectValue() + { + $array = new ArrayObject(); + $array['foo'] = 'bar'; + $this->assertArrayHasKey('foo', $array); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayHasKey + * @expectedException PHPUnit_Framework_AssertionFailedError + */ + public function testAssertArrayHasKeyProperlyFailsWithArrayObjectValue() + { + $array = new ArrayObject(); + $array['bar'] = 'bar'; + $this->assertArrayHasKey('foo', $array); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayHasKey + */ + public function testAssertArrayHasKeyAcceptsArrayAccessValue() + { + $array = new SampleArrayAccess(); + $array['foo'] = 'bar'; + $this->assertArrayHasKey('foo', $array); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayHasKey + * @expectedException PHPUnit_Framework_AssertionFailedError + */ + public function testAssertArrayHasKeyProperlyFailsWithArrayAccessValue() + { + $array = new SampleArrayAccess(); + $array['bar'] = 'bar'; + $this->assertArrayHasKey('foo', $array); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayNotHasKey + */ + public function testAssertArrayNotHasKeyAcceptsArrayAccessValue() + { + $array = new ArrayObject(); + $array['foo'] = 'bar'; + $this->assertArrayNotHasKey('bar', $array); + } + + /** + * @covers PHPUnit_Framework_Assert::assertArrayNotHasKey + * @expectedException PHPUnit_Framework_AssertionFailedError + */ + public function testAssertArrayNotHasKeyPropertlyFailsWithArrayAccessValue() + { + $array = new ArrayObject(); + $array['bar'] = 'bar'; + $this->assertArrayNotHasKey('bar', $array); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContains + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertContainsThrowsException() + { + $this->assertContains(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContains + */ + public function testAssertIteratorContainsObject() + { + $foo = new stdClass; + + $this->assertContains($foo, new TestIterator(array($foo))); + + try { + $this->assertContains($foo, new TestIterator(array(new stdClass))); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContains + */ + public function testAssertIteratorContainsString() + { + $this->assertContains('foo', new TestIterator(array('foo'))); + + try { + $this->assertContains('foo', new TestIterator(array('bar'))); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContains + */ + public function testAssertStringContainsString() + { + $this->assertContains('foo', 'foobar'); + + try { + $this->assertContains('foo', 'bar'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotContains + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotContainsThrowsException() + { + $this->assertNotContains(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotContains + */ + public function testAssertSplObjectStorageNotContainsObject() + { + $a = new stdClass; + $b = new stdClass; + $c = new SplObjectStorage; + $c->attach($a); + + $this->assertNotContains($b, $c); + + try { + $this->assertNotContains($a, $c); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotContains + */ + public function testAssertArrayNotContainsObject() + { + $a = new stdClass; + $b = new stdClass; + + $this->assertNotContains($a, array($b)); + + try { + $this->assertNotContains($a, array($a)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotContains + */ + public function testAssertArrayNotContainsString() + { + $this->assertNotContains('foo', array('bar')); + + try { + $this->assertNotContains('foo', array('foo')); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotContains + */ + public function testAssertArrayNotContainsNonObject() + { + $this->assertNotContains('foo', array(true), '', false, true, true); + + try { + $this->assertNotContains('foo', array(true)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotContains + */ + public function testAssertStringNotContainsString() + { + $this->assertNotContains('foo', 'bar'); + + try { + $this->assertNotContains('foo', 'foo'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContainsOnly + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertContainsOnlyThrowsException() + { + $this->assertContainsOnly(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotContainsOnly + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotContainsOnlyThrowsException() + { + $this->assertNotContainsOnly(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContainsOnlyInstancesOf + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertContainsOnlyInstancesOfThrowsException() + { + $this->assertContainsOnlyInstancesOf(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContainsOnly + */ + public function testAssertArrayContainsOnlyIntegers() + { + $this->assertContainsOnly('integer', array(1, 2, 3)); + + try { + $this->assertContainsOnly('integer', array('1', 2, 3)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotContainsOnly + */ + public function testAssertArrayNotContainsOnlyIntegers() + { + $this->assertNotContainsOnly('integer', array('1', 2, 3)); + + try { + $this->assertNotContainsOnly('integer', array(1, 2, 3)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertContainsOnly + */ + public function testAssertArrayContainsOnlyStdClass() + { + $this->assertContainsOnly('StdClass', array(new stdClass)); + + try { + $this->assertContainsOnly('StdClass', array('StdClass')); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotContainsOnly + */ + public function testAssertArrayNotContainsOnlyStdClass() + { + $this->assertNotContainsOnly('StdClass', array('StdClass')); + + try { + $this->assertNotContainsOnly('StdClass', array(new stdClass)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + protected function sameValues() + { + $object = new SampleClass(4, 8, 15); + // cannot use $filesDirectory, because neither setUp() nor + // setUpBeforeClass() are executed before the data providers + $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'foo.xml'; + $resource = fopen($file, 'r'); + + return array( + // null + array(null, null), + // strings + array('a', 'a'), + // integers + array(0, 0), + // floats + array(2.3, 2.3), + array(1/3, 1 - 2/3), + array(log(0), log(0)), + // arrays + array(array(), array()), + array(array(0 => 1), array(0 => 1)), + array(array(0 => null), array(0 => null)), + array(array('a', 'b' => array(1, 2)), array('a', 'b' => array(1, 2))), + // objects + array($object, $object), + // resources + array($resource, $resource), + ); + } + + protected function notEqualValues() + { + // cyclic dependencies + $book1 = new Book; + $book1->author = new Author('Terry Pratchett'); + $book1->author->books[] = $book1; + $book2 = new Book; + $book2->author = new Author('Terry Pratch'); + $book2->author->books[] = $book2; + + $book3 = new Book; + $book3->author = 'Terry Pratchett'; + $book4 = new stdClass; + $book4->author = 'Terry Pratchett'; + + $object1 = new SampleClass(4, 8, 15); + $object2 = new SampleClass(16, 23, 42); + $object3 = new SampleClass(4, 8, 15); + $storage1 = new SplObjectStorage; + $storage1->attach($object1); + $storage2 = new SplObjectStorage; + $storage2->attach($object3); // same content, different object + + // cannot use $filesDirectory, because neither setUp() nor + // setUpBeforeClass() are executed before the data providers + $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'foo.xml'; + + return array( + // strings + array('a', 'b'), + array('a', 'A'), + // https://github.com/sebastianbergmann/phpunit/issues/1023 + array('9E6666666','9E7777777'), + // integers + array(1, 2), + array(2, 1), + // floats + array(2.3, 4.2), + array(2.3, 4.2, 0.5), + array(array(2.3), array(4.2), 0.5), + array(array(array(2.3)), array(array(4.2)), 0.5), + array(new Struct(2.3), new Struct(4.2), 0.5), + array(array(new Struct(2.3)), array(new Struct(4.2)), 0.5), + // NAN + array(NAN, NAN), + // arrays + array(array(), array(0 => 1)), + array(array(0 => 1), array()), + array(array(0 => null), array()), + array(array(0 => 1, 1 => 2), array(0 => 1, 1 => 3)), + array(array('a', 'b' => array(1, 2)), array('a', 'b' => array(2, 1))), + // objects + array(new SampleClass(4, 8, 15), new SampleClass(16, 23, 42)), + array($object1, $object2), + array($book1, $book2), + array($book3, $book4), // same content, different class + // resources + array(fopen($file, 'r'), fopen($file, 'r')), + // SplObjectStorage + array($storage1, $storage2), + // DOMDocument + array( + PHPUnit_Util_XML::load(''), + PHPUnit_Util_XML::load(''), + ), + array( + PHPUnit_Util_XML::load(''), + PHPUnit_Util_XML::load(''), + ), + array( + PHPUnit_Util_XML::load(' bar '), + PHPUnit_Util_XML::load(''), + ), + array( + PHPUnit_Util_XML::load(''), + PHPUnit_Util_XML::load(''), + ), + array( + PHPUnit_Util_XML::load(' bar '), + PHPUnit_Util_XML::load(' bir '), + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York')), + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York')), + 3500 + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 05:13:35', new DateTimeZone('America/New_York')), + 3500 + ), + array( + new DateTime('2013-03-29', new DateTimeZone('America/New_York')), + new DateTime('2013-03-30', new DateTimeZone('America/New_York')), + ), + array( + new DateTime('2013-03-29', new DateTimeZone('America/New_York')), + new DateTime('2013-03-30', new DateTimeZone('America/New_York')), + 43200 + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')), + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')), + 3500 + ), + array( + new DateTime('2013-03-30', new DateTimeZone('America/New_York')), + new DateTime('2013-03-30', new DateTimeZone('America/Chicago')), + ), + array( + new DateTime('2013-03-29T05:13:35-0600'), + new DateTime('2013-03-29T04:13:35-0600'), + ), + array( + new DateTime('2013-03-29T05:13:35-0600'), + new DateTime('2013-03-29T05:13:35-0500'), + ), + // Exception + //array(new Exception('Exception 1'), new Exception('Exception 2')), + // different types + array(new SampleClass(4, 8, 15), false), + array(false, new SampleClass(4, 8, 15)), + array(array(0 => 1, 1 => 2), false), + array(false, array(0 => 1, 1 => 2)), + array(array(), new stdClass), + array(new stdClass, array()), + // PHP: 0 == 'Foobar' => true! + // We want these values to differ + array(0, 'Foobar'), + array('Foobar', 0), + array(3, acos(8)), + array(acos(8), 3) + ); + } + + protected function equalValues() + { + // cyclic dependencies + $book1 = new Book; + $book1->author = new Author('Terry Pratchett'); + $book1->author->books[] = $book1; + $book2 = new Book; + $book2->author = new Author('Terry Pratchett'); + $book2->author->books[] = $book2; + + $object1 = new SampleClass(4, 8, 15); + $object2 = new SampleClass(4, 8, 15); + $storage1 = new SplObjectStorage; + $storage1->attach($object1); + $storage2 = new SplObjectStorage; + $storage2->attach($object1); + + return array( + // strings + array('a', 'A', 0, false, true), // ignore case + // arrays + array(array('a' => 1, 'b' => 2), array('b' => 2, 'a' => 1)), + array(array(1), array('1')), + array(array(3, 2, 1), array(2, 3, 1), 0, true), // canonicalized comparison + // floats + array(2.3, 2.5, 0.5), + array(array(2.3), array(2.5), 0.5), + array(array(array(2.3)), array(array(2.5)), 0.5), + array(new Struct(2.3), new Struct(2.5), 0.5), + array(array(new Struct(2.3)), array(new Struct(2.5)), 0.5), + // numeric with delta + array(1, 2, 1), + // objects + array($object1, $object2), + array($book1, $book2), + // SplObjectStorage + array($storage1, $storage2), + // DOMDocument + array( + PHPUnit_Util_XML::load(''), + PHPUnit_Util_XML::load(''), + ), + array( + PHPUnit_Util_XML::load(''), + PHPUnit_Util_XML::load(''), + ), + array( + PHPUnit_Util_XML::load(''), + PHPUnit_Util_XML::load(''), + ), + array( + PHPUnit_Util_XML::load("\n \n"), + PHPUnit_Util_XML::load(''), + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 04:13:25', new DateTimeZone('America/New_York')), + 10 + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 04:14:40', new DateTimeZone('America/New_York')), + 65 + ), + array( + new DateTime('2013-03-29', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29', new DateTimeZone('America/New_York')), + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago')), + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 03:13:49', new DateTimeZone('America/Chicago')), + 15 + ), + array( + new DateTime('2013-03-30', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago')), + ), + array( + new DateTime('2013-03-30', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 23:01:30', new DateTimeZone('America/Chicago')), + 100 + ), + array( + new DateTime('@1364616000'), + new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago')), + ), + array( + new DateTime('2013-03-29T05:13:35-0500'), + new DateTime('2013-03-29T04:13:35-0600'), + ), + // Exception + //array(new Exception('Exception 1'), new Exception('Exception 1')), + // mixed types + array(0, '0'), + array('0', 0), + array(2.3, '2.3'), + array('2.3', 2.3), + array((string) (1/3), 1 - 2/3), + array(1/3, (string) (1 - 2/3)), + array('string representation', new ClassWithToString), + array(new ClassWithToString, 'string representation'), + ); + } + + public function equalProvider() + { + // same |= equal + return array_merge($this->equalValues(), $this->sameValues()); + } + + public function notEqualProvider() + { + return $this->notEqualValues(); + } + + public function sameProvider() + { + return $this->sameValues(); + } + + public function notSameProvider() + { + // not equal |= not same + // equal, ¬same |= not same + return array_merge($this->notEqualValues(), $this->equalValues()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEquals + * @dataProvider equalProvider + */ + public function testAssertEqualsSucceeds($a, $b, $delta = 0.0, $canonicalize = false, $ignoreCase = false) + { + $this->assertEquals($a, $b, '', $delta, 10, $canonicalize, $ignoreCase); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEquals + * @dataProvider notEqualProvider + */ + public function testAssertEqualsFails($a, $b, $delta = 0.0, $canonicalize = false, $ignoreCase = false) + { + try { + $this->assertEquals($a, $b, '', $delta, 10, $canonicalize, $ignoreCase); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotEquals + * @dataProvider notEqualProvider + */ + public function testAssertNotEqualsSucceeds($a, $b, $delta = 0.0, $canonicalize = false, $ignoreCase = false) + { + $this->assertNotEquals($a, $b, '', $delta, 10, $canonicalize, $ignoreCase); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotEquals + * @dataProvider equalProvider + */ + public function testAssertNotEqualsFails($a, $b, $delta = 0.0, $canonicalize = false, $ignoreCase = false) + { + try { + $this->assertNotEquals($a, $b, '', $delta, 10, $canonicalize, $ignoreCase); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertSame + * @dataProvider sameProvider + */ + public function testAssertSameSucceeds($a, $b) + { + $this->assertSame($a, $b); + } + + /** + * @covers PHPUnit_Framework_Assert::assertSame + * @dataProvider notSameProvider + */ + public function testAssertSameFails($a, $b) + { + try { + $this->assertSame($a, $b); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotSame + * @dataProvider notSameProvider + */ + public function testAssertNotSameSucceeds($a, $b) + { + $this->assertNotSame($a, $b); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotSame + * @dataProvider sameProvider + */ + public function testAssertNotSameFails($a, $b) + { + try { + $this->assertNotSame($a, $b); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertXmlFileEqualsXmlFile + */ + public function testAssertXmlFileEqualsXmlFile() + { + $this->assertXmlFileEqualsXmlFile( + $this->filesDirectory . 'foo.xml', + $this->filesDirectory . 'foo.xml' + ); + + try { + $this->assertXmlFileEqualsXmlFile( + $this->filesDirectory . 'foo.xml', + $this->filesDirectory . 'bar.xml' + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertXmlFileNotEqualsXmlFile + */ + public function testAssertXmlFileNotEqualsXmlFile() + { + $this->assertXmlFileNotEqualsXmlFile( + $this->filesDirectory . 'foo.xml', + $this->filesDirectory . 'bar.xml' + ); + + try { + $this->assertXmlFileNotEqualsXmlFile( + $this->filesDirectory . 'foo.xml', + $this->filesDirectory . 'foo.xml' + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertXmlStringEqualsXmlFile + */ + public function testAssertXmlStringEqualsXmlFile() + { + $this->assertXmlStringEqualsXmlFile( + $this->filesDirectory . 'foo.xml', + file_get_contents($this->filesDirectory . 'foo.xml') + ); + + try { + $this->assertXmlStringEqualsXmlFile( + $this->filesDirectory . 'foo.xml', + file_get_contents($this->filesDirectory . 'bar.xml') + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlFile + */ + public function testXmlStringNotEqualsXmlFile() + { + $this->assertXmlStringNotEqualsXmlFile( + $this->filesDirectory . 'foo.xml', + file_get_contents($this->filesDirectory . 'bar.xml') + ); + + try { + $this->assertXmlStringNotEqualsXmlFile( + $this->filesDirectory . 'foo.xml', + file_get_contents($this->filesDirectory . 'foo.xml') + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString + */ + public function testAssertXmlStringEqualsXmlString() + { + $this->assertXmlStringEqualsXmlString('', ''); + + try { + $this->assertXmlStringEqualsXmlString('', ''); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @expectedException PHPUnit_Framework_Exception + * @covers PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString + * @ticket 1860 + */ + public function testAssertXmlStringEqualsXmlString2() + { + $this->assertXmlStringEqualsXmlString('', ''); + } + + /** + * @covers PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString + * @ticket 1860 + */ + public function testAssertXmlStringEqualsXmlString3() + { + $expected = << + + + +XML; + + $actual = << + + + +XML; + + $this->assertXmlStringEqualsXmlString($expected, $actual); + } + + /** + * @covers PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlString + */ + public function testAssertXmlStringNotEqualsXmlString() + { + $this->assertXmlStringNotEqualsXmlString('', ''); + + try { + $this->assertXmlStringNotEqualsXmlString('', ''); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEqualXMLStructure + */ + public function testXMLStructureIsSame() + { + $expected = new DOMDocument; + $expected->load($this->filesDirectory . 'structureExpected.xml'); + + $actual = new DOMDocument; + $actual->load($this->filesDirectory . 'structureExpected.xml'); + + $this->assertEqualXMLStructure( + $expected->firstChild, $actual->firstChild, true + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEqualXMLStructure + * @expectedException PHPUnit_Framework_ExpectationFailedException + */ + public function testXMLStructureWrongNumberOfAttributes() + { + $expected = new DOMDocument; + $expected->load($this->filesDirectory . 'structureExpected.xml'); + + $actual = new DOMDocument; + $actual->load($this->filesDirectory . 'structureWrongNumberOfAttributes.xml'); + + $this->assertEqualXMLStructure( + $expected->firstChild, $actual->firstChild, true + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEqualXMLStructure + * @expectedException PHPUnit_Framework_ExpectationFailedException + */ + public function testXMLStructureWrongNumberOfNodes() + { + $expected = new DOMDocument; + $expected->load($this->filesDirectory . 'structureExpected.xml'); + + $actual = new DOMDocument; + $actual->load($this->filesDirectory . 'structureWrongNumberOfNodes.xml'); + + $this->assertEqualXMLStructure( + $expected->firstChild, $actual->firstChild, true + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEqualXMLStructure + */ + public function testXMLStructureIsSameButDataIsNot() + { + $expected = new DOMDocument; + $expected->load($this->filesDirectory . 'structureExpected.xml'); + + $actual = new DOMDocument; + $actual->load($this->filesDirectory . 'structureIsSameButDataIsNot.xml'); + + $this->assertEqualXMLStructure( + $expected->firstChild, $actual->firstChild, true + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEqualXMLStructure + */ + public function testXMLStructureAttributesAreSameButValuesAreNot() + { + $expected = new DOMDocument; + $expected->load($this->filesDirectory . 'structureExpected.xml'); + + $actual = new DOMDocument; + $actual->load($this->filesDirectory . 'structureAttributesAreSameButValuesAreNot.xml'); + + $this->assertEqualXMLStructure( + $expected->firstChild, $actual->firstChild, true + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEqualXMLStructure + */ + public function testXMLStructureIgnoreTextNodes() + { + $expected = new DOMDocument; + $expected->load($this->filesDirectory . 'structureExpected.xml'); + + $actual = new DOMDocument; + $actual->load($this->filesDirectory . 'structureIgnoreTextNodes.xml'); + + $this->assertEqualXMLStructure( + $expected->firstChild, $actual->firstChild, true + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEquals + */ + public function testAssertStringEqualsNumeric() + { + $this->assertEquals('0', 0); + + try { + $this->assertEquals('0', 1); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotEquals + */ + public function testAssertStringEqualsNumeric2() + { + $this->assertNotEquals('A', 0); + } + + /** + * @covers PHPUnit_Framework_Assert::assertFileExists + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertFileExistsThrowsException() + { + $this->assertFileExists(null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertFileExists + */ + public function testAssertFileExists() + { + $this->assertFileExists(__FILE__); + + try { + $this->assertFileExists(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertFileNotExists + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertFileNotExistsThrowsException() + { + $this->assertFileNotExists(null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertFileNotExists + */ + public function testAssertFileNotExists() + { + $this->assertFileNotExists(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting'); + + try { + $this->assertFileNotExists(__FILE__); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectHasAttribute + */ + public function testAssertObjectHasAttribute() + { + $o = new Author('Terry Pratchett'); + + $this->assertObjectHasAttribute('name', $o); + + try { + $this->assertObjectHasAttribute('foo', $o); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectNotHasAttribute + */ + public function testAssertObjectNotHasAttribute() + { + $o = new Author('Terry Pratchett'); + + $this->assertObjectNotHasAttribute('foo', $o); + + try { + $this->assertObjectNotHasAttribute('name', $o); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNull + */ + public function testAssertNull() + { + $this->assertNull(null); + + try { + $this->assertNull(new stdClass); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotNull + */ + public function testAssertNotNull() + { + $this->assertNotNull(new stdClass); + + try { + $this->assertNotNull(null); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertTrue + */ + public function testAssertTrue() + { + $this->assertTrue(true); + + try { + $this->assertTrue(false); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotTrue + */ + public function testAssertNotTrue() + { + $this->assertNotTrue(false); + $this->assertNotTrue(1); + $this->assertNotTrue('true'); + + try { + $this->assertNotTrue(true); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertFalse + */ + public function testAssertFalse() + { + $this->assertFalse(false); + + try { + $this->assertFalse(true); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotFalse + */ + public function testAssertNotFalse() + { + $this->assertNotFalse(true); + $this->assertNotFalse(0); + $this->assertNotFalse(''); + + try { + $this->assertNotFalse(false); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertRegExp + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertRegExpThrowsException() + { + $this->assertRegExp(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertRegExp + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertRegExpThrowsException2() + { + $this->assertRegExp('', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotRegExp + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotRegExpThrowsException() + { + $this->assertNotRegExp(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotRegExp + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotRegExpThrowsException2() + { + $this->assertNotRegExp('', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertRegExp + */ + public function testAssertRegExp() + { + $this->assertRegExp('/foo/', 'foobar'); + + try { + $this->assertRegExp('/foo/', 'bar'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotRegExp + */ + public function testAssertNotRegExp() + { + $this->assertNotRegExp('/foo/', 'bar'); + + try { + $this->assertNotRegExp('/foo/', 'foobar'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertSame + */ + public function testAssertSame() + { + $o = new stdClass; + + $this->assertSame($o, $o); + + try { + $this->assertSame( + new stdClass, + new stdClass + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertSame + */ + public function testAssertSame2() + { + $this->assertSame(true, true); + $this->assertSame(false, false); + + try { + $this->assertSame(true, false); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotSame + */ + public function testAssertNotSame() + { + $this->assertNotSame( + new stdClass, + null + ); + + $this->assertNotSame( + null, + new stdClass + ); + + $this->assertNotSame( + new stdClass, + new stdClass + ); + + $o = new stdClass; + + try { + $this->assertNotSame($o, $o); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotSame + */ + public function testAssertNotSame2() + { + $this->assertNotSame(true, false); + $this->assertNotSame(false, true); + + try { + $this->assertNotSame(true, true); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotSame + */ + public function testAssertNotSameFailsNull() + { + try { + $this->assertNotSame(null, null); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertGreaterThan + */ + public function testGreaterThan() + { + $this->assertGreaterThan(1, 2); + + try { + $this->assertGreaterThan(2, 1); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeGreaterThan + */ + public function testAttributeGreaterThan() + { + $this->assertAttributeGreaterThan( + 1, 'bar', new ClassWithNonPublicAttributes + ); + + try { + $this->assertAttributeGreaterThan( + 1, 'foo', new ClassWithNonPublicAttributes + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertGreaterThanOrEqual + */ + public function testGreaterThanOrEqual() + { + $this->assertGreaterThanOrEqual(1, 2); + + try { + $this->assertGreaterThanOrEqual(2, 1); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeGreaterThanOrEqual + */ + public function testAttributeGreaterThanOrEqual() + { + $this->assertAttributeGreaterThanOrEqual( + 1, 'bar', new ClassWithNonPublicAttributes + ); + + try { + $this->assertAttributeGreaterThanOrEqual( + 2, 'foo', new ClassWithNonPublicAttributes + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertLessThan + */ + public function testLessThan() + { + $this->assertLessThan(2, 1); + + try { + $this->assertLessThan(1, 2); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeLessThan + */ + public function testAttributeLessThan() + { + $this->assertAttributeLessThan( + 2, 'foo', new ClassWithNonPublicAttributes + ); + + try { + $this->assertAttributeLessThan( + 1, 'bar', new ClassWithNonPublicAttributes + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertLessThanOrEqual + */ + public function testLessThanOrEqual() + { + $this->assertLessThanOrEqual(2, 1); + + try { + $this->assertLessThanOrEqual(1, 2); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeLessThanOrEqual + */ + public function testAttributeLessThanOrEqual() + { + $this->assertAttributeLessThanOrEqual( + 2, 'foo', new ClassWithNonPublicAttributes + ); + + try { + $this->assertAttributeLessThanOrEqual( + 1, 'bar', new ClassWithNonPublicAttributes + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::readAttribute + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @covers PHPUnit_Framework_Assert::getObjectAttribute + */ + public function testReadAttribute() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertEquals('foo', $this->readAttribute($obj, 'publicAttribute')); + $this->assertEquals('bar', $this->readAttribute($obj, 'protectedAttribute')); + $this->assertEquals('baz', $this->readAttribute($obj, 'privateAttribute')); + $this->assertEquals('bar', $this->readAttribute($obj, 'protectedParentAttribute')); + //$this->assertEquals('bar', $this->readAttribute($obj, 'privateParentAttribute')); + } + + /** + * @covers PHPUnit_Framework_Assert::readAttribute + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @covers PHPUnit_Framework_Assert::getObjectAttribute + */ + public function testReadAttribute2() + { + $this->assertEquals('foo', $this->readAttribute('ClassWithNonPublicAttributes', 'publicStaticAttribute')); + $this->assertEquals('bar', $this->readAttribute('ClassWithNonPublicAttributes', 'protectedStaticAttribute')); + $this->assertEquals('baz', $this->readAttribute('ClassWithNonPublicAttributes', 'privateStaticAttribute')); + $this->assertEquals('foo', $this->readAttribute('ClassWithNonPublicAttributes', 'protectedStaticParentAttribute')); + $this->assertEquals('foo', $this->readAttribute('ClassWithNonPublicAttributes', 'privateStaticParentAttribute')); + } + + /** + * @covers PHPUnit_Framework_Assert::readAttribute + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @covers PHPUnit_Framework_Assert::getObjectAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testReadAttribute3() + { + $this->readAttribute('StdClass', null); + } + + /** + * @covers PHPUnit_Framework_Assert::readAttribute + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @covers PHPUnit_Framework_Assert::getObjectAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testReadAttribute4() + { + $this->readAttribute('NotExistingClass', 'foo'); + } + + /** + * @covers PHPUnit_Framework_Assert::readAttribute + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @covers PHPUnit_Framework_Assert::getObjectAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testReadAttribute5() + { + $this->readAttribute(null, 'foo'); + } + + /** + * @covers PHPUnit_Framework_Assert::readAttribute + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @covers PHPUnit_Framework_Assert::getObjectAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testReadAttributeIfAttributeNameIsNotValid() + { + $this->readAttribute('StdClass', '2'); + } + + /** + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testGetStaticAttributeRaisesExceptionForInvalidFirstArgument() + { + $this->getStaticAttribute(null, 'foo'); + } + + /** + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testGetStaticAttributeRaisesExceptionForInvalidFirstArgument2() + { + $this->getStaticAttribute('NotExistingClass', 'foo'); + } + + /** + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testGetStaticAttributeRaisesExceptionForInvalidSecondArgument() + { + $this->getStaticAttribute('stdClass', null); + } + + /** + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testGetStaticAttributeRaisesExceptionForInvalidSecondArgument2() + { + $this->getStaticAttribute('stdClass', '0'); + } + + /** + * @covers PHPUnit_Framework_Assert::getStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testGetStaticAttributeRaisesExceptionForInvalidSecondArgument3() + { + $this->getStaticAttribute('stdClass', 'foo'); + } + + /** + * @covers PHPUnit_Framework_Assert::getObjectAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testGetObjectAttributeRaisesExceptionForInvalidFirstArgument() + { + $this->getObjectAttribute(null, 'foo'); + } + + /** + * @covers PHPUnit_Framework_Assert::getObjectAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testGetObjectAttributeRaisesExceptionForInvalidSecondArgument() + { + $this->getObjectAttribute(new stdClass, null); + } + + /** + * @covers PHPUnit_Framework_Assert::getObjectAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testGetObjectAttributeRaisesExceptionForInvalidSecondArgument2() + { + $this->getObjectAttribute(new stdClass, '0'); + } + + /** + * @covers PHPUnit_Framework_Assert::getObjectAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testGetObjectAttributeRaisesExceptionForInvalidSecondArgument3() + { + $this->getObjectAttribute(new stdClass, 'foo'); + } + + /** + * @covers PHPUnit_Framework_Assert::getObjectAttribute + */ + public function testGetObjectAttributeWorksForInheritedAttributes() + { + $this->assertEquals( + 'bar', + $this->getObjectAttribute(new ClassWithNonPublicAttributes, 'privateParentAttribute') + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeContains + */ + public function testAssertPublicAttributeContains() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeContains('foo', 'publicArray', $obj); + + try { + $this->assertAttributeContains('bar', 'publicArray', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeContainsOnly + */ + public function testAssertPublicAttributeContainsOnly() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeContainsOnly('string', 'publicArray', $obj); + + try { + $this->assertAttributeContainsOnly('integer', 'publicArray', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotContains + */ + public function testAssertPublicAttributeNotContains() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeNotContains('bar', 'publicArray', $obj); + + try { + $this->assertAttributeNotContains('foo', 'publicArray', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotContainsOnly + */ + public function testAssertPublicAttributeNotContainsOnly() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeNotContainsOnly('integer', 'publicArray', $obj); + + try { + $this->assertAttributeNotContainsOnly('string', 'publicArray', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeContains + */ + public function testAssertProtectedAttributeContains() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeContains('bar', 'protectedArray', $obj); + + try { + $this->assertAttributeContains('foo', 'protectedArray', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotContains + */ + public function testAssertProtectedAttributeNotContains() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeNotContains('foo', 'protectedArray', $obj); + + try { + $this->assertAttributeNotContains('bar', 'protectedArray', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeContains + */ + public function testAssertPrivateAttributeContains() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeContains('baz', 'privateArray', $obj); + + try { + $this->assertAttributeContains('foo', 'privateArray', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotContains + */ + public function testAssertPrivateAttributeNotContains() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeNotContains('foo', 'privateArray', $obj); + + try { + $this->assertAttributeNotContains('baz', 'privateArray', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeContains + */ + public function testAssertAttributeContainsNonObject() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeContains(true, 'privateArray', $obj); + + try { + $this->assertAttributeContains(true, 'privateArray', $obj, '', false, true, true); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotContains + */ + public function testAssertAttributeNotContainsNonObject() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeNotContains(true, 'privateArray', $obj, '', false, true, true); + + try { + $this->assertAttributeNotContains(true, 'privateArray', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeEquals + */ + public function testAssertPublicAttributeEquals() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeEquals('foo', 'publicAttribute', $obj); + + try { + $this->assertAttributeEquals('bar', 'publicAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotEquals + */ + public function testAssertPublicAttributeNotEquals() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeNotEquals('bar', 'publicAttribute', $obj); + + try { + $this->assertAttributeNotEquals('foo', 'publicAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeSame + */ + public function testAssertPublicAttributeSame() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeSame('foo', 'publicAttribute', $obj); + + try { + $this->assertAttributeSame('bar', 'publicAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotSame + */ + public function testAssertPublicAttributeNotSame() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeNotSame('bar', 'publicAttribute', $obj); + + try { + $this->assertAttributeNotSame('foo', 'publicAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeEquals + */ + public function testAssertProtectedAttributeEquals() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeEquals('bar', 'protectedAttribute', $obj); + + try { + $this->assertAttributeEquals('foo', 'protectedAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotEquals + */ + public function testAssertProtectedAttributeNotEquals() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeNotEquals('foo', 'protectedAttribute', $obj); + + try { + $this->assertAttributeNotEquals('bar', 'protectedAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeEquals + */ + public function testAssertPrivateAttributeEquals() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeEquals('baz', 'privateAttribute', $obj); + + try { + $this->assertAttributeEquals('foo', 'privateAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotEquals + */ + public function testAssertPrivateAttributeNotEquals() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertAttributeNotEquals('foo', 'privateAttribute', $obj); + + try { + $this->assertAttributeNotEquals('baz', 'privateAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeEquals + */ + public function testAssertPublicStaticAttributeEquals() + { + $this->assertAttributeEquals('foo', 'publicStaticAttribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertAttributeEquals('bar', 'publicStaticAttribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotEquals + */ + public function testAssertPublicStaticAttributeNotEquals() + { + $this->assertAttributeNotEquals('bar', 'publicStaticAttribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertAttributeNotEquals('foo', 'publicStaticAttribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeEquals + */ + public function testAssertProtectedStaticAttributeEquals() + { + $this->assertAttributeEquals('bar', 'protectedStaticAttribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertAttributeEquals('foo', 'protectedStaticAttribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotEquals + */ + public function testAssertProtectedStaticAttributeNotEquals() + { + $this->assertAttributeNotEquals('foo', 'protectedStaticAttribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertAttributeNotEquals('bar', 'protectedStaticAttribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeEquals + */ + public function testAssertPrivateStaticAttributeEquals() + { + $this->assertAttributeEquals('baz', 'privateStaticAttribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertAttributeEquals('foo', 'privateStaticAttribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotEquals + */ + public function testAssertPrivateStaticAttributeNotEquals() + { + $this->assertAttributeNotEquals('foo', 'privateStaticAttribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertAttributeNotEquals('baz', 'privateStaticAttribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassHasAttributeThrowsException() + { + $this->assertClassHasAttribute(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassHasAttributeThrowsException2() + { + $this->assertClassHasAttribute('foo', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassHasAttributeThrowsExceptionIfAttributeNameIsNotValid() + { + $this->assertClassHasAttribute('1', 'ClassWithNonPublicAttributes'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassNotHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassNotHasAttributeThrowsException() + { + $this->assertClassNotHasAttribute(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassNotHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassNotHasAttributeThrowsException2() + { + $this->assertClassNotHasAttribute('foo', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassNotHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassNotHasAttributeThrowsExceptionIfAttributeNameIsNotValid() + { + $this->assertClassNotHasAttribute('1', 'ClassWithNonPublicAttributes'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassHasStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassHasStaticAttributeThrowsException() + { + $this->assertClassHasStaticAttribute(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassHasStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassHasStaticAttributeThrowsException2() + { + $this->assertClassHasStaticAttribute('foo', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassHasStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassHasStaticAttributeThrowsExceptionIfAttributeNameIsNotValid() + { + $this->assertClassHasStaticAttribute('1', 'ClassWithNonPublicAttributes'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassNotHasStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassNotHasStaticAttributeThrowsException() + { + $this->assertClassNotHasStaticAttribute(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassNotHasStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassNotHasStaticAttributeThrowsException2() + { + $this->assertClassNotHasStaticAttribute('foo', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassNotHasStaticAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertClassNotHasStaticAttributeThrowsExceptionIfAttributeNameIsNotValid() + { + $this->assertClassNotHasStaticAttribute('1', 'ClassWithNonPublicAttributes'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertObjectHasAttributeThrowsException() + { + $this->assertObjectHasAttribute(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertObjectHasAttributeThrowsException2() + { + $this->assertObjectHasAttribute('foo', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertObjectHasAttributeThrowsExceptionIfAttributeNameIsNotValid() + { + $this->assertObjectHasAttribute('1', 'ClassWithNonPublicAttributes'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectNotHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertObjectNotHasAttributeThrowsException() + { + $this->assertObjectNotHasAttribute(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectNotHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertObjectNotHasAttributeThrowsException2() + { + $this->assertObjectNotHasAttribute('foo', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectNotHasAttribute + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertObjectNotHasAttributeThrowsExceptionIfAttributeNameIsNotValid() + { + $this->assertObjectNotHasAttribute('1', 'ClassWithNonPublicAttributes'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassHasAttribute + */ + public function testClassHasPublicAttribute() + { + $this->assertClassHasAttribute('publicAttribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertClassHasAttribute('attribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassNotHasAttribute + */ + public function testClassNotHasPublicAttribute() + { + $this->assertClassNotHasAttribute('attribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertClassNotHasAttribute('publicAttribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassHasStaticAttribute + */ + public function testClassHasPublicStaticAttribute() + { + $this->assertClassHasStaticAttribute('publicStaticAttribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertClassHasStaticAttribute('attribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertClassNotHasStaticAttribute + */ + public function testClassNotHasPublicStaticAttribute() + { + $this->assertClassNotHasStaticAttribute('attribute', 'ClassWithNonPublicAttributes'); + + try { + $this->assertClassNotHasStaticAttribute('publicStaticAttribute', 'ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectHasAttribute + */ + public function testObjectHasPublicAttribute() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertObjectHasAttribute('publicAttribute', $obj); + + try { + $this->assertObjectHasAttribute('attribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectNotHasAttribute + */ + public function testObjectNotHasPublicAttribute() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertObjectNotHasAttribute('attribute', $obj); + + try { + $this->assertObjectNotHasAttribute('publicAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectHasAttribute + */ + public function testObjectHasOnTheFlyAttribute() + { + $obj = new stdClass; + $obj->foo = 'bar'; + + $this->assertObjectHasAttribute('foo', $obj); + + try { + $this->assertObjectHasAttribute('bar', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectNotHasAttribute + */ + public function testObjectNotHasOnTheFlyAttribute() + { + $obj = new stdClass; + $obj->foo = 'bar'; + + $this->assertObjectNotHasAttribute('bar', $obj); + + try { + $this->assertObjectNotHasAttribute('foo', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectHasAttribute + */ + public function testObjectHasProtectedAttribute() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertObjectHasAttribute('protectedAttribute', $obj); + + try { + $this->assertObjectHasAttribute('attribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectNotHasAttribute + */ + public function testObjectNotHasProtectedAttribute() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertObjectNotHasAttribute('attribute', $obj); + + try { + $this->assertObjectNotHasAttribute('protectedAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectHasAttribute + */ + public function testObjectHasPrivateAttribute() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertObjectHasAttribute('privateAttribute', $obj); + + try { + $this->assertObjectHasAttribute('attribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertObjectNotHasAttribute + */ + public function testObjectNotHasPrivateAttribute() + { + $obj = new ClassWithNonPublicAttributes; + + $this->assertObjectNotHasAttribute('attribute', $obj); + + try { + $this->assertObjectNotHasAttribute('privateAttribute', $obj); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::attribute + * @covers PHPUnit_Framework_Assert::equalTo + */ + public function testAssertThatAttributeEquals() + { + $this->assertThat( + new ClassWithNonPublicAttributes, + $this->attribute( + $this->equalTo('foo'), + 'publicAttribute' + ) + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::attribute + * @covers PHPUnit_Framework_Assert::equalTo + * @expectedException PHPUnit_Framework_AssertionFailedError + */ + public function testAssertThatAttributeEquals2() + { + $this->assertThat( + new ClassWithNonPublicAttributes, + $this->attribute( + $this->equalTo('bar'), + 'publicAttribute' + ) + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::attribute + * @covers PHPUnit_Framework_Assert::equalTo + */ + public function testAssertThatAttributeEqualTo() + { + $this->assertThat( + new ClassWithNonPublicAttributes, + $this->attributeEqualTo('publicAttribute', 'foo') + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::anything + */ + public function testAssertThatAnything() + { + $this->assertThat('anything', $this->anything()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::isTrue + */ + public function testAssertThatIsTrue() + { + $this->assertThat(true, $this->isTrue()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::isFalse + */ + public function testAssertThatIsFalse() + { + $this->assertThat(false, $this->isFalse()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::isJson + */ + public function testAssertThatIsJson() + { + $this->assertThat('{}', $this->isJson()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::anything + * @covers PHPUnit_Framework_Assert::logicalAnd + */ + public function testAssertThatAnythingAndAnything() + { + $this->assertThat( + 'anything', + $this->logicalAnd( + $this->anything(), $this->anything() + ) + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::anything + * @covers PHPUnit_Framework_Assert::logicalOr + */ + public function testAssertThatAnythingOrAnything() + { + $this->assertThat( + 'anything', + $this->logicalOr( + $this->anything(), $this->anything() + ) + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::anything + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_Assert::logicalXor + */ + public function testAssertThatAnythingXorNotAnything() + { + $this->assertThat( + 'anything', + $this->logicalXor( + $this->anything(), + $this->logicalNot($this->anything()) + ) + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::contains + */ + public function testAssertThatContains() + { + $this->assertThat(array('foo'), $this->contains('foo')); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::stringContains + */ + public function testAssertThatStringContains() + { + $this->assertThat('barfoobar', $this->stringContains('foo')); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::containsOnly + */ + public function testAssertThatContainsOnly() + { + $this->assertThat(array('foo'), $this->containsOnly('string')); + } + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::containsOnlyInstancesOf + */ + public function testAssertThatContainsOnlyInstancesOf() + { + $this->assertThat(array(new Book), $this->containsOnlyInstancesOf('Book')); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::arrayHasKey + */ + public function testAssertThatArrayHasKey() + { + $this->assertThat(array('foo' => 'bar'), $this->arrayHasKey('foo')); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::classHasAttribute + */ + public function testAssertThatClassHasAttribute() + { + $this->assertThat( + new ClassWithNonPublicAttributes, + $this->classHasAttribute('publicAttribute') + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::classHasStaticAttribute + */ + public function testAssertThatClassHasStaticAttribute() + { + $this->assertThat( + new ClassWithNonPublicAttributes, + $this->classHasStaticAttribute('publicStaticAttribute') + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::objectHasAttribute + */ + public function testAssertThatObjectHasAttribute() + { + $this->assertThat( + new ClassWithNonPublicAttributes, + $this->objectHasAttribute('publicAttribute') + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::equalTo + */ + public function testAssertThatEqualTo() + { + $this->assertThat('foo', $this->equalTo('foo')); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::identicalTo + */ + public function testAssertThatIdenticalTo() + { + $value = new stdClass; + $constraint = $this->identicalTo($value); + + $this->assertThat($value, $constraint); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::isInstanceOf + */ + public function testAssertThatIsInstanceOf() + { + $this->assertThat(new stdClass, $this->isInstanceOf('StdClass')); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::isType + */ + public function testAssertThatIsType() + { + $this->assertThat('string', $this->isType('string')); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::isEmpty + */ + public function testAssertThatIsEmpty() + { + $this->assertThat(array(), $this->isEmpty()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::fileExists + */ + public function testAssertThatFileExists() + { + $this->assertThat(__FILE__, $this->fileExists()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::greaterThan + */ + public function testAssertThatGreaterThan() + { + $this->assertThat(2, $this->greaterThan(1)); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::greaterThanOrEqual + */ + public function testAssertThatGreaterThanOrEqual() + { + $this->assertThat(2, $this->greaterThanOrEqual(1)); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::lessThan + */ + public function testAssertThatLessThan() + { + $this->assertThat(1, $this->lessThan(2)); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::lessThanOrEqual + */ + public function testAssertThatLessThanOrEqual() + { + $this->assertThat(1, $this->lessThanOrEqual(2)); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::matchesRegularExpression + */ + public function testAssertThatMatchesRegularExpression() + { + $this->assertThat('foobar', $this->matchesRegularExpression('/foo/')); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::callback + */ + public function testAssertThatCallback() + { + $this->assertThat( + null, + $this->callback(function ($other) { return true; }) + ); + } + + /** + * @covers PHPUnit_Framework_Assert::assertThat + * @covers PHPUnit_Framework_Assert::countOf + */ + public function testAssertThatCountOf() + { + $this->assertThat(array(1), $this->countOf(1)); + } + + /** + * @covers PHPUnit_Framework_Assert::assertFileEquals + */ + public function testAssertFileEquals() + { + $this->assertFileEquals( + $this->filesDirectory . 'foo.xml', + $this->filesDirectory . 'foo.xml' + ); + + try { + $this->assertFileEquals( + $this->filesDirectory . 'foo.xml', + $this->filesDirectory . 'bar.xml' + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertFileNotEquals + */ + public function testAssertFileNotEquals() + { + $this->assertFileNotEquals( + $this->filesDirectory . 'foo.xml', + $this->filesDirectory . 'bar.xml' + ); + + try { + $this->assertFileNotEquals( + $this->filesDirectory . 'foo.xml', + $this->filesDirectory . 'foo.xml' + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringEqualsFile + */ + public function testAssertStringEqualsFile() + { + $this->assertStringEqualsFile( + $this->filesDirectory . 'foo.xml', + file_get_contents($this->filesDirectory . 'foo.xml') + ); + + try { + $this->assertStringEqualsFile( + $this->filesDirectory . 'foo.xml', + file_get_contents($this->filesDirectory . 'bar.xml') + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringNotEqualsFile + */ + public function testAssertStringNotEqualsFile() + { + $this->assertStringNotEqualsFile( + $this->filesDirectory . 'foo.xml', + file_get_contents($this->filesDirectory . 'bar.xml') + ); + + try { + $this->assertStringNotEqualsFile( + $this->filesDirectory . 'foo.xml', + file_get_contents($this->filesDirectory . 'foo.xml') + ); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringStartsWith + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringStartsWithThrowsException() + { + $this->assertStringStartsWith(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringStartsWith + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringStartsWithThrowsException2() + { + $this->assertStringStartsWith('', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringStartsNotWith + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringStartsNotWithThrowsException() + { + $this->assertStringStartsNotWith(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringStartsNotWith + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringStartsNotWithThrowsException2() + { + $this->assertStringStartsNotWith('', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringEndsWith + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringEndsWithThrowsException() + { + $this->assertStringEndsWith(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringEndsWith + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringEndsWithThrowsException2() + { + $this->assertStringEndsWith('', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringEndsNotWith + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringEndsNotWithThrowsException() + { + $this->assertStringEndsNotWith(null, null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringEndsNotWith + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringEndsNotWithThrowsException2() + { + $this->assertStringEndsNotWith('', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringStartsWith + */ + public function testAssertStringStartsWith() + { + $this->assertStringStartsWith('prefix', 'prefixfoo'); + + try { + $this->assertStringStartsWith('prefix', 'foo'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringStartsNotWith + */ + public function testAssertStringStartsNotWith() + { + $this->assertStringStartsNotWith('prefix', 'foo'); + + try { + $this->assertStringStartsNotWith('prefix', 'prefixfoo'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringEndsWith + */ + public function testAssertStringEndsWith() + { + $this->assertStringEndsWith('suffix', 'foosuffix'); + + try { + $this->assertStringEndsWith('suffix', 'foo'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringEndsNotWith + */ + public function testAssertStringEndsNotWith() + { + $this->assertStringEndsNotWith('suffix', 'foo'); + + try { + $this->assertStringEndsNotWith('suffix', 'foosuffix'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringMatchesFormat + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringMatchesFormatRaisesExceptionForInvalidFirstArgument() + { + $this->assertStringMatchesFormat(null, ''); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringMatchesFormat + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringMatchesFormatRaisesExceptionForInvalidSecondArgument() + { + $this->assertStringMatchesFormat('', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringMatchesFormat + */ + public function testAssertStringMatchesFormat() + { + $this->assertStringMatchesFormat('*%s*', '***'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringMatchesFormat + * @expectedException PHPUnit_Framework_AssertionFailedError + */ + public function testAssertStringMatchesFormatFailure() + { + $this->assertStringMatchesFormat('*%s*', '**'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringNotMatchesFormat + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringNotMatchesFormatRaisesExceptionForInvalidFirstArgument() + { + $this->assertStringNotMatchesFormat(null, ''); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringNotMatchesFormat + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringNotMatchesFormatRaisesExceptionForInvalidSecondArgument() + { + $this->assertStringNotMatchesFormat('', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringNotMatchesFormat + */ + public function testAssertStringNotMatchesFormat() + { + $this->assertStringNotMatchesFormat('*%s*', '**'); + + try { + $this->assertStringMatchesFormat('*%s*', '**'); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertEmpty + */ + public function testAssertEmpty() + { + $this->assertEmpty(array()); + + try { + $this->assertEmpty(array('foo')); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotEmpty + */ + public function testAssertNotEmpty() + { + $this->assertNotEmpty(array('foo')); + + try { + $this->assertNotEmpty(array()); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeEmpty + */ + public function testAssertAttributeEmpty() + { + $o = new stdClass; + $o->a = array(); + + $this->assertAttributeEmpty('a', $o); + + try { + $o->a = array('b'); + $this->assertAttributeEmpty('a', $o); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotEmpty + */ + public function testAssertAttributeNotEmpty() + { + $o = new stdClass; + $o->a = array('b'); + + $this->assertAttributeNotEmpty('a', $o); + + try { + $o->a = array(); + $this->assertAttributeNotEmpty('a', $o); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::markTestIncomplete + */ + public function testMarkTestIncomplete() + { + try { + $this->markTestIncomplete('incomplete'); + } catch (PHPUnit_Framework_IncompleteTestError $e) { + $this->assertEquals('incomplete', $e->getMessage()); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::markTestSkipped + */ + public function testMarkTestSkipped() + { + try { + $this->markTestSkipped('skipped'); + } catch (PHPUnit_Framework_SkippedTestError $e) { + $this->assertEquals('skipped', $e->getMessage()); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertCount + */ + public function testAssertCount() + { + $this->assertCount(2, array(1, 2)); + + try { + $this->assertCount(2, array(1, 2, 3)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertCount + */ + public function testAssertCountTraversable() + { + $this->assertCount(2, new ArrayIterator(array(1, 2))); + + try { + $this->assertCount(2, new ArrayIterator(array(1, 2, 3))); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertCount + */ + public function testAssertCountThrowsExceptionIfExpectedCountIsNoInteger() + { + try { + $this->assertCount('a', array()); + } catch (PHPUnit_Framework_Exception $e) { + $this->assertEquals('Argument #1 (No Value) of PHPUnit_Framework_Assert::assertCount() must be a integer', $e->getMessage()); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertCount + */ + public function testAssertCountThrowsExceptionIfElementIsNotCountable() + { + try { + $this->assertCount(2, ''); + } catch (PHPUnit_Framework_Exception $e) { + $this->assertEquals('Argument #2 (No Value) of PHPUnit_Framework_Assert::assertCount() must be a countable or traversable', $e->getMessage()); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeCount + */ + public function testAssertAttributeCount() + { + $o = new stdClass; + $o->a = array(); + + $this->assertAttributeCount(0, 'a', $o); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotCount + */ + public function testAssertNotCount() + { + $this->assertNotCount(2, array(1, 2, 3)); + + try { + $this->assertNotCount(2, array(1, 2)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotCount + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotCountThrowsExceptionIfExpectedCountIsNoInteger() + { + $this->assertNotCount('a', array()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotCount + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotCountThrowsExceptionIfElementIsNotCountable() + { + $this->assertNotCount(2, ''); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotCount + */ + public function testAssertAttributeNotCount() + { + $o = new stdClass; + $o->a = array(); + + $this->assertAttributeNotCount(1, 'a', $o); + } + + /** + * @covers PHPUnit_Framework_Assert::assertSameSize + */ + public function testAssertSameSize() + { + $this->assertSameSize(array(1, 2), array(3, 4)); + + try { + $this->assertSameSize(array(1, 2), array(1, 2, 3)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertSameSize + */ + public function testAssertSameSizeThrowsExceptionIfExpectedIsNotCountable() + { + try { + $this->assertSameSize('a', array()); + } catch (PHPUnit_Framework_Exception $e) { + $this->assertEquals('Argument #1 (No Value) of PHPUnit_Framework_Assert::assertSameSize() must be a countable or traversable', $e->getMessage()); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertSameSize + */ + public function testAssertSameSizeThrowsExceptionIfActualIsNotCountable() + { + try { + $this->assertSameSize(array(), ''); + } catch (PHPUnit_Framework_Exception $e) { + $this->assertEquals('Argument #2 (No Value) of PHPUnit_Framework_Assert::assertSameSize() must be a countable or traversable', $e->getMessage()); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotSameSize + */ + public function testAssertNotSameSize() + { + $this->assertNotSameSize(array(1, 2), array(1, 2, 3)); + + try { + $this->assertNotSameSize(array(1, 2), array(3, 4)); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotSameSize + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotSameSizeThrowsExceptionIfExpectedIsNotCountable() + { + $this->assertNotSameSize('a', array()); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotSameSize + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotSameSizeThrowsExceptionIfActualIsNotCountable() + { + $this->assertNotSameSize(array(), ''); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJson + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertJsonRaisesExceptionForInvalidArgument() + { + $this->assertJson(null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJson + */ + public function testAssertJson() + { + $this->assertJson('{}'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJsonStringEqualsJsonString + */ + public function testAssertJsonStringEqualsJsonString() + { + $expected = '{"Mascott" : "Tux"}'; + $actual = '{"Mascott" : "Tux"}'; + $message = 'Given Json strings do not match'; + + $this->assertJsonStringEqualsJsonString($expected, $actual, $message); + } + + /** + * @dataProvider validInvalidJsonDataprovider + * @covers PHPUnit_Framework_Assert::assertJsonStringEqualsJsonString + */ + public function testAssertJsonStringEqualsJsonStringErrorRaised($expected, $actual) + { + try { + $this->assertJsonStringEqualsJsonString($expected, $actual); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + $this->fail('Expected exception not found'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonString + */ + public function testAssertJsonStringNotEqualsJsonString() + { + $expected = '{"Mascott" : "Beastie"}'; + $actual = '{"Mascott" : "Tux"}'; + $message = 'Given Json strings do match'; + + $this->assertJsonStringNotEqualsJsonString($expected, $actual, $message); + } + + /** + * @dataProvider validInvalidJsonDataprovider + * @covers PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonString + */ + public function testAssertJsonStringNotEqualsJsonStringErrorRaised($expected, $actual) + { + try { + $this->assertJsonStringNotEqualsJsonString($expected, $actual); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + $this->fail('Expected exception not found'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJsonStringEqualsJsonFile + */ + public function testAssertJsonStringEqualsJsonFile() + { + $file = __DIR__ . '/../_files/JsonData/simpleObject.json'; + $actual = json_encode(array('Mascott' => 'Tux')); + $message = ''; + $this->assertJsonStringEqualsJsonFile($file, $actual, $message); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJsonStringEqualsJsonFile + */ + public function testAssertJsonStringEqualsJsonFileExpectingExpectationFailedException() + { + $file = __DIR__ . '/../_files/JsonData/simpleObject.json'; + $actual = json_encode(array('Mascott' => 'Beastie')); + $message = ''; + try { + $this->assertJsonStringEqualsJsonFile($file, $actual, $message); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + 'Failed asserting that \'{"Mascott":"Beastie"}\' matches JSON string "{"Mascott":"Tux"}".', + $e->getMessage() + ); + + return; + } + + $this->fail('Expected Exception not thrown.'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJsonStringEqualsJsonFile + */ + public function testAssertJsonStringEqualsJsonFileExpectingException() + { + $file = __DIR__ . '/../_files/JsonData/simpleObject.json'; + try { + $this->assertJsonStringEqualsJsonFile($file, null); + } catch (PHPUnit_Framework_Exception $e) { + return; + } + $this->fail('Expected Exception not thrown.'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonFile + */ + public function testAssertJsonStringNotEqualsJsonFile() + { + $file = __DIR__ . '/../_files/JsonData/simpleObject.json'; + $actual = json_encode(array('Mascott' => 'Beastie')); + $message = ''; + $this->assertJsonStringNotEqualsJsonFile($file, $actual, $message); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonFile + */ + public function testAssertJsonStringNotEqualsJsonFileExpectingException() + { + $file = __DIR__ . '/../_files/JsonData/simpleObject.json'; + try { + $this->assertJsonStringNotEqualsJsonFile($file, null); + } catch (PHPUnit_Framework_Exception $e) { + return; + } + $this->fail('Expected exception not found.'); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJsonFileNotEqualsJsonFile + */ + public function testAssertJsonFileNotEqualsJsonFile() + { + $fileExpected = __DIR__ . '/../_files/JsonData/simpleObject.json'; + $fileActual = __DIR__ . '/../_files/JsonData/arrayObject.json'; + $message = ''; + $this->assertJsonFileNotEqualsJsonFile($fileExpected, $fileActual, $message); + } + + /** + * @covers PHPUnit_Framework_Assert::assertJsonFileEqualsJsonFile + */ + public function testAssertJsonFileEqualsJsonFile() + { + $file = __DIR__ . '/../_files/JsonData/simpleObject.json'; + $message = ''; + $this->assertJsonFileEqualsJsonFile($file, $file, $message); + } + + /** + * @covers PHPUnit_Framework_Assert::assertInstanceOf + */ + public function testAssertInstanceOf() + { + $this->assertInstanceOf('stdClass', new stdClass); + + try { + $this->assertInstanceOf('Exception', new stdClass); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertInstanceOf + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertInstanceOfThrowsExceptionForInvalidArgument() + { + $this->assertInstanceOf(null, new stdClass); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeInstanceOf + */ + public function testAssertAttributeInstanceOf() + { + $o = new stdClass; + $o->a = new stdClass; + + $this->assertAttributeInstanceOf('stdClass', 'a', $o); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotInstanceOf + */ + public function testAssertNotInstanceOf() + { + $this->assertNotInstanceOf('Exception', new stdClass); + + try { + $this->assertNotInstanceOf('stdClass', new stdClass); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotInstanceOf + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotInstanceOfThrowsExceptionForInvalidArgument() + { + $this->assertNotInstanceOf(null, new stdClass); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotInstanceOf + */ + public function testAssertAttributeNotInstanceOf() + { + $o = new stdClass; + $o->a = new stdClass; + + $this->assertAttributeNotInstanceOf('Exception', 'a', $o); + } + + /** + * @covers PHPUnit_Framework_Assert::assertInternalType + */ + public function testAssertInternalType() + { + $this->assertInternalType('integer', 1); + + try { + $this->assertInternalType('string', 1); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertInternalType + */ + public function testAssertInternalTypeDouble() + { + $this->assertInternalType('double', 1.0); + + try { + $this->assertInternalType('double', 1); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertInternalType + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertInternalTypeThrowsExceptionForInvalidArgument() + { + $this->assertInternalType(null, 1); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeInternalType + */ + public function testAssertAttributeInternalType() + { + $o = new stdClass; + $o->a = 1; + + $this->assertAttributeInternalType('integer', 'a', $o); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotInternalType + */ + public function testAssertNotInternalType() + { + $this->assertNotInternalType('string', 1); + + try { + $this->assertNotInternalType('integer', 1); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertNotInternalType + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertNotInternalTypeThrowsExceptionForInvalidArgument() + { + $this->assertNotInternalType(null, 1); + } + + /** + * @covers PHPUnit_Framework_Assert::assertAttributeNotInternalType + */ + public function testAssertAttributeNotInternalType() + { + $o = new stdClass; + $o->a = 1; + + $this->assertAttributeNotInternalType('string', 'a', $o); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringMatchesFormatFile + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringMatchesFormatFileThrowsExceptionForInvalidArgument() + { + $this->assertStringMatchesFormatFile('not_existing_file', ''); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringMatchesFormatFile + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringMatchesFormatFileThrowsExceptionForInvalidArgument2() + { + $this->assertStringMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringMatchesFormatFile + */ + public function testAssertStringMatchesFormatFile() + { + $this->assertStringMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', "FOO\n"); + + try { + $this->assertStringMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', "BAR\n"); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringNotMatchesFormatFile + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringNotMatchesFormatFileThrowsExceptionForInvalidArgument() + { + $this->assertStringNotMatchesFormatFile('not_existing_file', ''); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringNotMatchesFormatFile + * @expectedException PHPUnit_Framework_Exception + */ + public function testAssertStringNotMatchesFormatFileThrowsExceptionForInvalidArgument2() + { + $this->assertStringNotMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', null); + } + + /** + * @covers PHPUnit_Framework_Assert::assertStringNotMatchesFormatFile + */ + public function testAssertStringNotMatchesFormatFile() + { + $this->assertStringNotMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', "BAR\n"); + + try { + $this->assertStringNotMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', "FOO\n"); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + return; + } + + $this->fail(); + } + + /** + * @return array + */ + public static function validInvalidJsonDataprovider() + { + return array( + 'error syntax in expected JSON' => array('{"Mascott"::}', '{"Mascott" : "Tux"}'), + 'error UTF-8 in actual JSON' => array('{"Mascott" : "Tux"}', '{"Mascott" : :}'), + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/BaseTestListenerTest.php b/vendor/phpunit/phpunit/tests/Framework/BaseTestListenerTest.php new file mode 100644 index 000000000..0d426cf05 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/BaseTestListenerTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 4.0.0 + */ +class Framework_BaseTestListenerTest extends PHPUnit_Framework_TestCase +{ + /** + * @var PHPUnit_Framework_TestResult + */ + private $result; + + /** + * @covers PHPUnit_Framework_TestResult + */ + public function testEndEventsAreCounted() + { + $this->result = new PHPUnit_Framework_TestResult; + $listener = new BaseTestListenerSample(); + $this->result->addListener($listener); + $test = new Success; + $test->run($this->result); + + $this->assertEquals(1, $listener->endCount); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/CountTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/CountTest.php new file mode 100644 index 000000000..79e99e888 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/CountTest.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 3.7.30 + * @covers PHPUnit_Framework_Constraint_Count + */ +class CountTest extends PHPUnit_Framework_TestCase +{ + public function testCount() + { + $countConstraint = new PHPUnit_Framework_Constraint_Count(3); + $this->assertTrue($countConstraint->evaluate(array(1, 2, 3), '', true)); + + $countConstraint = new PHPUnit_Framework_Constraint_Count(0); + $this->assertTrue($countConstraint->evaluate(array(), '', true)); + + $countConstraint = new PHPUnit_Framework_Constraint_Count(2); + $it = new TestIterator(array(1, 2)); + $this->assertTrue($countConstraint->evaluate($it, '', true)); + } + + public function testCountDoesNotChangeIteratorKey() + { + $countConstraint = new PHPUnit_Framework_Constraint_Count(2); + + // test with 1st implementation of Iterator + $it = new TestIterator(array(1, 2)); + + $countConstraint->evaluate($it, '', true); + $this->assertEquals(1, $it->current()); + + $it->next(); + $countConstraint->evaluate($it, '', true); + $this->assertEquals(2, $it->current()); + + $it->next(); + $countConstraint->evaluate($it, '', true); + $this->assertFalse($it->valid()); + + // test with 2nd implementation of Iterator + $it = new TestIterator2(array(1, 2)); + + $countConstraint = new PHPUnit_Framework_Constraint_Count(2); + $countConstraint->evaluate($it, '', true); + $this->assertEquals(1, $it->current()); + + $it->next(); + $countConstraint->evaluate($it, '', true); + $this->assertEquals(2, $it->current()); + + $it->next(); + $countConstraint->evaluate($it, '', true); + $this->assertFalse($it->valid()); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageRegExpTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageRegExpTest.php new file mode 100644 index 000000000..1c02a12ba --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageRegExpTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 4.3.0 + * @covers PHPUnit_Framework_Constraint_ExceptionMessageRegExp + */ +class ExceptionMessageRegExpTest extends PHPUnit_Framework_TestCase +{ + /** + * @expectedException \Exception + * @expectedExceptionMessageRegExp /^A polymorphic \w+ message/ + */ + public function testRegexMessage() + { + throw new Exception('A polymorphic exception message'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessageRegExp /^a poly[a-z]+ [a-zA-Z0-9_]+ me(s){2}age$/i + */ + public function testRegexMessageExtreme() + { + throw new Exception('A polymorphic exception message'); + } + + /** + * @runInSeparateProcess + * @requires extension xdebug + * @expectedException \Exception + * @expectedExceptionMessageRegExp #Screaming preg_match# + */ + public function testMessageXdebugScreamCompatibility() + { + ini_set('xdebug.scream', '1'); + throw new Exception('Screaming preg_match'); + } + + /** + * @coversNothing + * @expectedException \Exception variadic + * @expectedExceptionMessageRegExp /^A variadic \w+ message/ + */ + public function testSimultaneousLiteralAndRegExpExceptionMessage() + { + throw new Exception('A variadic exception message'); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageTest.php new file mode 100644 index 000000000..33f4319bd --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageTest.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 4.0.20 + * @covers PHPUnit_Framework_Constraint_ExceptionMessage + */ +class ExceptionMessageTest extends PHPUnit_Framework_TestCase +{ + /** + * @expectedException \Exception + * @expectedExceptionMessage A literal exception message + */ + public function testLiteralMessage() + { + throw new Exception('A literal exception message'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage A partial + */ + public function testPatialMessageBegin() + { + throw new Exception('A partial exception message'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage partial exception + */ + public function testPatialMessageMiddle() + { + throw new Exception('A partial exception message'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage exception message + */ + public function testPatialMessageEnd() + { + throw new Exception('A partial exception message'); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatches/ErrorMessageProviderTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatches/ErrorMessageProviderTest.php new file mode 100644 index 000000000..852902629 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatches/ErrorMessageProviderTest.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since File available since Release 3.7.0 + */ +class Framework_Constraint_JsonMatches_ErrorMessageProviderTest extends PHPUnit_Framework_TestCase +{ + /** + * @dataProvider translateTypeToPrefixDataprovider + * @covers PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::translateTypeToPrefix + */ + public function testTranslateTypeToPrefix($expected, $type) + { + $this->assertEquals( + $expected, + PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::translateTypeToPrefix($type) + ); + } + + /** + * @dataProvider determineJsonErrorDataprovider + * @covers PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::determineJsonError + */ + public function testDetermineJsonError($expected, $error, $prefix) + { + $this->assertEquals( + $expected, + PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::determineJsonError( + $error, + $prefix + ) + ); + } + + public static function determineJsonErrorDataprovider() + { + return array( + 'JSON_ERROR_NONE' => array( + null, 'json_error_none', '' + ), + 'JSON_ERROR_DEPTH' => array( + 'Maximum stack depth exceeded', JSON_ERROR_DEPTH, '' + ), + 'prefixed JSON_ERROR_DEPTH' => array( + 'TUX: Maximum stack depth exceeded', JSON_ERROR_DEPTH, 'TUX: ' + ), + 'JSON_ERROR_STATE_MISMatch' => array( + 'Underflow or the modes mismatch', JSON_ERROR_STATE_MISMATCH, '' + ), + 'JSON_ERROR_CTRL_CHAR' => array( + 'Unexpected control character found', JSON_ERROR_CTRL_CHAR, '' + ), + 'JSON_ERROR_SYNTAX' => array( + 'Syntax error, malformed JSON', JSON_ERROR_SYNTAX, '' + ), + 'JSON_ERROR_UTF8`' => array( + 'Malformed UTF-8 characters, possibly incorrectly encoded', + JSON_ERROR_UTF8, + '' + ), + 'Invalid error indicator' => array( + 'Unknown error', 55, '' + ), + ); + } + + public static function translateTypeToPrefixDataprovider() + { + return array( + 'expected' => array('Expected value JSON decode error - ', 'expected'), + 'actual' => array('Actual value JSON decode error - ', 'actual'), + 'default' => array('', ''), + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatchesTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatchesTest.php new file mode 100644 index 000000000..2b7221c4c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatchesTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since File available since Release 3.7.0 + */ +class Framework_Constraint_JsonMatchesTest extends PHPUnit_Framework_TestCase +{ + /** + * @dataProvider evaluateDataprovider + * @covers PHPUnit_Framework_Constraint_JsonMatches::evaluate + * @covers PHPUnit_Framework_Constraint_JsonMatches::matches + * @covers PHPUnit_Framework_Constraint_JsonMatches::__construct + */ + public function testEvaluate($expected, $jsonOther, $jsonValue) + { + $constraint = new PHPUnit_Framework_Constraint_JsonMatches($jsonValue); + $this->assertEquals($expected, $constraint->evaluate($jsonOther, '', true)); + } + + /** + * @covers PHPUnit_Framework_Constraint_JsonMatches::toString + */ + public function testToString() + { + $jsonValue = json_encode(array('Mascott' => 'Tux')); + $constraint = new PHPUnit_Framework_Constraint_JsonMatches($jsonValue); + + $this->assertEquals('matches JSON string "' . $jsonValue . '"', $constraint->toString()); + } + + public static function evaluateDataprovider() + { + return array( + 'valid JSON' => array(true, json_encode(array('Mascott' => 'Tux')), json_encode(array('Mascott' => 'Tux'))), + 'error syntax' => array(false, '{"Mascott"::}', json_encode(array('Mascott' => 'Tux'))), + 'error UTF-8' => array(false, json_encode('\xB1\x31'), json_encode(array('Mascott' => 'Tux'))), + 'invalid JSON in class instantiation' => array(false, json_encode(array('Mascott' => 'Tux')), '{"Mascott"::}'), + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/ConstraintTest.php b/vendor/phpunit/phpunit/tests/Framework/ConstraintTest.php new file mode 100644 index 000000000..716566082 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/ConstraintTest.php @@ -0,0 +1,3489 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 3.0.0 + */ +class Framework_ConstraintTest extends PHPUnit_Framework_TestCase +{ + /** + * @covers PHPUnit_Framework_Constraint_ArrayHasKey + * @covers PHPUnit_Framework_Assert::arrayHasKey + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintArrayHasKey() + { + $constraint = PHPUnit_Framework_Assert::arrayHasKey(0); + + $this->assertFalse($constraint->evaluate(array(), '', true)); + $this->assertEquals('has the key 0', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(array()); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ArrayHasKey + * @covers PHPUnit_Framework_Assert::arrayHasKey + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintArrayHasKey2() + { + $constraint = PHPUnit_Framework_Assert::arrayHasKey(0); + + try { + $constraint->evaluate(array(), 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ArrayHasKey + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::arrayHasKey + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintArrayNotHasKey() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::arrayHasKey(0) + ); + + $this->assertFalse($constraint->evaluate(array(0 => 1), '', true)); + $this->assertEquals('does not have the key 0', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(array(0 => 1)); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ArrayHasKey + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::arrayHasKey + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintArrayNotHasKey2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::arrayHasKey(0) + ); + + try { + $constraint->evaluate(array(0), 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_FileExists + * @covers PHPUnit_Framework_Assert::fileExists + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintFileExists() + { + $constraint = PHPUnit_Framework_Assert::fileExists(); + + $this->assertFalse($constraint->evaluate('foo', '', true)); + $this->assertEquals('file exists', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('foo'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_FileExists + * @covers PHPUnit_Framework_Assert::fileExists + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintFileExists2() + { + $constraint = PHPUnit_Framework_Assert::fileExists(); + + try { + $constraint->evaluate('foo', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_FileExists + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_Assert::fileExists + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintFileNotExists() + { + $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'ClassWithNonPublicAttributes.php'; + + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::fileExists() + ); + + $this->assertFalse($constraint->evaluate($file, '', true)); + $this->assertEquals('file does not exist', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate($file); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_FileExists + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_Assert::fileExists + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintFileNotExists2() + { + $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'ClassWithNonPublicAttributes.php'; + + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::fileExists() + ); + + try { + $constraint->evaluate($file, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_GreaterThan + * @covers PHPUnit_Framework_Assert::greaterThan + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintGreaterThan() + { + $constraint = PHPUnit_Framework_Assert::greaterThan(1); + + $this->assertFalse($constraint->evaluate(0, '', true)); + $this->assertTrue($constraint->evaluate(2, '', true)); + $this->assertEquals('is greater than 1', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(0); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_GreaterThan + * @covers PHPUnit_Framework_Assert::greaterThan + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintGreaterThan2() + { + $constraint = PHPUnit_Framework_Assert::greaterThan(1); + + try { + $constraint->evaluate(0, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_GreaterThan + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::greaterThan + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotGreaterThan() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::greaterThan(1) + ); + + $this->assertTrue($constraint->evaluate(1, '', true)); + $this->assertEquals('is not greater than 1', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(2); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_GreaterThan + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::greaterThan + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotGreaterThan2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::greaterThan(1) + ); + + try { + $constraint->evaluate(2, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_GreaterThan + * @covers PHPUnit_Framework_Constraint_Or + * @covers PHPUnit_Framework_Assert::greaterThanOrEqual + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintGreaterThanOrEqual() + { + $constraint = PHPUnit_Framework_Assert::greaterThanOrEqual(1); + + $this->assertTrue($constraint->evaluate(1, '', true)); + $this->assertFalse($constraint->evaluate(0, '', true)); + $this->assertEquals('is equal to 1 or is greater than 1', $constraint->toString()); + $this->assertEquals(2, count($constraint)); + + try { + $constraint->evaluate(0); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_GreaterThan + * @covers PHPUnit_Framework_Constraint_Or + * @covers PHPUnit_Framework_Assert::greaterThanOrEqual + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintGreaterThanOrEqual2() + { + $constraint = PHPUnit_Framework_Assert::greaterThanOrEqual(1); + + try { + $constraint->evaluate(0, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_GreaterThan + * @covers PHPUnit_Framework_Constraint_Or + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::greaterThanOrEqual + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotGreaterThanOrEqual() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::greaterThanOrEqual(1) + ); + + $this->assertFalse($constraint->evaluate(1, '', true)); + $this->assertEquals('not( is equal to 1 or is greater than 1 )', $constraint->toString()); + $this->assertEquals(2, count($constraint)); + + try { + $constraint->evaluate(1); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_GreaterThan + * @covers PHPUnit_Framework_Constraint_Or + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::greaterThanOrEqual + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotGreaterThanOrEqual2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::greaterThanOrEqual(1) + ); + + try { + $constraint->evaluate(1, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsAnything + * @covers PHPUnit_Framework_Assert::anything + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsAnything() + { + $constraint = PHPUnit_Framework_Assert::anything(); + + $this->assertTrue($constraint->evaluate(null, '', true)); + $this->assertNull($constraint->evaluate(null)); + $this->assertEquals('is anything', $constraint->toString()); + $this->assertEquals(0, count($constraint)); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsAnything + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::anything + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotIsAnything() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::anything() + ); + + $this->assertFalse($constraint->evaluate(null, '', true)); + $this->assertEquals('is not anything', $constraint->toString()); + $this->assertEquals(0, count($constraint)); + + try { + $constraint->evaluate(null); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Assert::equalTo + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsEqual() + { + $constraint = PHPUnit_Framework_Assert::equalTo(1); + + $this->assertTrue($constraint->evaluate(1, '', true)); + $this->assertFalse($constraint->evaluate(0, '', true)); + $this->assertEquals('is equal to 1', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(0); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + public function isEqualProvider() + { + $a = new stdClass; + $a->foo = 'bar'; + $b = new stdClass; + $ahash = spl_object_hash($a); + $bhash = spl_object_hash($b); + + $c = new stdClass; + $c->foo = 'bar'; + $c->int = 1; + $c->array = array(0, array(1), array(2), 3); + $c->related = new stdClass; + $c->related->foo = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk"; + $c->self = $c; + $c->c = $c; + $d = new stdClass; + $d->foo = 'bar'; + $d->int = 2; + $d->array = array(0, array(4), array(2), 3); + $d->related = new stdClass; + $d->related->foo = "a\np\nc\nd\ne\nf\ng\nh\ni\nw\nk"; + $d->self = $d; + $d->c = $c; + + $storage1 = new SplObjectStorage; + $storage1->attach($a); + $storage1->attach($b); + $storage2 = new SplObjectStorage; + $storage2->attach($b); + $storage1hash = spl_object_hash($storage1); + $storage2hash = spl_object_hash($storage2); + + $dom1 = new DOMDocument; + $dom1->preserveWhiteSpace = false; + $dom1->loadXML(''); + $dom2 = new DOMDocument; + $dom2->preserveWhiteSpace = false; + $dom2->loadXML(''); + + $data = array( + array(1, 0, << 0 ++ 0 => 1 + ) + +EOF + ), + array(array(true), array('true'), << true ++ 0 => 'true' + ) + +EOF + ), + array(array(0, array(1), array(2), 3), array(0, array(4), array(2), 3), << 0 + 1 => Array ( +- 0 => 1 ++ 0 => 4 + ) + 2 => Array (...) + 3 => 3 + ) + +EOF + ), + array($a, array(0), << 'bar' + ) + +EOF + ), + array($c, $d, << 'bar' +- 'int' => 1 ++ 'int' => 2 + 'array' => Array ( + 0 => 0 + 1 => Array ( +- 0 => 1 ++ 0 => 4 + +@@ @@ + 'foo' => 'a +- b ++ p + +@@ @@ + i +- j ++ w + k' + ) + 'self' => stdClass Object (...) + 'c' => stdClass Object (...) + ) + +EOF + ), + array($dom1, $dom2, << +- ++ ++ ++ + +EOF + ), + array( + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')), + new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')), + << Array &0 ( +- 'obj' => stdClass Object &$ahash ( +- 'foo' => 'bar' +- ) ++SplObjectStorage Object &$storage2hash ( ++ '$bhash' => Array &0 ( ++ 'obj' => stdClass Object &$bhash () + 'inf' => null + ) +- '$bhash' => Array &0 + ) + +EOF + ); + } else { + $data[] = array($storage1, $storage2, << Array &0 ( +- 'obj' => stdClass Object &$ahash ( +- 'foo' => 'bar' +- ) ++SplObjectStorage Object &$storage2hash ( ++ '$bhash' => Array &0 ( ++ 'obj' => stdClass Object &$bhash () + 'inf' => null + ) +- '$bhash' => Array &0 + ) + +EOF + ); + } + + return $data; + } + + /** + * @dataProvider isEqualProvider + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Assert::equalTo + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsEqual2($expected, $actual, $message) + { + $constraint = PHPUnit_Framework_Assert::equalTo($expected); + + try { + $constraint->evaluate($actual, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + "custom message\n$message", + $this->trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e)) + ); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::equalTo + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotEqual() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::equalTo(1) + ); + + $this->assertTrue($constraint->evaluate(0, '', true)); + $this->assertFalse($constraint->evaluate(1, '', true)); + $this->assertEquals('is not equal to 1', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(1); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::equalTo + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotEqual2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::equalTo(1) + ); + + try { + $constraint->evaluate(1, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsIdentical + * @covers PHPUnit_Framework_Assert::identicalTo + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsIdentical() + { + $a = new stdClass; + $b = new stdClass; + + $constraint = PHPUnit_Framework_Assert::identicalTo($a); + + $this->assertFalse($constraint->evaluate($b, '', true)); + $this->assertTrue($constraint->evaluate($a, '', true)); + $this->assertEquals('is identical to an object of class "stdClass"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate($b); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsIdentical + * @covers PHPUnit_Framework_Assert::identicalTo + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsIdentical2() + { + $a = new stdClass; + $b = new stdClass; + + $constraint = PHPUnit_Framework_Assert::identicalTo($a); + + try { + $constraint->evaluate($b, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsIdentical + * @covers PHPUnit_Framework_Assert::identicalTo + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsIdentical3() + { + $constraint = PHPUnit_Framework_Assert::identicalTo('a'); + + try { + $constraint->evaluate('b', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsIdentical + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::identicalTo + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotIdentical() + { + $a = new stdClass; + $b = new stdClass; + + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::identicalTo($a) + ); + + $this->assertTrue($constraint->evaluate($b, '', true)); + $this->assertFalse($constraint->evaluate($a, '', true)); + $this->assertEquals('is not identical to an object of class "stdClass"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate($a); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e)) + ); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsIdentical + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::identicalTo + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotIdentical2() + { + $a = new stdClass; + + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::identicalTo($a) + ); + + try { + $constraint->evaluate($a, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsIdentical + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::identicalTo + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotIdentical3() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::identicalTo('a') + ); + + try { + $constraint->evaluate('a', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e)) + ); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsInstanceOf + * @covers PHPUnit_Framework_Assert::isInstanceOf + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsInstanceOf() + { + $constraint = PHPUnit_Framework_Assert::isInstanceOf('Exception'); + + $this->assertFalse($constraint->evaluate(new stdClass, '', true)); + $this->assertTrue($constraint->evaluate(new Exception, '', true)); + $this->assertEquals('is instance of class "Exception"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + $interfaceConstraint = PHPUnit_Framework_Assert::isInstanceOf('Countable'); + $this->assertFalse($interfaceConstraint->evaluate(new stdClass, '', true)); + $this->assertTrue($interfaceConstraint->evaluate(new ArrayObject, '', true)); + $this->assertEquals('is instance of interface "Countable"', $interfaceConstraint->toString()); + + try { + $constraint->evaluate(new stdClass); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsInstanceOf + * @covers PHPUnit_Framework_Assert::isInstanceOf + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsInstanceOf2() + { + $constraint = PHPUnit_Framework_Assert::isInstanceOf('Exception'); + + try { + $constraint->evaluate(new stdClass, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsInstanceOf + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::isInstanceOf + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotInstanceOf() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::isInstanceOf('stdClass') + ); + + $this->assertFalse($constraint->evaluate(new stdClass, '', true)); + $this->assertTrue($constraint->evaluate(new Exception, '', true)); + $this->assertEquals('is not instance of class "stdClass"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(new stdClass); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsInstanceOf + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::isInstanceOf + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotInstanceOf2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::isInstanceOf('stdClass') + ); + + try { + $constraint->evaluate(new stdClass, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsType + * @covers PHPUnit_Framework_Assert::isType + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsType() + { + $constraint = PHPUnit_Framework_Assert::isType('string'); + + $this->assertFalse($constraint->evaluate(0, '', true)); + $this->assertTrue($constraint->evaluate('', '', true)); + $this->assertEquals('is of type "string"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(new stdClass); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertStringMatchesFormat(<<trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e)) + ); + + return; + } + + $this->fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsType + * @covers PHPUnit_Framework_Assert::isType + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsType2() + { + $constraint = PHPUnit_Framework_Assert::isType('string'); + + try { + $constraint->evaluate(new stdClass, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertStringMatchesFormat(<<trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e)) + ); + + return; + } + + $this->fail(); + } + + public function resources() + { + $fh = fopen(__FILE__, 'r'); + fclose($fh); + + return array( + 'open resource' => array(fopen(__FILE__, 'r')), + 'closed resource' => array($fh), + ); + } + + /** + * @dataProvider resources + * @covers PHPUnit_Framework_Constraint_IsType + * @covers PHPUnit_Framework_Assert::isType + */ + public function testConstraintIsResourceTypeEvaluatesCorrectlyWithResources($resource) + { + $constraint = PHPUnit_Framework_Assert::isType('resource'); + + $this->assertTrue($constraint->evaluate($resource, '', true)); + + @fclose($resource); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsType + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::isType + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotType() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::isType('string') + ); + + $this->assertTrue($constraint->evaluate(0, '', true)); + $this->assertFalse($constraint->evaluate('', '', true)); + $this->assertEquals('is not of type "string"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(''); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsType + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::isType + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotType2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::isType('string') + ); + + try { + $constraint->evaluate('', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsNull + * @covers PHPUnit_Framework_Assert::isNull + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNull() + { + $constraint = PHPUnit_Framework_Assert::isNull(); + + $this->assertFalse($constraint->evaluate(0, '', true)); + $this->assertTrue($constraint->evaluate(null, '', true)); + $this->assertEquals('is null', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(0); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsNull + * @covers PHPUnit_Framework_Assert::isNull + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNull2() + { + $constraint = PHPUnit_Framework_Assert::isNull(); + + try { + $constraint->evaluate(0, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsNull + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::isNull + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotNull() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::isNull() + ); + + $this->assertFalse($constraint->evaluate(null, '', true)); + $this->assertTrue($constraint->evaluate(0, '', true)); + $this->assertEquals('is not null', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(null); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsNull + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::isNull + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsNotNull2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::isNull() + ); + + try { + $constraint->evaluate(null, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_LessThan + * @covers PHPUnit_Framework_Assert::lessThan + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintLessThan() + { + $constraint = PHPUnit_Framework_Assert::lessThan(1); + + $this->assertTrue($constraint->evaluate(0, '', true)); + $this->assertFalse($constraint->evaluate(1, '', true)); + $this->assertEquals('is less than 1', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(1); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_LessThan + * @covers PHPUnit_Framework_Assert::lessThan + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintLessThan2() + { + $constraint = PHPUnit_Framework_Assert::lessThan(1); + + try { + $constraint->evaluate(1, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_LessThan + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::lessThan + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotLessThan() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::lessThan(1) + ); + + $this->assertTrue($constraint->evaluate(1, '', true)); + $this->assertFalse($constraint->evaluate(0, '', true)); + $this->assertEquals('is not less than 1', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(0); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_LessThan + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::lessThan + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotLessThan2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::lessThan(1) + ); + + try { + $constraint->evaluate(0, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_LessThan + * @covers PHPUnit_Framework_Constraint_Or + * @covers PHPUnit_Framework_Assert::lessThanOrEqual + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintLessThanOrEqual() + { + $constraint = PHPUnit_Framework_Assert::lessThanOrEqual(1); + + $this->assertTrue($constraint->evaluate(1, '', true)); + $this->assertFalse($constraint->evaluate(2, '', true)); + $this->assertEquals('is equal to 1 or is less than 1', $constraint->toString()); + $this->assertEquals(2, count($constraint)); + + try { + $constraint->evaluate(2); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_Callback + */ + public function testConstraintCallback() + { + $closureReflect = function ($parameter) { + return $parameter; + }; + + $closureWithoutParameter = function () { + return true; + }; + + $constraint = PHPUnit_Framework_Assert::callback($closureWithoutParameter); + $this->assertTrue($constraint->evaluate('', '', true)); + + $constraint = PHPUnit_Framework_Assert::callback($closureReflect); + $this->assertTrue($constraint->evaluate(true, '', true)); + $this->assertFalse($constraint->evaluate(false, '', true)); + + $callback = array($this, 'callbackReturningTrue'); + $constraint = PHPUnit_Framework_Assert::callback($callback); + $this->assertTrue($constraint->evaluate(false, '', true)); + + $callback = array('Framework_ConstraintTest', 'staticCallbackReturningTrue'); + $constraint = PHPUnit_Framework_Assert::callback($callback); + $this->assertTrue($constraint->evaluate(null, '', true)); + + $this->assertEquals('is accepted by specified callback', $constraint->toString()); + } + + /** + * @covers PHPUnit_Framework_Constraint_Callback + * @expectedException PHPUnit_Framework_ExpectationFailedException + * @expectedExceptionMessage Failed asserting that 'This fails' is accepted by specified callback. + */ + public function testConstraintCallbackFailure() + { + $constraint = PHPUnit_Framework_Assert::callback(function () { + return false; + }); + $constraint->evaluate('This fails'); + } + + public function callbackReturningTrue() + { + return true; + } + + public static function staticCallbackReturningTrue() + { + return true; + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_LessThan + * @covers PHPUnit_Framework_Constraint_Or + * @covers PHPUnit_Framework_Assert::lessThanOrEqual + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintLessThanOrEqual2() + { + $constraint = PHPUnit_Framework_Assert::lessThanOrEqual(1); + + try { + $constraint->evaluate(2, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_LessThan + * @covers PHPUnit_Framework_Constraint_Or + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::lessThanOrEqual + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotLessThanOrEqual() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::lessThanOrEqual(1) + ); + + $this->assertTrue($constraint->evaluate(2, '', true)); + $this->assertFalse($constraint->evaluate(1, '', true)); + $this->assertEquals('not( is equal to 1 or is less than 1 )', $constraint->toString()); + $this->assertEquals(2, count($constraint)); + + try { + $constraint->evaluate(1); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEqual + * @covers PHPUnit_Framework_Constraint_LessThan + * @covers PHPUnit_Framework_Constraint_Or + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::lessThanOrEqual + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotLessThanOrEqual2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::lessThanOrEqual(1) + ); + + try { + $constraint->evaluate(1, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ClassHasAttribute + * @covers PHPUnit_Framework_Assert::classHasAttribute + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintClassHasAttribute() + { + $constraint = PHPUnit_Framework_Assert::classHasAttribute('privateAttribute'); + + $this->assertTrue($constraint->evaluate('ClassWithNonPublicAttributes', '', true)); + $this->assertFalse($constraint->evaluate('stdClass', '', true)); + $this->assertEquals('has attribute "privateAttribute"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('stdClass'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ClassHasAttribute + * @covers PHPUnit_Framework_Assert::classHasAttribute + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintClassHasAttribute2() + { + $constraint = PHPUnit_Framework_Assert::classHasAttribute('privateAttribute'); + + try { + $constraint->evaluate('stdClass', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ClassHasAttribute + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::classHasAttribute + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintClassNotHasAttribute() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::classHasAttribute('privateAttribute') + ); + + $this->assertTrue($constraint->evaluate('stdClass', '', true)); + $this->assertFalse($constraint->evaluate('ClassWithNonPublicAttributes', '', true)); + $this->assertEquals('does not have attribute "privateAttribute"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ClassHasAttribute + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::classHasAttribute + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintClassNotHasAttribute2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::classHasAttribute('privateAttribute') + ); + + try { + $constraint->evaluate('ClassWithNonPublicAttributes', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ClassHasStaticAttribute + * @covers PHPUnit_Framework_Assert::classHasStaticAttribute + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintClassHasStaticAttribute() + { + $constraint = PHPUnit_Framework_Assert::classHasStaticAttribute('privateStaticAttribute'); + + $this->assertTrue($constraint->evaluate('ClassWithNonPublicAttributes', '', true)); + $this->assertFalse($constraint->evaluate('stdClass', '', true)); + $this->assertEquals('has static attribute "privateStaticAttribute"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('stdClass'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ClassHasStaticAttribute + * @covers PHPUnit_Framework_Assert::classHasStaticAttribute + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintClassHasStaticAttribute2() + { + $constraint = PHPUnit_Framework_Assert::classHasStaticAttribute('foo'); + + try { + $constraint->evaluate('stdClass', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ClassHasStaticAttribute + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::classHasStaticAttribute + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintClassNotHasStaticAttribute() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::classHasStaticAttribute('privateStaticAttribute') + ); + + $this->assertTrue($constraint->evaluate('stdClass', '', true)); + $this->assertFalse($constraint->evaluate('ClassWithNonPublicAttributes', '', true)); + $this->assertEquals('does not have static attribute "privateStaticAttribute"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('ClassWithNonPublicAttributes'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ClassHasStaticAttribute + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::classHasStaticAttribute + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintClassNotHasStaticAttribute2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::classHasStaticAttribute('privateStaticAttribute') + ); + + try { + $constraint->evaluate('ClassWithNonPublicAttributes', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ObjectHasAttribute + * @covers PHPUnit_Framework_Assert::objectHasAttribute + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintObjectHasAttribute() + { + $constraint = PHPUnit_Framework_Assert::objectHasAttribute('privateAttribute'); + + $this->assertTrue($constraint->evaluate(new ClassWithNonPublicAttributes, '', true)); + $this->assertFalse($constraint->evaluate(new stdClass, '', true)); + $this->assertEquals('has attribute "privateAttribute"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(new stdClass); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ObjectHasAttribute + * @covers PHPUnit_Framework_Assert::objectHasAttribute + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintObjectHasAttribute2() + { + $constraint = PHPUnit_Framework_Assert::objectHasAttribute('privateAttribute'); + + try { + $constraint->evaluate(new stdClass, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ObjectHasAttribute + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::objectHasAttribute + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintObjectNotHasAttribute() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::objectHasAttribute('privateAttribute') + ); + + $this->assertTrue($constraint->evaluate(new stdClass, '', true)); + $this->assertFalse($constraint->evaluate(new ClassWithNonPublicAttributes, '', true)); + $this->assertEquals('does not have attribute "privateAttribute"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(new ClassWithNonPublicAttributes); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_ObjectHasAttribute + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::objectHasAttribute + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintObjectNotHasAttribute2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::objectHasAttribute('privateAttribute') + ); + + try { + $constraint->evaluate(new ClassWithNonPublicAttributes, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_PCREMatch + * @covers PHPUnit_Framework_Assert::matchesRegularExpression + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintPCREMatch() + { + $constraint = PHPUnit_Framework_Assert::matchesRegularExpression('/foo/'); + + $this->assertFalse($constraint->evaluate('barbazbar', '', true)); + $this->assertTrue($constraint->evaluate('barfoobar', '', true)); + $this->assertEquals('matches PCRE pattern "/foo/"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('barbazbar'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_PCREMatch + * @covers PHPUnit_Framework_Assert::matchesRegularExpression + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintPCREMatch2() + { + $constraint = PHPUnit_Framework_Assert::matchesRegularExpression('/foo/'); + + try { + $constraint->evaluate('barbazbar', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_PCREMatch + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::matchesRegularExpression + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintPCRENotMatch() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::matchesRegularExpression('/foo/') + ); + + $this->assertTrue($constraint->evaluate('barbazbar', '', true)); + $this->assertFalse($constraint->evaluate('barfoobar', '', true)); + $this->assertEquals('does not match PCRE pattern "/foo/"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('barfoobar'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_PCREMatch + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::matchesRegularExpression + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintPCRENotMatch2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::matchesRegularExpression('/foo/') + ); + + try { + $constraint->evaluate('barfoobar', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals(<<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringMatches + * @covers PHPUnit_Framework_Assert::matches + * @covers PHPUnit_Framework_Constraint::count + */ + public function testConstraintStringMatches() + { + $constraint = PHPUnit_Framework_Assert::matches('*%c*'); + $this->assertFalse($constraint->evaluate('**', '', true)); + $this->assertTrue($constraint->evaluate('***', '', true)); + $this->assertEquals('matches PCRE pattern "/^\*.\*$/s"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringMatches + * @covers PHPUnit_Framework_Assert::matches + * @covers PHPUnit_Framework_Constraint::count + */ + public function testConstraintStringMatches2() + { + $constraint = PHPUnit_Framework_Assert::matches('*%s*'); + $this->assertFalse($constraint->evaluate('**', '', true)); + $this->assertTrue($constraint->evaluate('***', '', true)); + $this->assertEquals('matches PCRE pattern "/^\*[^\r\n]+\*$/s"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringMatches + * @covers PHPUnit_Framework_Assert::matches + * @covers PHPUnit_Framework_Constraint::count + */ + public function testConstraintStringMatches3() + { + $constraint = PHPUnit_Framework_Assert::matches('*%i*'); + $this->assertFalse($constraint->evaluate('**', '', true)); + $this->assertTrue($constraint->evaluate('*0*', '', true)); + $this->assertEquals('matches PCRE pattern "/^\*[+-]?\d+\*$/s"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringMatches + * @covers PHPUnit_Framework_Assert::matches + * @covers PHPUnit_Framework_Constraint::count + */ + public function testConstraintStringMatches4() + { + $constraint = PHPUnit_Framework_Assert::matches('*%d*'); + $this->assertFalse($constraint->evaluate('**', '', true)); + $this->assertTrue($constraint->evaluate('*0*', '', true)); + $this->assertEquals('matches PCRE pattern "/^\*\d+\*$/s"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringMatches + * @covers PHPUnit_Framework_Assert::matches + * @covers PHPUnit_Framework_Constraint::count + */ + public function testConstraintStringMatches5() + { + $constraint = PHPUnit_Framework_Assert::matches('*%x*'); + $this->assertFalse($constraint->evaluate('**', '', true)); + $this->assertTrue($constraint->evaluate('*0f0f0f*', '', true)); + $this->assertEquals('matches PCRE pattern "/^\*[0-9a-fA-F]+\*$/s"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringMatches + * @covers PHPUnit_Framework_Assert::matches + * @covers PHPUnit_Framework_Constraint::count + */ + public function testConstraintStringMatches6() + { + $constraint = PHPUnit_Framework_Assert::matches('*%f*'); + $this->assertFalse($constraint->evaluate('**', '', true)); + $this->assertTrue($constraint->evaluate('*1.0*', '', true)); + $this->assertEquals('matches PCRE pattern "/^\*[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?\*$/s"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringStartsWith + * @covers PHPUnit_Framework_Assert::stringStartsWith + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringStartsWith() + { + $constraint = PHPUnit_Framework_Assert::stringStartsWith('prefix'); + + $this->assertFalse($constraint->evaluate('foo', '', true)); + $this->assertTrue($constraint->evaluate('prefixfoo', '', true)); + $this->assertEquals('starts with "prefix"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('foo'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringStartsWith + * @covers PHPUnit_Framework_Assert::stringStartsWith + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringStartsWith2() + { + $constraint = PHPUnit_Framework_Assert::stringStartsWith('prefix'); + + try { + $constraint->evaluate('foo', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringStartsWith + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::stringStartsWith + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringStartsNotWith() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::stringStartsWith('prefix') + ); + + $this->assertTrue($constraint->evaluate('foo', '', true)); + $this->assertFalse($constraint->evaluate('prefixfoo', '', true)); + $this->assertEquals('starts not with "prefix"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('prefixfoo'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringStartsWith + * @covers PHPUnit_Framework_Assert::stringStartsWith + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringStartsNotWith2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::stringStartsWith('prefix') + ); + + try { + $constraint->evaluate('prefixfoo', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringContains + * @covers PHPUnit_Framework_Assert::stringContains + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringContains() + { + $constraint = PHPUnit_Framework_Assert::stringContains('foo'); + + $this->assertFalse($constraint->evaluate('barbazbar', '', true)); + $this->assertTrue($constraint->evaluate('barfoobar', '', true)); + $this->assertEquals('contains "foo"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('barbazbar'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringContains + * @covers PHPUnit_Framework_Assert::stringContains + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringContains2() + { + $constraint = PHPUnit_Framework_Assert::stringContains('foo'); + + try { + $constraint->evaluate('barbazbar', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringContains + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::stringContains + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringNotContains() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::stringContains('foo') + ); + + $this->assertTrue($constraint->evaluate('barbazbar', '', true)); + $this->assertFalse($constraint->evaluate('barfoobar', '', true)); + $this->assertEquals('does not contain "foo"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('barfoobar'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringContains + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::stringContains + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringNotContains2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::stringContains('foo') + ); + + try { + $constraint->evaluate('barfoobar', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringEndsWith + * @covers PHPUnit_Framework_Assert::stringEndsWith + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringEndsWith() + { + $constraint = PHPUnit_Framework_Assert::stringEndsWith('suffix'); + + $this->assertFalse($constraint->evaluate('foo', '', true)); + $this->assertTrue($constraint->evaluate('foosuffix', '', true)); + $this->assertEquals('ends with "suffix"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('foo'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringEndsWith + * @covers PHPUnit_Framework_Assert::stringEndsWith + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringEndsWith2() + { + $constraint = PHPUnit_Framework_Assert::stringEndsWith('suffix'); + + try { + $constraint->evaluate('foo', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringEndsWith + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::stringEndsWith + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringEndsNotWith() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::stringEndsWith('suffix') + ); + + $this->assertTrue($constraint->evaluate('foo', '', true)); + $this->assertFalse($constraint->evaluate('foosuffix', '', true)); + $this->assertEquals('ends not with "suffix"', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate('foosuffix'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_StringEndsWith + * @covers PHPUnit_Framework_Assert::stringEndsWith + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintStringEndsNotWith2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::stringEndsWith('suffix') + ); + + try { + $constraint->evaluate('foosuffix', 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_TraversableContains + */ + public function testConstraintArrayContainsCheckForObjectIdentity() + { + // Check for primitive type. + $constraint = new PHPUnit_Framework_Constraint_TraversableContains('foo', true, true); + + $this->assertFalse($constraint->evaluate(array(0), '', true)); + $this->assertFalse($constraint->evaluate(array(true), '', true)); + + // Default case. + $constraint = new PHPUnit_Framework_Constraint_TraversableContains('foo'); + + $this->assertTrue($constraint->evaluate(array(0), '', true)); + $this->assertTrue($constraint->evaluate(array(true), '', true)); + } + + /** + * @covers PHPUnit_Framework_Constraint_TraversableContains + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintArrayContains() + { + $constraint = new PHPUnit_Framework_Constraint_TraversableContains('foo'); + + $this->assertFalse($constraint->evaluate(array('bar'), '', true)); + $this->assertTrue($constraint->evaluate(array('foo'), '', true)); + $this->assertEquals("contains 'foo'", $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(array('bar')); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_TraversableContains + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintArrayContains2() + { + $constraint = new PHPUnit_Framework_Constraint_TraversableContains('foo'); + + try { + $constraint->evaluate(array('bar'), 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_TraversableContains + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintArrayNotContains() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + new PHPUnit_Framework_Constraint_TraversableContains('foo') + ); + + $this->assertTrue($constraint->evaluate(array('bar'), '', true)); + $this->assertFalse($constraint->evaluate(array('foo'), '', true)); + $this->assertEquals("does not contain 'foo'", $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(array('foo')); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_TraversableContains + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintArrayNotContains2() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + new PHPUnit_Framework_Constraint_TraversableContains('foo') + ); + + try { + $constraint->evaluate(array('foo'), 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_TraversableContains + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintSplObjectStorageContains() + { + $object = new StdClass; + $constraint = new PHPUnit_Framework_Constraint_TraversableContains($object); + $this->assertStringMatchesFormat('contains stdClass Object &%s ()', $constraint->toString()); + + $storage = new SplObjectStorage; + $this->assertFalse($constraint->evaluate($storage, '', true)); + + $storage->attach($object); + $this->assertTrue($constraint->evaluate($storage, '', true)); + + try { + $constraint->evaluate(new SplObjectStorage); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertStringMatchesFormat( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_TraversableContains + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintSplObjectStorageContains2() + { + $object = new StdClass; + $constraint = new PHPUnit_Framework_Constraint_TraversableContains($object); + + try { + $constraint->evaluate(new SplObjectStorage, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertStringMatchesFormat( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::attributeEqualTo + * @covers PHPUnit_Framework_Constraint_Attribute + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testAttributeEqualTo() + { + $object = new ClassWithNonPublicAttributes; + $constraint = PHPUnit_Framework_Assert::attributeEqualTo('foo', 1); + + $this->assertTrue($constraint->evaluate($object, '', true)); + $this->assertEquals('attribute "foo" is equal to 1', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + $constraint = PHPUnit_Framework_Assert::attributeEqualTo('foo', 2); + + $this->assertFalse($constraint->evaluate($object, '', true)); + + try { + $constraint->evaluate($object); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::attributeEqualTo + * @covers PHPUnit_Framework_Constraint_Attribute + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testAttributeEqualTo2() + { + $object = new ClassWithNonPublicAttributes; + $constraint = PHPUnit_Framework_Assert::attributeEqualTo('foo', 2); + + try { + $constraint->evaluate($object, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::attributeEqualTo + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_Constraint_Attribute + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testAttributeNotEqualTo() + { + $object = new ClassWithNonPublicAttributes; + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::attributeEqualTo('foo', 2) + ); + + $this->assertTrue($constraint->evaluate($object, '', true)); + $this->assertEquals('attribute "foo" is not equal to 2', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::attributeEqualTo('foo', 1) + ); + + $this->assertFalse($constraint->evaluate($object, '', true)); + + try { + $constraint->evaluate($object); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Assert::attributeEqualTo + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_Constraint_Attribute + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testAttributeNotEqualTo2() + { + $object = new ClassWithNonPublicAttributes; + $constraint = PHPUnit_Framework_Assert::logicalNot( + PHPUnit_Framework_Assert::attributeEqualTo('foo', 1) + ); + + try { + $constraint->evaluate($object, 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEmpty + * @covers PHPUnit_Framework_Constraint::count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsEmpty() + { + $constraint = new PHPUnit_Framework_Constraint_IsEmpty; + + $this->assertFalse($constraint->evaluate(array('foo'), '', true)); + $this->assertTrue($constraint->evaluate(array(), '', true)); + $this->assertFalse($constraint->evaluate(new ArrayObject(array('foo')), '', true)); + $this->assertTrue($constraint->evaluate(new ArrayObject(array()), '', true)); + $this->assertEquals('is empty', $constraint->toString()); + $this->assertEquals(1, count($constraint)); + + try { + $constraint->evaluate(array('foo')); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_IsEmpty + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintIsEmpty2() + { + $constraint = new PHPUnit_Framework_Constraint_IsEmpty; + + try { + $constraint->evaluate(array('foo'), 'custom message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_Count + */ + public function testConstraintCountWithAnArray() + { + $constraint = new PHPUnit_Framework_Constraint_Count(5); + + $this->assertTrue($constraint->evaluate(array(1, 2, 3, 4, 5), '', true)); + $this->assertFalse($constraint->evaluate(array(1, 2, 3, 4), '', true)); + } + + /** + * @covers PHPUnit_Framework_Constraint_Count + */ + public function testConstraintCountWithAnIteratorWhichDoesNotImplementCountable() + { + $constraint = new PHPUnit_Framework_Constraint_Count(5); + + $this->assertTrue($constraint->evaluate(new TestIterator(array(1, 2, 3, 4, 5)), '', true)); + $this->assertFalse($constraint->evaluate(new TestIterator(array(1, 2, 3, 4)), '', true)); + } + + /** + * @covers PHPUnit_Framework_Constraint_Count + */ + public function testConstraintCountWithAnObjectImplementingCountable() + { + $constraint = new PHPUnit_Framework_Constraint_Count(5); + + $this->assertTrue($constraint->evaluate(new ArrayObject(array(1, 2, 3, 4, 5)), '', true)); + $this->assertFalse($constraint->evaluate(new ArrayObject(array(1, 2, 3, 4)), '', true)); + } + + /** + * @covers PHPUnit_Framework_Constraint_Count + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintCountFailing() + { + $constraint = new PHPUnit_Framework_Constraint_Count(5); + + try { + $constraint->evaluate(array(1, 2)); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_Count + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotCountFailing() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + new PHPUnit_Framework_Constraint_Count(2) + ); + + try { + $constraint->evaluate(array(1, 2)); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_SameSize + */ + public function testConstraintSameSizeWithAnArray() + { + $constraint = new PHPUnit_Framework_Constraint_SameSize(array(1, 2, 3, 4, 5)); + + $this->assertTrue($constraint->evaluate(array(6, 7, 8, 9, 10), '', true)); + $this->assertFalse($constraint->evaluate(array(1, 2, 3, 4), '', true)); + } + + /** + * @covers PHPUnit_Framework_Constraint_SameSize + */ + public function testConstraintSameSizeWithAnIteratorWhichDoesNotImplementCountable() + { + $constraint = new PHPUnit_Framework_Constraint_SameSize(new TestIterator(array(1, 2, 3, 4, 5))); + + $this->assertTrue($constraint->evaluate(new TestIterator(array(6, 7, 8, 9, 10)), '', true)); + $this->assertFalse($constraint->evaluate(new TestIterator(array(1, 2, 3, 4)), '', true)); + } + + /** + * @covers PHPUnit_Framework_Constraint_SameSize + */ + public function testConstraintSameSizeWithAnObjectImplementingCountable() + { + $constraint = new PHPUnit_Framework_Constraint_SameSize(new ArrayObject(array(1, 2, 3, 4, 5))); + + $this->assertTrue($constraint->evaluate(new ArrayObject(array(6, 7, 8, 9, 10)), '', true)); + $this->assertFalse($constraint->evaluate(new ArrayObject(array(1, 2, 3, 4)), '', true)); + } + + /** + * @covers PHPUnit_Framework_Constraint_SameSize + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintSameSizeFailing() + { + $constraint = new PHPUnit_Framework_Constraint_SameSize(array(1, 2, 3, 4, 5)); + + try { + $constraint->evaluate(array(1, 2)); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_SameSize + * @covers PHPUnit_Framework_Constraint_Not + * @covers PHPUnit_Framework_Assert::logicalNot + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintNotSameSizeFailing() + { + $constraint = PHPUnit_Framework_Assert::logicalNot( + new PHPUnit_Framework_Constraint_SameSize(array(1, 2)) + ); + + try { + $constraint->evaluate(array(3, 4)); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * @covers PHPUnit_Framework_Constraint_Exception + * @covers PHPUnit_Framework_TestFailure::exceptionToString + */ + public function testConstraintException() + { + $constraint = new PHPUnit_Framework_Constraint_Exception('FoobarException'); + $exception = new DummyException('Test'); + $stackTrace = $exception->getTraceAsString(); + + try { + $constraint->evaluate($exception); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->assertEquals( + <<fail(); + } + + /** + * Removes spaces in front of newlines + * + * @param string $string + * + * @return string + */ + private function trimnl($string) + { + return preg_replace('/[ ]*\n/', "\n", $string); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/SuiteTest.php b/vendor/phpunit/phpunit/tests/Framework/SuiteTest.php new file mode 100644 index 000000000..e3f58b3d3 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/SuiteTest.php @@ -0,0 +1,242 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'BeforeAndAfterTest.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'BeforeClassAndAfterClassTest.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'TestWithTest.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'DataProviderSkippedTest.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'DataProviderIncompleteTest.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'InheritedTestCase.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NoTestCaseClass.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NoTestCases.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NotPublicTestCase.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NotVoidTestCase.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'OverrideTestCase.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'RequirementsClassBeforeClassHookTest.php'; + +/** + * @since Class available since Release 2.0.0 + * @covers PHPUnit_Framework_TestSuite + */ +class Framework_SuiteTest extends PHPUnit_Framework_TestCase +{ + protected $result; + + protected function setUp() + { + $this->result = new PHPUnit_Framework_TestResult; + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite; + + $suite->addTest(new self('testAddTestSuite')); + $suite->addTest(new self('testInheritedTests')); + $suite->addTest(new self('testNoTestCases')); + $suite->addTest(new self('testNoTestCaseClass')); + $suite->addTest(new self('testNotExistingTestCase')); + $suite->addTest(new self('testNotPublicTestCase')); + $suite->addTest(new self('testNotVoidTestCase')); + $suite->addTest(new self('testOneTestCase')); + $suite->addTest(new self('testShadowedTests')); + $suite->addTest(new self('testBeforeClassAndAfterClassAnnotations')); + $suite->addTest(new self('testBeforeAnnotation')); + $suite->addTest(new self('testTestWithAnnotation')); + $suite->addTest(new self('testSkippedTestDataProvider')); + $suite->addTest(new self('testIncompleteTestDataProvider')); + $suite->addTest(new self('testRequirementsBeforeClassHook')); + $suite->addTest(new self('testDontSkipInheritedClass')); + + return $suite; + } + + public function testAddTestSuite() + { + $suite = new PHPUnit_Framework_TestSuite( + 'OneTestCase' + ); + + $suite->run($this->result); + + $this->assertEquals(1, count($this->result)); + } + + public function testInheritedTests() + { + $suite = new PHPUnit_Framework_TestSuite( + 'InheritedTestCase' + ); + + $suite->run($this->result); + + $this->assertTrue($this->result->wasSuccessful()); + $this->assertEquals(2, count($this->result)); + } + + public function testNoTestCases() + { + $suite = new PHPUnit_Framework_TestSuite( + 'NoTestCases' + ); + + $suite->run($this->result); + + $this->assertTrue(!$this->result->wasSuccessful()); + $this->assertEquals(1, $this->result->failureCount()); + $this->assertEquals(1, count($this->result)); + } + + /** + * @expectedException PHPUnit_Framework_Exception + */ + public function testNoTestCaseClass() + { + $suite = new PHPUnit_Framework_TestSuite('NoTestCaseClass'); + } + + public function testNotExistingTestCase() + { + $suite = new self('notExistingMethod'); + + $suite->run($this->result); + + $this->assertEquals(0, $this->result->errorCount()); + $this->assertEquals(1, $this->result->failureCount()); + $this->assertEquals(1, count($this->result)); + } + + public function testNotPublicTestCase() + { + $suite = new PHPUnit_Framework_TestSuite( + 'NotPublicTestCase' + ); + + $this->assertEquals(2, count($suite)); + } + + public function testNotVoidTestCase() + { + $suite = new PHPUnit_Framework_TestSuite( + 'NotVoidTestCase' + ); + + $this->assertEquals(1, count($suite)); + } + + public function testOneTestCase() + { + $suite = new PHPUnit_Framework_TestSuite( + 'OneTestCase' + ); + + $suite->run($this->result); + + $this->assertEquals(0, $this->result->errorCount()); + $this->assertEquals(0, $this->result->failureCount()); + $this->assertEquals(1, count($this->result)); + $this->assertTrue($this->result->wasSuccessful()); + } + + public function testShadowedTests() + { + $suite = new PHPUnit_Framework_TestSuite( + 'OverrideTestCase' + ); + + $suite->run($this->result); + + $this->assertEquals(1, count($this->result)); + } + + public function testBeforeClassAndAfterClassAnnotations() + { + $suite = new PHPUnit_Framework_TestSuite( + 'BeforeClassAndAfterClassTest' + ); + + BeforeClassAndAfterClassTest::resetProperties(); + $suite->run($this->result); + + $this->assertEquals(1, BeforeClassAndAfterClassTest::$beforeClassWasRun, '@beforeClass method was not run once for the whole suite.'); + $this->assertEquals(1, BeforeClassAndAfterClassTest::$afterClassWasRun, '@afterClass method was not run once for the whole suite.'); + } + + public function testBeforeAnnotation() + { + $test = new PHPUnit_Framework_TestSuite( + 'BeforeAndAfterTest' + ); + + BeforeAndAfterTest::resetProperties(); + $result = $test->run(); + + $this->assertEquals(2, BeforeAndAfterTest::$beforeWasRun); + $this->assertEquals(2, BeforeAndAfterTest::$afterWasRun); + } + + public function testTestWithAnnotation() + { + $test = new PHPUnit_Framework_TestSuite( + 'TestWithTest' + ); + + BeforeAndAfterTest::resetProperties(); + $result = $test->run(); + + $this->assertEquals(4, count($result->passed())); + } + + public function testSkippedTestDataProvider() + { + $suite = new PHPUnit_Framework_TestSuite('DataProviderSkippedTest'); + + $suite->run($this->result); + + $this->assertEquals(3, $this->result->count()); + $this->assertEquals(1, $this->result->skippedCount()); + } + + public function testIncompleteTestDataProvider() + { + $suite = new PHPUnit_Framework_TestSuite('DataProviderIncompleteTest'); + + $suite->run($this->result); + + $this->assertEquals(3, $this->result->count()); + $this->assertEquals(1, $this->result->notImplementedCount()); + } + + public function testRequirementsBeforeClassHook() + { + $suite = new PHPUnit_Framework_TestSuite( + 'RequirementsClassBeforeClassHookTest' + ); + + $suite->run($this->result); + + $this->assertEquals(0, $this->result->errorCount()); + $this->assertEquals(1, $this->result->skippedCount()); + } + + public function testDontSkipInheritedClass() + { + $suite = new PHPUnit_Framework_TestSuite( + 'DontSkipInheritedClass' + ); + + $dir = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'Inheritance' . DIRECTORY_SEPARATOR; + + $suite->addTestFile($dir . 'InheritanceA.php'); + $suite->addTestFile($dir . 'InheritanceB.php'); + $result = $suite->run(); + $this->assertEquals(2, count($result)); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/TestCaseTest.php b/vendor/phpunit/phpunit/tests/Framework/TestCaseTest.php new file mode 100644 index 000000000..913327865 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/TestCaseTest.php @@ -0,0 +1,550 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NoArgTestCaseTest.php'; +require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'Singleton.php'; + +$GLOBALS['a'] = 'a'; +$_ENV['b'] = 'b'; +$_POST['c'] = 'c'; +$_GET['d'] = 'd'; +$_COOKIE['e'] = 'e'; +$_SERVER['f'] = 'f'; +$_FILES['g'] = 'g'; +$_REQUEST['h'] = 'h'; +$GLOBALS['i'] = 'i'; + +/** + * @since Class available since Release 2.0.0 + * @covers PHPUnit_Framework_TestCase + */ +class Framework_TestCaseTest extends PHPUnit_Framework_TestCase +{ + protected $backupGlobalsBlacklist = array('i', 'singleton'); + + /** + * Used be testStaticAttributesBackupPre + */ + protected static $_testStatic = 0; + + public function testCaseToString() + { + $this->assertEquals( + 'Framework_TestCaseTest::testCaseToString', + $this->toString() + ); + } + + public function testSuccess() + { + $test = new Success; + $result = $test->run(); + + $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_PASSED, $test->getStatus()); + $this->assertEquals(0, $result->errorCount()); + $this->assertEquals(0, $result->failureCount()); + $this->assertEquals(0, $result->skippedCount()); + $this->assertEquals(1, count($result)); + } + + public function testFailure() + { + $test = new Failure; + $result = $test->run(); + + $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE, $test->getStatus()); + $this->assertEquals(0, $result->errorCount()); + $this->assertEquals(1, $result->failureCount()); + $this->assertEquals(0, $result->skippedCount()); + $this->assertEquals(1, count($result)); + } + + public function testError() + { + $test = new TestError; + $result = $test->run(); + + $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_ERROR, $test->getStatus()); + $this->assertEquals(1, $result->errorCount()); + $this->assertEquals(0, $result->failureCount()); + $this->assertEquals(0, $result->skippedCount()); + $this->assertEquals(1, count($result)); + } + + public function testSkipped() + { + $test = new TestSkipped(); + $result = $test->run(); + + $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED, $test->getStatus()); + $this->assertEquals('Skipped test', $test->getStatusMessage()); + $this->assertEquals(0, $result->errorCount()); + $this->assertEquals(0, $result->failureCount()); + $this->assertEquals(1, $result->skippedCount()); + $this->assertEquals(1, count($result)); + } + + public function testIncomplete() + { + $test = new TestIncomplete(); + $result = $test->run(); + + $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE, $test->getStatus()); + $this->assertEquals('Incomplete test', $test->getStatusMessage()); + $this->assertEquals(0, $result->errorCount()); + $this->assertEquals(0, $result->failureCount()); + $this->assertEquals(0, $result->skippedCount()); + $this->assertEquals(1, count($result)); + } + + public function testExceptionInSetUp() + { + $test = new ExceptionInSetUpTest('testSomething'); + $result = $test->run(); + + $this->assertTrue($test->setUp); + $this->assertFalse($test->assertPreConditions); + $this->assertFalse($test->testSomething); + $this->assertFalse($test->assertPostConditions); + $this->assertTrue($test->tearDown); + } + + public function testExceptionInAssertPreConditions() + { + $test = new ExceptionInAssertPreConditionsTest('testSomething'); + $result = $test->run(); + + $this->assertTrue($test->setUp); + $this->assertTrue($test->assertPreConditions); + $this->assertFalse($test->testSomething); + $this->assertFalse($test->assertPostConditions); + $this->assertTrue($test->tearDown); + } + + public function testExceptionInTest() + { + $test = new ExceptionInTest('testSomething'); + $result = $test->run(); + + $this->assertTrue($test->setUp); + $this->assertTrue($test->assertPreConditions); + $this->assertTrue($test->testSomething); + $this->assertFalse($test->assertPostConditions); + $this->assertTrue($test->tearDown); + } + + public function testExceptionInAssertPostConditions() + { + $test = new ExceptionInAssertPostConditionsTest('testSomething'); + $result = $test->run(); + + $this->assertTrue($test->setUp); + $this->assertTrue($test->assertPreConditions); + $this->assertTrue($test->testSomething); + $this->assertTrue($test->assertPostConditions); + $this->assertTrue($test->tearDown); + } + + public function testExceptionInTearDown() + { + $test = new ExceptionInTearDownTest('testSomething'); + $result = $test->run(); + + $this->assertTrue($test->setUp); + $this->assertTrue($test->assertPreConditions); + $this->assertTrue($test->testSomething); + $this->assertTrue($test->assertPostConditions); + $this->assertTrue($test->tearDown); + } + + public function testNoArgTestCasePasses() + { + $result = new PHPUnit_Framework_TestResult; + $t = new PHPUnit_Framework_TestSuite('NoArgTestCaseTest'); + + $t->run($result); + + $this->assertEquals(1, count($result)); + $this->assertEquals(0, $result->failureCount()); + $this->assertEquals(0, $result->errorCount()); + } + + public function testWasRun() + { + $test = new WasRun; + $test->run(); + + $this->assertTrue($test->wasRun); + } + + public function testException() + { + $test = new ThrowExceptionTestCase('test'); + $test->setExpectedException('RuntimeException'); + + $result = $test->run(); + + $this->assertEquals(1, count($result)); + $this->assertTrue($result->wasSuccessful()); + } + + public function testExceptionWithMessage() + { + $test = new ThrowExceptionTestCase('test'); + $test->setExpectedException('RuntimeException', 'A runtime error occurred'); + + $result = $test->run(); + + $this->assertEquals(1, count($result)); + $this->assertTrue($result->wasSuccessful()); + } + + public function testExceptionWithWrongMessage() + { + $test = new ThrowExceptionTestCase('test'); + $test->setExpectedException('RuntimeException', 'A logic error occurred'); + + $result = $test->run(); + + $this->assertEquals(1, $result->failureCount()); + $this->assertEquals(1, count($result)); + $this->assertEquals( + "Failed asserting that exception message 'A runtime error occurred' contains 'A logic error occurred'.", + $test->getStatusMessage() + ); + } + + public function testExceptionWithRegexpMessage() + { + $test = new ThrowExceptionTestCase('test'); + $test->setExpectedExceptionRegExp('RuntimeException', '/runtime .*? occurred/'); + + $result = $test->run(); + + $this->assertEquals(1, count($result)); + $this->assertTrue($result->wasSuccessful()); + } + + public function testExceptionWithWrongRegexpMessage() + { + $test = new ThrowExceptionTestCase('test'); + $test->setExpectedExceptionRegExp('RuntimeException', '/logic .*? occurred/'); + + $result = $test->run(); + + $this->assertEquals(1, $result->failureCount()); + $this->assertEquals(1, count($result)); + $this->assertEquals( + "Failed asserting that exception message 'A runtime error occurred' matches '/logic .*? occurred/'.", + $test->getStatusMessage() + ); + } + + /** + * @covers PHPUnit_Framework_Constraint_ExceptionMessageRegExp + */ + public function testExceptionWithInvalidRegexpMessage() + { + $test = new ThrowExceptionTestCase('test'); + $test->setExpectedExceptionRegExp('RuntimeException', '#runtime .*? occurred/'); // wrong delimiter + + $result = $test->run(); + + $this->assertEquals( + "Invalid expected exception message regex given: '#runtime .*? occurred/'", + $test->getStatusMessage() + ); + } + + public function testNoException() + { + $test = new ThrowNoExceptionTestCase('test'); + $test->setExpectedException('RuntimeException'); + + $result = $test->run(); + + $this->assertEquals(1, $result->failureCount()); + $this->assertEquals(1, count($result)); + } + + public function testWrongException() + { + $test = new ThrowExceptionTestCase('test'); + $test->setExpectedException('InvalidArgumentException'); + + $result = $test->run(); + + $this->assertEquals(1, $result->failureCount()); + $this->assertEquals(1, count($result)); + } + + /** + * @backupGlobals enabled + */ + public function testGlobalsBackupPre() + { + global $a; + global $i; + + $this->assertEquals('a', $a); + $this->assertEquals('a', $GLOBALS['a']); + $this->assertEquals('b', $_ENV['b']); + $this->assertEquals('c', $_POST['c']); + $this->assertEquals('d', $_GET['d']); + $this->assertEquals('e', $_COOKIE['e']); + $this->assertEquals('f', $_SERVER['f']); + $this->assertEquals('g', $_FILES['g']); + $this->assertEquals('h', $_REQUEST['h']); + $this->assertEquals('i', $i); + $this->assertEquals('i', $GLOBALS['i']); + + $GLOBALS['a'] = 'aa'; + $GLOBALS['foo'] = 'bar'; + $_ENV['b'] = 'bb'; + $_POST['c'] = 'cc'; + $_GET['d'] = 'dd'; + $_COOKIE['e'] = 'ee'; + $_SERVER['f'] = 'ff'; + $_FILES['g'] = 'gg'; + $_REQUEST['h'] = 'hh'; + $GLOBALS['i'] = 'ii'; + + $this->assertEquals('aa', $a); + $this->assertEquals('aa', $GLOBALS['a']); + $this->assertEquals('bar', $GLOBALS['foo']); + $this->assertEquals('bb', $_ENV['b']); + $this->assertEquals('cc', $_POST['c']); + $this->assertEquals('dd', $_GET['d']); + $this->assertEquals('ee', $_COOKIE['e']); + $this->assertEquals('ff', $_SERVER['f']); + $this->assertEquals('gg', $_FILES['g']); + $this->assertEquals('hh', $_REQUEST['h']); + $this->assertEquals('ii', $i); + $this->assertEquals('ii', $GLOBALS['i']); + } + + public function testGlobalsBackupPost() + { + global $a; + global $i; + + $this->assertEquals('a', $a); + $this->assertEquals('a', $GLOBALS['a']); + $this->assertEquals('b', $_ENV['b']); + $this->assertEquals('c', $_POST['c']); + $this->assertEquals('d', $_GET['d']); + $this->assertEquals('e', $_COOKIE['e']); + $this->assertEquals('f', $_SERVER['f']); + $this->assertEquals('g', $_FILES['g']); + $this->assertEquals('h', $_REQUEST['h']); + $this->assertEquals('ii', $i); + $this->assertEquals('ii', $GLOBALS['i']); + + $this->assertArrayNotHasKey('foo', $GLOBALS); + } + + /** + * @backupGlobals enabled + * @backupStaticAttributes enabled + */ + public function testStaticAttributesBackupPre() + { + $GLOBALS['singleton'] = Singleton::getInstance(); + self::$_testStatic = 123; + } + + /** + * @depends testStaticAttributesBackupPre + */ + public function testStaticAttributesBackupPost() + { + $this->assertNotSame($GLOBALS['singleton'], Singleton::getInstance()); + $this->assertSame(0, self::$_testStatic); + } + + public function testIsInIsolationReturnsFalse() + { + $test = new IsolationTest('testIsInIsolationReturnsFalse'); + $result = $test->run(); + + $this->assertEquals(1, count($result)); + $this->assertTrue($result->wasSuccessful()); + } + + public function testIsInIsolationReturnsTrue() + { + $test = new IsolationTest('testIsInIsolationReturnsTrue'); + $test->setRunTestInSeparateProcess(true); + $result = $test->run(); + + $this->assertEquals(1, count($result)); + $this->assertTrue($result->wasSuccessful()); + } + + public function testExpectOutputStringFooActualFoo() + { + $test = new OutputTestCase('testExpectOutputStringFooActualFoo'); + $result = $test->run(); + + $this->assertEquals(1, count($result)); + $this->assertTrue($result->wasSuccessful()); + } + + public function testExpectOutputStringFooActualBar() + { + $test = new OutputTestCase('testExpectOutputStringFooActualBar'); + $result = $test->run(); + + $this->assertEquals(1, count($result)); + $this->assertFalse($result->wasSuccessful()); + } + + public function testExpectOutputRegexFooActualFoo() + { + $test = new OutputTestCase('testExpectOutputRegexFooActualFoo'); + $result = $test->run(); + + $this->assertEquals(1, count($result)); + $this->assertTrue($result->wasSuccessful()); + } + + public function testExpectOutputRegexFooActualBar() + { + $test = new OutputTestCase('testExpectOutputRegexFooActualBar'); + $result = $test->run(); + + $this->assertEquals(1, count($result)); + $this->assertFalse($result->wasSuccessful()); + } + + public function testSkipsIfRequiresHigherVersionOfPHPUnit() + { + $test = new RequirementsTest('testAlwaysSkip'); + $result = $test->run(); + + $this->assertEquals(1, $result->skippedCount()); + $this->assertEquals( + 'PHPUnit 1111111 (or later) is required.', + $test->getStatusMessage() + ); + } + + public function testSkipsIfRequiresHigherVersionOfPHP() + { + $test = new RequirementsTest('testAlwaysSkip2'); + $result = $test->run(); + + $this->assertEquals(1, $result->skippedCount()); + $this->assertEquals( + 'PHP 9999999 (or later) is required.', + $test->getStatusMessage() + ); + } + + public function testSkipsIfRequiresNonExistingOs() + { + $test = new RequirementsTest('testAlwaysSkip3'); + $result = $test->run(); + + $this->assertEquals(1, $result->skippedCount()); + $this->assertEquals( + 'Operating system matching /DOESNOTEXIST/i is required.', + $test->getStatusMessage() + ); + } + + public function testSkipsIfRequiresNonExistingFunction() + { + $test = new RequirementsTest('testNine'); + $result = $test->run(); + + $this->assertEquals(1, $result->skippedCount()); + $this->assertEquals( + 'Function testFunc is required.', + $test->getStatusMessage() + ); + } + + public function testSkipsIfRequiresNonExistingExtension() + { + $test = new RequirementsTest('testTen'); + $result = $test->run(); + + $this->assertEquals( + 'Extension testExt is required.', + $test->getStatusMessage() + ); + } + + public function testSkipsProvidesMessagesForAllSkippingReasons() + { + $test = new RequirementsTest('testAllPossibleRequirements'); + $result = $test->run(); + + $this->assertEquals( + 'PHP 99-dev (or later) is required.' . PHP_EOL . + 'PHPUnit 9-dev (or later) is required.' . PHP_EOL . + 'Operating system matching /DOESNOTEXIST/i is required.' . PHP_EOL . + 'Function testFuncOne is required.' . PHP_EOL . + 'Function testFuncTwo is required.' . PHP_EOL . + 'Extension testExtOne is required.' . PHP_EOL . + 'Extension testExtTwo is required.', + $test->getStatusMessage() + ); + } + + public function testRequiringAnExistingMethodDoesNotSkip() + { + $test = new RequirementsTest('testExistingMethod'); + $result = $test->run(); + $this->assertEquals(0, $result->skippedCount()); + } + + public function testRequiringAnExistingFunctionDoesNotSkip() + { + $test = new RequirementsTest('testExistingFunction'); + $result = $test->run(); + $this->assertEquals(0, $result->skippedCount()); + } + + public function testRequiringAnExistingExtensionDoesNotSkip() + { + $test = new RequirementsTest('testExistingExtension'); + $result = $test->run(); + $this->assertEquals(0, $result->skippedCount()); + } + + public function testRequiringAnExistingOsDoesNotSkip() + { + $test = new RequirementsTest('testExistingOs'); + $result = $test->run(); + $this->assertEquals(0, $result->skippedCount()); + } + + public function testCurrentWorkingDirectoryIsRestored() + { + $expectedCwd = getcwd(); + + $test = new ChangeCurrentWorkingDirectoryTest('testSomethingThatChangesTheCwd'); + $test->run(); + + $this->assertSame($expectedCwd, getcwd()); + } + + /** + * @requires PHP 7 + * @expectedException TypeError + */ + public function testTypeErrorCanBeExpected() + { + $o = new ClassWithScalarTypeDeclarations; + $o->foo(null, null); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/TestFailureTest.php b/vendor/phpunit/phpunit/tests/Framework/TestFailureTest.php new file mode 100644 index 000000000..8df0a3945 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/TestFailureTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since File available since Release 3.7.20 + */ +class Framework_TestFailureTest extends PHPUnit_Framework_TestCase +{ + /** + * @covers PHPUnit_Framework_TestFailure::toString + */ + public function testToString() + { + $test = new self(__FUNCTION__); + $exception = new PHPUnit_Framework_Exception('message'); + $failure = new PHPUnit_Framework_TestFailure($test, $exception); + + $this->assertEquals(__METHOD__ . ': message', $failure->toString()); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/TestImplementorTest.php b/vendor/phpunit/phpunit/tests/Framework/TestImplementorTest.php new file mode 100644 index 000000000..f10a5098a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/TestImplementorTest.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 2.0.0 + */ +class Framework_TestImplementorTest extends PHPUnit_Framework_TestCase +{ + /** + * @covers PHPUnit_Framework_TestCase + */ + public function testSuccessfulRun() + { + $result = new PHPUnit_Framework_TestResult; + + $test = new DoubleTestCase(new Success); + $test->run($result); + + $this->assertEquals(count($test), count($result)); + $this->assertEquals(0, $result->errorCount()); + $this->assertEquals(0, $result->failureCount()); + } +} diff --git a/vendor/phpunit/phpunit/tests/Framework/TestListenerTest.php b/vendor/phpunit/phpunit/tests/Framework/TestListenerTest.php new file mode 100644 index 000000000..589741bfd --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Framework/TestListenerTest.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 2.0.0 + * @covers PHPUnit_Framework_TestCase + */ +class Framework_TestListenerTest extends PHPUnit_Framework_TestCase implements PHPUnit_Framework_TestListener +{ + protected $endCount; + protected $errorCount; + protected $failureCount; + protected $notImplementedCount; + protected $riskyCount; + protected $skippedCount; + protected $result; + protected $startCount; + + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->errorCount++; + } + + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $this->failureCount++; + } + + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->notImplementedCount++; + } + + public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->riskyCount++; + } + + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->skippedCount++; + } + + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + public function startTest(PHPUnit_Framework_Test $test) + { + $this->startCount++; + } + + public function endTest(PHPUnit_Framework_Test $test, $time) + { + $this->endCount++; + } + + protected function setUp() + { + $this->result = new PHPUnit_Framework_TestResult; + $this->result->addListener($this); + + $this->endCount = 0; + $this->failureCount = 0; + $this->notImplementedCount = 0; + $this->riskyCount = 0; + $this->skippedCount = 0; + $this->startCount = 0; + } + + public function testError() + { + $test = new TestError; + $test->run($this->result); + + $this->assertEquals(1, $this->errorCount); + $this->assertEquals(1, $this->endCount); + } + + public function testFailure() + { + $test = new Failure; + $test->run($this->result); + + $this->assertEquals(1, $this->failureCount); + $this->assertEquals(1, $this->endCount); + } + + public function testStartStop() + { + $test = new Success; + $test->run($this->result); + + $this->assertEquals(1, $this->startCount); + $this->assertEquals(1, $this->endCount); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1149.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1149.phpt new file mode 100644 index 000000000..c41119085 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1149.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-1149: Test swallows output buffer when run in a separate process +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.1.2 + +Time: %s, Memory: %s + +OK (2 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1149/Issue1149Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1149/Issue1149Test.php new file mode 100644 index 000000000..01ac870a0 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1149/Issue1149Test.php @@ -0,0 +1,18 @@ +assertTrue(true); + print '1'; + } + + /** + * @runInSeparateProcess + */ + public function testTwo() + { + $this->assertTrue(true); + print '2'; + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1216.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216.phpt new file mode 100644 index 000000000..631bb2a18 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-1216: PHPUnit bootstrap must take globals vars even when the file is specified in command line +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + + +Starting test 'Issue1216Test::testConfigAvailableInBootstrap'. +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/Issue1216Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/Issue1216Test.php new file mode 100644 index 000000000..cfceaf582 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/Issue1216Test.php @@ -0,0 +1,8 @@ +assertTrue($_ENV['configAvailableInBootstrap']); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/bootstrap1216.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/bootstrap1216.php new file mode 100644 index 000000000..cec2724aa --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/bootstrap1216.php @@ -0,0 +1,2 @@ + + + Issue1216Test.php + + + + + diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1265.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265.phpt new file mode 100644 index 000000000..1b3159c34 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-1265: Could not use "PHPUnit_Runner_StandardTestSuiteLoader" as loader +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/Issue1265Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/Issue1265Test.php new file mode 100644 index 000000000..68d71b3c0 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/Issue1265Test.php @@ -0,0 +1,8 @@ +assertTrue(true); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/phpunit1265.xml b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/phpunit1265.xml new file mode 100644 index 000000000..27fdd529f --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/phpunit1265.xml @@ -0,0 +1,2 @@ + + diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1330.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330.phpt new file mode 100644 index 000000000..48dab3c2c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-1330: Allow non-ambiguous shortened longopts +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + + +Starting test 'Issue1330Test::testTrue'. +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/Issue1330Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/Issue1330Test.php new file mode 100644 index 000000000..0829cb95b --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/Issue1330Test.php @@ -0,0 +1,8 @@ +assertTrue(PHPUNIT_1330); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/phpunit1330.xml b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/phpunit1330.xml new file mode 100644 index 000000000..a61e0cc10 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/phpunit1330.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1335.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335.phpt new file mode 100644 index 000000000..1ed520310 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-1335: exportVariable multiple backslash problem +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +............ + +Time: %s, Memory: %s + +OK (12 tests, 12 assertions) diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/Issue1335Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/Issue1335Test.php new file mode 100644 index 000000000..4407ec8df --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/Issue1335Test.php @@ -0,0 +1,67 @@ +assertEquals('Hello', $GLOBALS['globalString']); + } + + public function testGlobalIntTruthy() + { + $this->assertEquals(1, $GLOBALS['globalIntTruthy']); + } + + public function testGlobalIntFalsey() + { + $this->assertEquals(0, $GLOBALS['globalIntFalsey']); + } + + public function testGlobalFloat() + { + $this->assertEquals(1.123, $GLOBALS['globalFloat']); + } + + public function testGlobalBoolTrue() + { + $this->assertEquals(true, $GLOBALS['globalBoolTrue']); + } + + public function testGlobalBoolFalse() + { + $this->assertEquals(false, $GLOBALS['globalBoolFalse']); + } + + public function testGlobalNull() + { + $this->assertEquals(null, $GLOBALS['globalNull']); + } + + public function testGlobalArray() + { + $this->assertEquals(array('foo'), $GLOBALS['globalArray']); + } + + public function testGlobalNestedArray() + { + $this->assertEquals(array(array('foo')), $GLOBALS['globalNestedArray']); + } + + public function testGlobalObject() + { + $this->assertEquals((object) array('foo'=> 'bar'), $GLOBALS['globalObject']); + } + + public function testGlobalObjectWithBackSlashString() + { + $this->assertEquals((object) array('foo'=> 'back\\slash'), $GLOBALS['globalObjectWithBackSlashString']); + } + + public function testGlobalObjectWithDoubleBackSlashString() + { + $this->assertEquals((object) array('foo'=> 'back\\\\slash'), $GLOBALS['globalObjectWithDoubleBackSlashString']); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/bootstrap1335.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/bootstrap1335.php new file mode 100644 index 000000000..073a87e35 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/bootstrap1335.php @@ -0,0 +1,13 @@ + 'bar'); +$globalObjectWithBackSlashString = (object) array('foo'=> 'back\\slash'); +$globalObjectWithDoubleBackSlashString = (object) array('foo'=> 'back\\\\slash'); diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1337.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1337.phpt new file mode 100644 index 000000000..3c7077e45 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1337.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-1337: Data Provider with \ at the end of the name breaks with process isolation +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 2 assertions) \ No newline at end of file diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1337/Issue1337Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1337/Issue1337Test.php new file mode 100644 index 000000000..b972b2ade --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1337/Issue1337Test.php @@ -0,0 +1,19 @@ +assertTrue($a); + } + + public function dataProvider() + { + return array( + 'c:\\'=> array(true), + 0.9 => array(true) + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1348.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1348.phpt new file mode 100644 index 000000000..a3a721d72 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1348.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-1348: STDOUT/STDERR IO streams should exist in process isolation +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. +STDOUT does not break test result +E + +Time: %s, Memory: %s + +There was 1 error: + +1) Issue1348Test::testSTDERR +PHPUnit_Framework_Exception: STDERR works as usual. + +FAILURES! +Tests: 2, Assertions: 1, Errors: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1348/Issue1348Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1348/Issue1348Test.php new file mode 100644 index 000000000..d3c82f0e8 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1348/Issue1348Test.php @@ -0,0 +1,14 @@ +assertTrue(true); + } + + public function testSTDERR() + { + fwrite(STDERR, 'STDERR works as usual.'); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1351.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351.phpt new file mode 100644 index 000000000..c13c4220c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351.phpt @@ -0,0 +1,48 @@ +--TEST-- +GH-1351: Test result does not serialize test class in process isolation +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +F.E.E + +Time: %s, Memory: %s + +There were 2 errors: + +1) Issue1351Test::testExceptionPre +RuntimeException: Expected rethrown exception. +%A +Caused by +LogicException: Expected exception. +%A + +2) Issue1351Test::testPhpCoreLanguageException +PDOException: SQLSTATE[HY000]: General error: 1 no such table: php_wtf +%A + +-- + +There was 1 failure: + +1) Issue1351Test::testFailurePre +Expected failure. +%A +FAILURES! +Tests: 5, Assertions: 5, Errors: 2, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/ChildProcessClass1351.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/ChildProcessClass1351.php new file mode 100644 index 000000000..24c053766 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/ChildProcessClass1351.php @@ -0,0 +1,4 @@ +instance = new ChildProcessClass1351(); + $this->assertFalse(true, 'Expected failure.'); + } + + public function testFailurePost() + { + $this->assertNull($this->instance); + $this->assertFalse(class_exists('ChildProcessClass1351', false), 'ChildProcessClass1351 is not loaded.'); + } + + /** + * @runInSeparateProcess + */ + public function testExceptionPre() + { + $this->instance = new ChildProcessClass1351(); + try { + throw new LogicException('Expected exception.'); + } catch (LogicException $e) { + throw new RuntimeException('Expected rethrown exception.', 0, $e); + } + } + + public function testExceptionPost() + { + $this->assertNull($this->instance); + $this->assertFalse(class_exists('ChildProcessClass1351', false), 'ChildProcessClass1351 is not loaded.'); + } + + public function testPhpCoreLanguageException() + { + // User-space code cannot instantiate a PDOException with a string code, + // so trigger a real one. + $connection = new PDO('sqlite::memory:'); + $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $connection->query("DELETE FROM php_wtf WHERE exception_code = 'STRING'"); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1374.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1374.phpt new file mode 100644 index 000000000..473e01fff --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1374.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-1374: tearDown() is called despite unmet requirements +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +S + +Time: %s, Memory: %s + +OK, but incomplete, skipped, or risky tests! +Tests: 1, Assertions: 0, Skipped: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1374/Issue1374Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1374/Issue1374Test.php new file mode 100644 index 000000000..ad6a3bf09 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1374/Issue1374Test.php @@ -0,0 +1,21 @@ +fail('This should not be reached'); + } + + protected function tearDown() + { + print __FUNCTION__; + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1437.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1437.phpt new file mode 100644 index 000000000..b7064c585 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1437.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-1437: Risky test messages mask failures +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Issue1437Test::testFailure +Failed asserting that false is true. + +%sIssue1437Test.php:%i + +FAILURES! +Tests: 1, Assertions: 1, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1437/Issue1437Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1437/Issue1437Test.php new file mode 100644 index 000000000..bff4b205a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1437/Issue1437Test.php @@ -0,0 +1,9 @@ +assertTrue(false); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1468.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1468.phpt new file mode 100644 index 000000000..7b46ca97d --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1468.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-1468: Incomplete and @todo annotated tests are counted twice +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +I + +Time: %s, Memory: %s + +OK, but incomplete, skipped, or risky tests! +Tests: 1, Assertions: 0, Incomplete: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1468/Issue1468Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1468/Issue1468Test.php new file mode 100644 index 000000000..535b25b99 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1468/Issue1468Test.php @@ -0,0 +1,11 @@ +markTestIncomplete(); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1471.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1471.phpt new file mode 100644 index 000000000..20886823e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1471.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-1471: Output made while test is running is printed although expectOutputString() is used when an assertion fails +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Issue1471Test::testFailure +Failed asserting that false is true. + +%s/Issue1471Test.php:10 + +FAILURES! +Tests: 1, Assertions: 1, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1471/Issue1471Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1471/Issue1471Test.php new file mode 100644 index 000000000..28f127485 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1471/Issue1471Test.php @@ -0,0 +1,12 @@ +expectOutputString('*'); + + print '*'; + + $this->assertTrue(false); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1472.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1472.phpt new file mode 100644 index 000000000..0958eb358 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1472.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-1472: assertEqualXMLStructure modifies the tested elements +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 4 assertions) diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1472/Issue1472Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1472/Issue1472Test.php new file mode 100644 index 000000000..a392773a9 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1472/Issue1472Test.php @@ -0,0 +1,21 @@ +loadXML(''); + + $xpath = new DOMXPath($doc); + + $labelElement = $doc->getElementsByTagName('label')->item(0); + + $this->assertEquals(1, $xpath->evaluate('count(//label[text() = "text content"])')); + + $expectedElmt = $doc->createElement('label', 'text content'); + $this->assertEqualXMLStructure($expectedElmt, $labelElement); + + // the following assertion fails, even though it passed before - which is due to the assertEqualXMLStructure() has modified the $labelElement + $this->assertEquals(1, $xpath->evaluate('count(//label[text() = "text content"])')); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1570.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1570.phpt new file mode 100644 index 000000000..553c6448d --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1570.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-1570: Test that prints output is marked as failure and not as risky when --disallow-test-output is used +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +R* + +Time: %s, Memory: %s + +OK, but incomplete, skipped, or risky tests! +Tests: 1, Assertions: 0, Risky: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1570/Issue1570Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1570/Issue1570Test.php new file mode 100644 index 000000000..014850669 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1570/Issue1570Test.php @@ -0,0 +1,8 @@ + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +%s + +Time: %s, Memory: %s + +OK (2 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/Issue2158Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/Issue2158Test.php new file mode 100644 index 000000000..014aa4f62 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/Issue2158Test.php @@ -0,0 +1,23 @@ +assertTrue(true); + } + + /** + * Constant defined previously in main process constant should be available and + * no errors should be yielded by reload of included files + * + * @runInSeparateProcess + */ + public function testSomethingElse() + { + $this->assertTrue(defined('TEST_CONSTANT')); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/constant.inc b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/constant.inc new file mode 100644 index 000000000..4137114fd --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/constant.inc @@ -0,0 +1,5 @@ + diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/244.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/244.phpt new file mode 100644 index 000000000..b517e5c0a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/244.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-244: Expected Exception should support string codes +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.FFF + +Time: %s, Memory: %s + +There were 3 failures: + +1) Issue244Test::testFails +Failed asserting that '123StringCode' is equal to expected exception code 'OtherString'. + +2) Issue244Test::testFailsTooIfExpectationIsANumber +Failed asserting that '123StringCode' is equal to expected exception code 123. + +3) Issue244Test::testFailsTooIfExceptionCodeIsANumber +Failed asserting that 123 is equal to expected exception code '123String'. + +FAILURES! +Tests: 4, Assertions: 8, Failures: 3. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/244/Issue244Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/244/Issue244Test.php new file mode 100644 index 000000000..621c4cf54 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/244/Issue244Test.php @@ -0,0 +1,55 @@ +code = '123StringCode'; + } +} + +class Issue244ExceptionIntCode extends Exception +{ + public function __construct() + { + $this->code = 123; + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/322.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/322.phpt new file mode 100644 index 000000000..0974a706e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/322.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-322: group commandline option should override group/exclude setting in phpunit.xml +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + + +Starting test 'Issue322Test::testOne'. +. + +Time: %s, Memory: %s + +OK (1 test, 0 assertions) diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/322/Issue322Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/322/Issue322Test.php new file mode 100644 index 000000000..618bcaa19 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/322/Issue322Test.php @@ -0,0 +1,17 @@ + + + Test.php + + + + + one + + + diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/433.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/433.phpt new file mode 100644 index 000000000..df6c6f8ec --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/433.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-433: expectOutputString not completely working as expected +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +..F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Issue433Test::testNotMatchingOutput +Failed asserting that two strings are equal. +--- Expected ++++ Actual +@@ @@ +-'foo' ++'bar' + +FAILURES! +Tests: 3, Assertions: 3, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/433/Issue433Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/433/Issue433Test.php new file mode 100644 index 000000000..e0a91b35b --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/433/Issue433Test.php @@ -0,0 +1,21 @@ +expectOutputString('test'); + print 'test'; + } + + public function testOutputWithExpectationAfter() + { + print 'test'; + $this->expectOutputString('test'); + } + + public function testNotMatchingOutput() + { + print 'bar'; + $this->expectOutputString('foo'); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/445.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/445.phpt new file mode 100644 index 000000000..c0183f9e9 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/445.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-455: expectOutputString not working in strict mode +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +..F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Issue445Test::testNotMatchingOutput +Failed asserting that two strings are equal. +--- Expected ++++ Actual +@@ @@ +-'foo' ++'bar' + +FAILURES! +Tests: 3, Assertions: 3, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/445/Issue445Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/445/Issue445Test.php new file mode 100644 index 000000000..c3090259e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/445/Issue445Test.php @@ -0,0 +1,21 @@ +expectOutputString('test'); + print 'test'; + } + + public function testOutputWithExpectationAfter() + { + print 'test'; + $this->expectOutputString('test'); + } + + public function testNotMatchingOutput() + { + print 'bar'; + $this->expectOutputString('foo'); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/498.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/498.phpt new file mode 100644 index 000000000..4f8508e1c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/498.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-498: The test methods won't be run if a dataProvider throws Exception and --group is added in command line +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Warning +The data provider specified for Issue498Test::shouldBeFalse is invalid. +Can't create the data + +FAILURES! +Tests: 1, Assertions: 0, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/498/Issue498Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/498/Issue498Test.php new file mode 100644 index 000000000..49fa76454 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/498/Issue498Test.php @@ -0,0 +1,44 @@ +assertTrue(true); + } + + /** + * @test + * @dataProvider shouldBeFalseDataProvider + * @group trueOnly + */ + public function shouldBeFalse($testData) + { + $this->assertFalse(false); + } + + public function shouldBeTrueDataProvider() + { + + //throw new Exception("Can't create the data"); + return array( + array(true), + array(false) + ); + } + + public function shouldBeFalseDataProvider() + { + throw new Exception("Can't create the data"); + + return array( + array(true), + array(false) + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/503.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/503.phpt new file mode 100644 index 000000000..c9dbd5649 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/503.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-503: assertEquals() Line Ending Differences Are Obscure +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Issue503Test::testCompareDifferentLineEndings +Failed asserting that two strings are identical. +--- Expected ++++ Actual +@@ @@ + #Warning: Strings contain different line endings! + foo + +%s:%i + +FAILURES! +Tests: 1, Assertions: 1, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/503/Issue503Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/503/Issue503Test.php new file mode 100644 index 000000000..75ca8d454 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/503/Issue503Test.php @@ -0,0 +1,11 @@ +assertSame( + "foo\n", + "foo\r\n" + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/581.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/581.phpt new file mode 100644 index 000000000..96ad88a9e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/581.phpt @@ -0,0 +1,42 @@ +--TEST-- +GH-581: PHPUnit_Util_Type::export adds extra newlines in Windows +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Issue581Test::testExportingObjectsDoesNotBreakWindowsLineFeeds +Failed asserting that two objects are equal. +--- Expected ++++ Actual +@@ @@ + stdClass Object ( + 0 => 1 + 1 => 2 + 2 => 'Test\n' + 3 => 4 +- 4 => 5 ++ 4 => 1 + 5 => 6 + 6 => 7 + 7 => 8 + ) + +%s:%i + +FAILURES! +Tests: 1, Assertions: 1, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/581/Issue581Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/581/Issue581Test.php new file mode 100644 index 000000000..51de83b18 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/581/Issue581Test.php @@ -0,0 +1,11 @@ +assertEquals( + (object) array(1, 2, "Test\r\n", 4, 5, 6, 7, 8), + (object) array(1, 2, "Test\r\n", 4, 1, 6, 7, 8) + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/74.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/74.phpt new file mode 100644 index 000000000..2f54d2682 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/74.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-74: catchable fatal error in 3.5 +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +E + +Time: %s, Memory: %s + +There was 1 error: + +1) Issue74Test::testCreateAndThrowNewExceptionInProcessIsolation +NewException: Testing GH-74 + +%sIssue74Test.php:7 + +FAILURES! +Tests: 1, Assertions: 0, Errors: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/74/Issue74Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/74/Issue74Test.php new file mode 100644 index 000000000..72f35928a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/74/Issue74Test.php @@ -0,0 +1,9 @@ + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Warning +The data provider specified for Issue765Test::testDependent is invalid. + +FAILURES! +Tests: 2, Assertions: 1, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/765/Issue765Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/765/Issue765Test.php new file mode 100644 index 000000000..a47474b27 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/765/Issue765Test.php @@ -0,0 +1,22 @@ +assertTrue(true); + } + + /** + * @depends testDependee + * @dataProvider dependentProvider + */ + public function testDependent($a) + { + $this->assertTrue(true); + } + + public function dependentProvider() + { + throw new Exception; + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/797.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/797.phpt new file mode 100644 index 000000000..8be21eb63 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/797.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-797: Disabled $preserveGlobalState does not load bootstrap.php. +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) \ No newline at end of file diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/797/Issue797Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/797/Issue797Test.php new file mode 100644 index 000000000..b1c1b8f92 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/797/Issue797Test.php @@ -0,0 +1,10 @@ +assertEquals(GITHUB_ISSUE, 797); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/797/bootstrap797.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/797/bootstrap797.php new file mode 100644 index 000000000..03890a35a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/797/bootstrap797.php @@ -0,0 +1,6 @@ + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +............................................................... 63 / 150 ( 42%) +............................................................... 126 / 150 ( 84%) +........................ + +Time: %s, Memory: %s + +OK (150 tests, 150 assertions) diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php5.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php5.phpt new file mode 100644 index 000000000..89b740235 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php5.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-873: PHPUnit suppresses exceptions thrown outside of test case function +--SKIPIF-- + 5) { + print 'skip: PHP 5 is required'; +} +?> +--FILE-- + +--EXPECTF-- + +Fatal error: Uncaught exception 'Exception' with message 'PHPUnit suppresses exceptions thrown outside of test case function' in %s:%i +Stack trace: +%a diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php7.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php7.phpt new file mode 100644 index 000000000..b022f9976 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php7.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-873: PHPUnit suppresses exceptions thrown outside of test case function +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Fatal error: Uncaught Exception: PHPUnit suppresses exceptions thrown outside of test case function in %s:%i +Stack trace: +%a diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/873/Issue873Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/873/Issue873Test.php new file mode 100644 index 000000000..70fd90464 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/873/Issue873Test.php @@ -0,0 +1,9 @@ + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/1021/Issue1021Test.php b/vendor/phpunit/phpunit/tests/Regression/Trac/1021/Issue1021Test.php new file mode 100644 index 000000000..5814e94c3 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/1021/Issue1021Test.php @@ -0,0 +1,23 @@ +assertTrue($data); + } + + /** + * @depends testSomething + */ + public function testSomethingElse() + { + } + + public function provider() + { + return array(array(true)); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/523.phpt b/vendor/phpunit/phpunit/tests/Regression/Trac/523.phpt new file mode 100644 index 000000000..c182a9870 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/523.phpt @@ -0,0 +1,19 @@ +--TEST-- +#523: assertAttributeEquals does not work with classes extending ArrayIterator +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/523/Issue523Test.php b/vendor/phpunit/phpunit/tests/Regression/Trac/523/Issue523Test.php new file mode 100644 index 000000000..80124f1da --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/523/Issue523Test.php @@ -0,0 +1,13 @@ +assertAttributeEquals('foo', 'field', new Issue523()); + } +}; + +class Issue523 extends ArrayIterator +{ + protected $field = 'foo'; +} diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/578.phpt b/vendor/phpunit/phpunit/tests/Regression/Trac/578.phpt new file mode 100644 index 000000000..27ea9f1f3 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/578.phpt @@ -0,0 +1,37 @@ +--TEST-- +#578: Double printing of trace line for exceptions from notices and warnings +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +EEE + +Time: %s, Memory: %s + +There were 3 errors: + +1) Issue578Test::testNoticesDoublePrintStackTrace +Invalid error type specified + +%sIssue578Test.php:%i + +2) Issue578Test::testWarningsDoublePrintStackTrace +Invalid error type specified + +%sIssue578Test.php:%i + +3) Issue578Test::testUnexpectedExceptionsPrintsCorrectly +Exception: Double printed exception + +%sIssue578Test.php:%i + +FAILURES! +Tests: 3, Assertions: 0, Errors: 3. diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/578/Issue578Test.php b/vendor/phpunit/phpunit/tests/Regression/Trac/578/Issue578Test.php new file mode 100644 index 000000000..262d97f64 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/578/Issue578Test.php @@ -0,0 +1,20 @@ +iniSet('error_reporting', E_ALL | E_NOTICE); + trigger_error('Stack Trace Test Notice', E_NOTICE); + } + + public function testWarningsDoublePrintStackTrace() + { + $this->iniSet('error_reporting', E_ALL | E_NOTICE); + trigger_error('Stack Trace Test Notice', E_WARNING); + } + + public function testUnexpectedExceptionsPrintsCorrectly() + { + throw new Exception('Double printed exception'); + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/684.phpt b/vendor/phpunit/phpunit/tests/Regression/Trac/684.phpt new file mode 100644 index 000000000..da51508d1 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/684.phpt @@ -0,0 +1,25 @@ +--TEST-- +#684: Unable to find test class when no test methods exists +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Warning +No tests found in class "Foo_Bar_Issue684Test". + +FAILURES! +Tests: 1, Assertions: 0, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/684/Issue684Test.php b/vendor/phpunit/phpunit/tests/Regression/Trac/684/Issue684Test.php new file mode 100644 index 000000000..e8e5d87ec --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/684/Issue684Test.php @@ -0,0 +1,4 @@ + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 0 assertions) diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/783/ChildSuite.php b/vendor/phpunit/phpunit/tests/Regression/Trac/783/ChildSuite.php new file mode 100644 index 000000000..8bac5144b --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/783/ChildSuite.php @@ -0,0 +1,15 @@ +addTestSuite('OneTest'); + $suite->addTestSuite('TwoTest'); + + return $suite; + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/783/OneTest.php b/vendor/phpunit/phpunit/tests/Regression/Trac/783/OneTest.php new file mode 100644 index 000000000..71951582e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/783/OneTest.php @@ -0,0 +1,10 @@ +addTest(ChildSuite::suite()); + + return $suite; + } +} diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/783/TwoTest.php b/vendor/phpunit/phpunit/tests/Regression/Trac/783/TwoTest.php new file mode 100644 index 000000000..580246ce9 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Regression/Trac/783/TwoTest.php @@ -0,0 +1,10 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 2.0.0 + * @covers PHPUnit_Runner_BaseTestRunner + */ +class Runner_BaseTestRunnerTest extends PHPUnit_Framework_TestCase +{ + public function testInvokeNonStaticSuite() + { + $runner = new MockRunner; + $runner->getTest('NonStatic'); + } +} diff --git a/vendor/phpunit/phpunit/tests/TextUI/abstract-test-class.phpt b/vendor/phpunit/phpunit/tests/TextUI/abstract-test-class.phpt new file mode 100644 index 000000000..e26a80c79 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/abstract-test-class.phpt @@ -0,0 +1,25 @@ +--TEST-- +phpunit AbstractTest ../_files/AbstractTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Warning +Cannot instantiate class "AbstractTest". + +FAILURES! +Tests: 1, Assertions: 0, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/TextUI/colors-always.phpt b/vendor/phpunit/phpunit/tests/TextUI/colors-always.phpt new file mode 100644 index 000000000..0e0ac1ed0 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/colors-always.phpt @@ -0,0 +1,19 @@ +--TEST-- +phpunit --colors=always BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +%s[30;42mOK (3 tests, 3 assertions)%s[0m diff --git a/vendor/phpunit/phpunit/tests/TextUI/concrete-test-class.phpt b/vendor/phpunit/phpunit/tests/TextUI/concrete-test-class.phpt new file mode 100644 index 000000000..445c01c4a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/concrete-test-class.phpt @@ -0,0 +1,19 @@ +--TEST-- +phpunit ConcreteTest ../_files/ConcreteTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 0 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/custom-printer-debug.phpt b/vendor/phpunit/phpunit/tests/TextUI/custom-printer-debug.phpt new file mode 100644 index 000000000..81e4ae061 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/custom-printer-debug.phpt @@ -0,0 +1,27 @@ +--TEST-- +phpunit -c ../_files/configuration.custom-printer.xml --debug BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + + +Starting test 'BankAccountTest::testBalanceIsInitiallyZero'. +. +Starting test 'BankAccountTest::testBalanceCannotBecomeNegative'. +. +Starting test 'BankAccountTest::testBalanceCannotBecomeNegative2'. +. + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/custom-printer-verbose.phpt b/vendor/phpunit/phpunit/tests/TextUI/custom-printer-verbose.phpt new file mode 100644 index 000000000..2255a6ee7 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/custom-printer-verbose.phpt @@ -0,0 +1,32 @@ +--TEST-- +phpunit -c ../_files/configuration.custom-printer.xml --verbose IncompleteTest ../_files/IncompleteTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Runtime: %s +Configuration: %sconfiguration.custom-printer.xml + +I + +Time: %s, Memory: %s + +There was 1 incomplete test: + +1) IncompleteTest::testIncomplete +Test incomplete + +%s + +OK, but incomplete, skipped, or risky tests! +Tests: 1, Assertions: 0, Incomplete: 1. diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-debug.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-debug.phpt new file mode 100644 index 000000000..e95136f2a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-debug.phpt @@ -0,0 +1,34 @@ +--TEST-- +phpunit --debug DataProviderDebugTest ../_files/DataProviderDebugTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + + +Starting test 'DataProviderDebugTest::testProvider with data set #0 (null, true, 1, 1.0)'. +. +Starting test 'DataProviderDebugTest::testProvider with data set #1 (1.2, resource(%d) of type (stream), '1')'. +. +Starting test 'DataProviderDebugTest::testProvider with data set #2 (array(array(1, 2, 3), array(3, 4, 5)))'. +. +Starting test 'DataProviderDebugTest::testProvider with data set #3 ('this\nis\na\nvery\nvery\nvery\nvery...g\ntext')'. +. +Starting test 'DataProviderDebugTest::testProvider with data set #4 (stdClass Object (), stdClass Object (...), array(), SplObjectStorage Object (...), stdClass Object (...))'. +. +Starting test 'DataProviderDebugTest::testProvider with data set #5 (Binary String: 0x000102030405, Binary String: 0x0e0f101112131...c1d1e1f)'. +. +Starting test 'DataProviderDebugTest::testProvider with data set #6 (Binary String: 0x0009)'. +. + +Time: %s, Memory: %s + +OK (7 tests, 7 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml-isolation.phpt new file mode 100644 index 000000000..0e70df802 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml-isolation.phpt @@ -0,0 +1,47 @@ +--TEST-- +phpunit --process-isolation --log-junit php://stdout DataProviderTest ../_files/DataProviderTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +..F. + + + + + + + DataProviderTest::testAdd with data set #2 (1, 1, 3) +Failed asserting that 2 matches expected 3. + +%s:%i + + + + + + + + +Time: %s, Memory: %s + +There was 1 failure: + +1) DataProviderTest::testAdd with data set #2 (1, 1, 3) +Failed asserting that 2 matches expected 3. + +%s:%i + +FAILURES! +Tests: 4, Assertions: 4, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml.phpt new file mode 100644 index 000000000..f6ca5d169 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml.phpt @@ -0,0 +1,46 @@ +--TEST-- +phpunit --log-junit php://stdout DataProviderTest ../_files/DataProviderTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +..F. + + + + + + + DataProviderTest::testAdd with data set #2 (1, 1, 3) +Failed asserting that 2 matches expected 3. + +%s:%i + + + + + + + + +Time: %s, Memory: %s + +There was 1 failure: + +1) DataProviderTest::testAdd with data set #2 (1, 1, 3) +Failed asserting that 2 matches expected 3. + +%s:%i + +FAILURES! +Tests: 4, Assertions: 4, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-testdox.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-testdox.phpt new file mode 100644 index 000000000..75973feaa --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-testdox.phpt @@ -0,0 +1,17 @@ +--TEST-- +phpunit --testdox DataProviderTest ../_files/DataProviderTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +DataProvider + [ ] Add diff --git a/vendor/phpunit/phpunit/tests/TextUI/debug.phpt b/vendor/phpunit/phpunit/tests/TextUI/debug.phpt new file mode 100644 index 000000000..0829197c1 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/debug.phpt @@ -0,0 +1,26 @@ +--TEST-- +phpunit --debug BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + + +Starting test 'BankAccountTest::testBalanceIsInitiallyZero'. +. +Starting test 'BankAccountTest::testBalanceCannotBecomeNegative'. +. +Starting test 'BankAccountTest::testBalanceCannotBecomeNegative2'. +. + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/default-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/default-isolation.phpt new file mode 100644 index 000000000..cca8bc81e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/default-isolation.phpt @@ -0,0 +1,20 @@ +--TEST-- +phpunit --process-isolation BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/default.phpt b/vendor/phpunit/phpunit/tests/TextUI/default.phpt new file mode 100644 index 000000000..bd7615b2d --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/default.phpt @@ -0,0 +1,19 @@ +--TEST-- +phpunit BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies-isolation.phpt new file mode 100644 index 000000000..6d2a5b352 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies-isolation.phpt @@ -0,0 +1,40 @@ +--TEST-- +phpunit --process-isolation --verbose DependencyTestSuite ../_files/DependencyTestSuite.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Runtime: %s + +...FSS + +Time: %s, Memory: %s + +There was 1 failure: + +1) DependencyFailureTest::testOne + +%s:%i + +-- + +There were 2 skipped tests: + +1) DependencyFailureTest::testTwo +This test depends on "DependencyFailureTest::testOne" to pass. + +2) DependencyFailureTest::testThree +This test depends on "DependencyFailureTest::testTwo" to pass. + +FAILURES! +Tests: 4, Assertions: 0, Failures: 1, Skipped: 2. diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies.phpt new file mode 100644 index 000000000..f32d10a51 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies.phpt @@ -0,0 +1,39 @@ +--TEST-- +phpunit --verbose DependencyTestSuite ../_files/DependencyTestSuite.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Runtime: %s + +...FSS + +Time: %s, Memory: %s + +There was 1 failure: + +1) DependencyFailureTest::testOne + +%s:%i + +-- + +There were 2 skipped tests: + +1) DependencyFailureTest::testTwo +This test depends on "DependencyFailureTest::testOne" to pass. + +2) DependencyFailureTest::testThree +This test depends on "DependencyFailureTest::testTwo" to pass. + +FAILURES! +Tests: 4, Assertions: 0, Failures: 1, Skipped: 2. diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies2-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies2-isolation.phpt new file mode 100644 index 000000000..5e7ef8fee --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies2-isolation.phpt @@ -0,0 +1,20 @@ +--TEST-- +phpunit --process-isolation StackTest ../_files/StackTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 5 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies2.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies2.phpt new file mode 100644 index 000000000..a30dd4e22 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies2.phpt @@ -0,0 +1,19 @@ +--TEST-- +phpunit StackTest ../_files/StackTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 5 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies3-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies3-isolation.phpt new file mode 100644 index 000000000..51d448c26 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies3-isolation.phpt @@ -0,0 +1,20 @@ +--TEST-- +phpunit --process-isolation MultiDependencyTest ../_files/MultiDependencyTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies3.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies3.phpt new file mode 100644 index 000000000..218620d6d --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies3.phpt @@ -0,0 +1,19 @@ +--TEST-- +phpunit MultiDependencyTest ../_files/MultiDependencyTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/empty-testcase.phpt b/vendor/phpunit/phpunit/tests/TextUI/empty-testcase.phpt new file mode 100644 index 000000000..0d0eccb5b --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/empty-testcase.phpt @@ -0,0 +1,25 @@ +--TEST-- +phpunit EmptyTestCaseTest ../_files/EmptyTestCaseTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +F + +Time: %s, Memory: %s + +There was 1 failure: + +1) Warning +No tests found in class "EmptyTestCaseTest". + +FAILURES! +Tests: 1, Assertions: 0, Failures: 1. diff --git a/vendor/phpunit/phpunit/tests/TextUI/exception-stack.phpt b/vendor/phpunit/phpunit/tests/TextUI/exception-stack.phpt new file mode 100644 index 000000000..823ef1bd5 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/exception-stack.phpt @@ -0,0 +1,65 @@ +--TEST-- +phpunit ExceptionStackTest ../_files/ExceptionStackTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +EE + +Time: %s, Memory: %s + +There were 2 errors: + +1) ExceptionStackTest::testPrintingChildException +PHPUnit_Framework_Exception: Child exception +message +Failed asserting that two arrays are equal. +--- Expected ++++ Actual +@@ @@ + Array ( +- 0 => 1 ++ 0 => 2 + ) + + +%s:%i + +Caused by +message +Failed asserting that two arrays are equal. +--- Expected ++++ Actual +@@ @@ + Array ( +- 0 => 1 ++ 0 => 2 + ) + +%s:%i + +2) ExceptionStackTest::testNestedExceptions +Exception: One + +%s:%i + +Caused by +InvalidArgumentException: Two + +%s:%i + +Caused by +Exception: Three + +%s:%i + +FAILURES! +Tests: 2, Assertions: 1, Errors: 2. diff --git a/vendor/phpunit/phpunit/tests/TextUI/exclude-group-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/exclude-group-isolation.phpt new file mode 100644 index 000000000..b9afb6b75 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/exclude-group-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --exclude-group balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/exclude-group.phpt b/vendor/phpunit/phpunit/tests/TextUI/exclude-group.phpt new file mode 100644 index 000000000..dcbc5d3db --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/exclude-group.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --exclude-group balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/failure-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/failure-isolation.phpt new file mode 100644 index 000000000..a0c9906ae --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/failure-isolation.phpt @@ -0,0 +1,142 @@ +--TEST-- +phpunit --process-isolation FailureTest ../_files/FailureTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +FFFFFFFFFFFFF + +Time: %s, Memory: %s + +There were 13 failures: + +1) FailureTest::testAssertArrayEqualsArray +message +Failed asserting that two arrays are equal. +--- Expected ++++ Actual +@@ @@ + Array ( +- 0 => 1 ++ 0 => 2 + ) + +%s:%i + +2) FailureTest::testAssertIntegerEqualsInteger +message +Failed asserting that 2 matches expected 1. + +%s:%i + +3) FailureTest::testAssertObjectEqualsObject +message +Failed asserting that two objects are equal. +--- Expected ++++ Actual +@@ @@ + stdClass Object ( +- 'foo' => 'bar' ++ 'bar' => 'foo' + ) + +%s:%i + +4) FailureTest::testAssertNullEqualsString +message +Failed asserting that 'bar' matches expected null. + +%s:%i + +5) FailureTest::testAssertStringEqualsString +message +Failed asserting that two strings are equal. +--- Expected ++++ Actual +@@ @@ +-'foo' ++'bar' + +%s:%i + +6) FailureTest::testAssertTextEqualsText +message +Failed asserting that two strings are equal. +--- Expected ++++ Actual +@@ @@ + 'foo +-bar ++baz + ' + +%s:%i + +7) FailureTest::testAssertStringMatchesFormat +message +Failed asserting that format description matches text. +--- Expected ++++ Actual +@@ @@ +-*%s* ++** + +%s:%i + +8) FailureTest::testAssertNumericEqualsNumeric +message +Failed asserting that 2 matches expected 1. + +%s:%i + +9) FailureTest::testAssertTextSameText +message +Failed asserting that two strings are identical. +--- Expected ++++ Actual +@@ @@ +-foo ++bar + +%s:%i + +10) FailureTest::testAssertObjectSameObject +message +Failed asserting that two variables reference the same object. + +%s:%i + +11) FailureTest::testAssertObjectSameNull +message +Failed asserting that null is identical to an object of class "stdClass". + +%s:%i + +12) FailureTest::testAssertFloatSameFloat +message +Failed asserting that 1.5 is identical to 1.0. + +%s:%i + +13) FailureTest::testAssertStringMatchesFormatFile +Failed asserting that format description matches text. +--- Expected ++++ Actual +@@ @@ +-FOO +- ++...BAR... + +%s:%i + +FAILURES! +Tests: 13, Assertions: 14, Failures: 13. diff --git a/vendor/phpunit/phpunit/tests/TextUI/failure.phpt b/vendor/phpunit/phpunit/tests/TextUI/failure.phpt new file mode 100644 index 000000000..30ce30314 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/failure.phpt @@ -0,0 +1,141 @@ +--TEST-- +phpunit FailureTest ../_files/FailureTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +FFFFFFFFFFFFF + +Time: %s, Memory: %s + +There were 13 failures: + +1) FailureTest::testAssertArrayEqualsArray +message +Failed asserting that two arrays are equal. +--- Expected ++++ Actual +@@ @@ + Array ( +- 0 => 1 ++ 0 => 2 + ) + +%s:%i + +2) FailureTest::testAssertIntegerEqualsInteger +message +Failed asserting that 2 matches expected 1. + +%s:%i + +3) FailureTest::testAssertObjectEqualsObject +message +Failed asserting that two objects are equal. +--- Expected ++++ Actual +@@ @@ + stdClass Object ( +- 'foo' => 'bar' ++ 'bar' => 'foo' + ) + +%s:%i + +4) FailureTest::testAssertNullEqualsString +message +Failed asserting that 'bar' matches expected null. + +%s:%i + +5) FailureTest::testAssertStringEqualsString +message +Failed asserting that two strings are equal. +--- Expected ++++ Actual +@@ @@ +-'foo' ++'bar' + +%s:%i + +6) FailureTest::testAssertTextEqualsText +message +Failed asserting that two strings are equal. +--- Expected ++++ Actual +@@ @@ + 'foo +-bar ++baz + ' + +%s:%i + +7) FailureTest::testAssertStringMatchesFormat +message +Failed asserting that format description matches text. +--- Expected ++++ Actual +@@ @@ +-*%s* ++** + +%s:%i + +8) FailureTest::testAssertNumericEqualsNumeric +message +Failed asserting that 2 matches expected 1. + +%s:%i + +9) FailureTest::testAssertTextSameText +message +Failed asserting that two strings are identical. +--- Expected ++++ Actual +@@ @@ +-foo ++bar + +%s:%i + +10) FailureTest::testAssertObjectSameObject +message +Failed asserting that two variables reference the same object. + +%s:%i + +11) FailureTest::testAssertObjectSameNull +message +Failed asserting that null is identical to an object of class "stdClass". + +%s:%i + +12) FailureTest::testAssertFloatSameFloat +message +Failed asserting that 1.5 is identical to 1.0. + +%s:%i + +13) FailureTest::testAssertStringMatchesFormatFile +Failed asserting that format description matches text. +--- Expected ++++ Actual +@@ @@ +-FOO +- ++...BAR... + +%s:%i + +FAILURES! +Tests: 13, Assertions: 14, Failures: 13. diff --git a/vendor/phpunit/phpunit/tests/TextUI/fatal-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/fatal-isolation.phpt new file mode 100644 index 000000000..95e3f113e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/fatal-isolation.phpt @@ -0,0 +1,26 @@ +--TEST-- +phpunit FatalTest --process-isolation ../_files/FatalTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +E + +Time: %s, Memory: %s + +There was 1 error: + +1) FatalTest::testFatalError +%s + +FAILURES! +Tests: 1, Assertions: 0, Errors: 1. diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-class-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-class-isolation.phpt new file mode 100644 index 000000000..acb2e5d70 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-class-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter BankAccountTest BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-class.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-class.phpt new file mode 100644 index 000000000..97c94da1b --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-class.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter BankAccountTest BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range-isolation.phpt new file mode 100644 index 000000000..630a48a78 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter DataProviderFilterTest#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range.phpt new file mode 100644 index 000000000..2314eb858 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter DataProviderFilterTest#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number-isolation.phpt new file mode 100644 index 000000000..3ff675e4b --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter testTrue#3 DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number.phpt new file mode 100644 index 000000000..bc7beda43 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter testTrue#3 DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range-isolation.phpt new file mode 100644 index 000000000..6aa256767 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter \#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range.phpt new file mode 100644 index 000000000..b3b681c4c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter \#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp-isolation.phpt new file mode 100644 index 000000000..db1516bba --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter @false.* DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp.phpt new file mode 100644 index 000000000..27db60b30 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter @false.* DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string-isolation.phpt new file mode 100644 index 000000000..fca15519d --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter @false\ test DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string.phpt new file mode 100644 index 000000000..00a32d7a0 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter @false\ test DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range-isolation.phpt new file mode 100644 index 000000000..22bacbbe2 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter testTrue#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range.phpt new file mode 100644 index 000000000..2a6a55709 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter testTrue#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp-isolation.phpt new file mode 100644 index 000000000..8126802c0 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter testFalse@false.* DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp.phpt new file mode 100644 index 000000000..17ad71837 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter testFalse@false.* DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.. + +Time: %s, Memory: %s + +OK (2 tests, 2 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string-isolation.phpt new file mode 100644 index 000000000..db34b62be --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter testFalse@false\ test DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string.phpt new file mode 100644 index 000000000..79878e9b5 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter testFalse@false\ test DataProviderFilterTest ../_files/DataProviderFilterTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-insensitive.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-insensitive.phpt new file mode 100644 index 000000000..4f5104212 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-insensitive.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter /balanceIsInitiallyZero/i BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-sensitive-no-result.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-sensitive-no-result.phpt new file mode 100644 index 000000000..454d116d0 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-sensitive-no-result.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + + + +Time: %s, Memory: %s + +No tests executed! diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-method-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-method-isolation.phpt new file mode 100644 index 000000000..c9fa6e54c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-method-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --filter testBalanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-method.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-method.phpt new file mode 100644 index 000000000..95fd598af --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-method.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter testBalanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-no-results.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-no-results.phpt new file mode 100644 index 000000000..bb1e6d378 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/filter-no-results.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --filter doesNotExist BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + + + +Time: %s, Memory: %s + +No tests executed! diff --git a/vendor/phpunit/phpunit/tests/TextUI/group-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/group-isolation.phpt new file mode 100644 index 000000000..7e74c6f9a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/group-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation --group balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/group.phpt b/vendor/phpunit/phpunit/tests/TextUI/group.phpt new file mode 100644 index 000000000..be1239347 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/group.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --group balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/help.phpt b/vendor/phpunit/phpunit/tests/TextUI/help.phpt new file mode 100644 index 000000000..8022c47f8 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/help.phpt @@ -0,0 +1,87 @@ +--TEST-- +phpunit +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Usage: phpunit [options] UnitTest [UnitTest.php] + phpunit [options] + +Code Coverage Options: + + --coverage-clover Generate code coverage report in Clover XML format. + --coverage-crap4j Generate code coverage report in Crap4J XML format. + --coverage-html Generate code coverage report in HTML format. + --coverage-php Export PHP_CodeCoverage object to file. + --coverage-text= Generate code coverage report in text format. + Default: Standard output. + --coverage-xml Generate code coverage report in PHPUnit XML format. + +Logging Options: + + --log-junit Log test execution in JUnit XML format to file. + --log-tap Log test execution in TAP format to file. + --log-json Log test execution in JSON format. + --testdox-html Write agile documentation in HTML format to file. + --testdox-text Write agile documentation in Text format to file. + +Test Selection Options: + + --filter Filter which tests to run. + --testsuite Filter which testsuite to run. + --group ... Only runs tests from the specified group(s). + --exclude-group ... Exclude tests from the specified group(s). + --list-groups List available test groups. + --test-suffix ... Only search for test in files with specified + suffix(es). Default: Test.php,.phpt + +Test Execution Options: + + --report-useless-tests Be strict about tests that do not test anything. + --strict-coverage Be strict about unintentionally covered code. + --strict-global-state Be strict about changes to global state + --disallow-test-output Be strict about output during tests. + --enforce-time-limit Enforce time limit based on test size. + --disallow-todo-tests Disallow @todo-annotated tests. + + --process-isolation Run each test in a separate PHP process. + --no-globals-backup Do not backup and restore $GLOBALS for each test. + --static-backup Backup and restore static attributes for each test. + + --colors= Use colors in output ("never", "auto" or "always"). + --columns Number of columns to use for progress output. + --columns max Use maximum number of columns for progress output. + --stderr Write to STDERR instead of STDOUT. + --stop-on-error Stop execution upon first error. + --stop-on-failure Stop execution upon first error or failure. + --stop-on-risky Stop execution upon first risky test. + --stop-on-skipped Stop execution upon first skipped test. + --stop-on-incomplete Stop execution upon first incomplete test. + -v|--verbose Output more verbose information. + --debug Display debugging information during test execution. + + --loader TestSuiteLoader implementation to use. + --repeat Runs the test(s) repeatedly. + --tap Report test execution progress in TAP format. + --testdox Report test execution progress in TestDox format. + --printer TestListener implementation to use. + +Configuration Options: + + --bootstrap A "bootstrap" PHP file that is run before the tests. + -c|--configuration Read configuration from XML file. + --no-configuration Ignore default configuration file (phpunit.xml). + --no-coverage Ignore code coverage configuration. + --include-path Prepend PHP's include_path with given path(s). + -d key[=value] Sets a php.ini value. + +Miscellaneous Options: + + -h|--help Prints this usage information. + --version Prints the version and exits. diff --git a/vendor/phpunit/phpunit/tests/TextUI/help2.phpt b/vendor/phpunit/phpunit/tests/TextUI/help2.phpt new file mode 100644 index 000000000..020f949cb --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/help2.phpt @@ -0,0 +1,88 @@ +--TEST-- +phpunit --help +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Usage: phpunit [options] UnitTest [UnitTest.php] + phpunit [options] + +Code Coverage Options: + + --coverage-clover Generate code coverage report in Clover XML format. + --coverage-crap4j Generate code coverage report in Crap4J XML format. + --coverage-html Generate code coverage report in HTML format. + --coverage-php Export PHP_CodeCoverage object to file. + --coverage-text= Generate code coverage report in text format. + Default: Standard output. + --coverage-xml Generate code coverage report in PHPUnit XML format. + +Logging Options: + + --log-junit Log test execution in JUnit XML format to file. + --log-tap Log test execution in TAP format to file. + --log-json Log test execution in JSON format. + --testdox-html Write agile documentation in HTML format to file. + --testdox-text Write agile documentation in Text format to file. + +Test Selection Options: + + --filter Filter which tests to run. + --testsuite Filter which testsuite to run. + --group ... Only runs tests from the specified group(s). + --exclude-group ... Exclude tests from the specified group(s). + --list-groups List available test groups. + --test-suffix ... Only search for test in files with specified + suffix(es). Default: Test.php,.phpt + +Test Execution Options: + + --report-useless-tests Be strict about tests that do not test anything. + --strict-coverage Be strict about unintentionally covered code. + --strict-global-state Be strict about changes to global state + --disallow-test-output Be strict about output during tests. + --enforce-time-limit Enforce time limit based on test size. + --disallow-todo-tests Disallow @todo-annotated tests. + + --process-isolation Run each test in a separate PHP process. + --no-globals-backup Do not backup and restore $GLOBALS for each test. + --static-backup Backup and restore static attributes for each test. + + --colors= Use colors in output ("never", "auto" or "always"). + --columns Number of columns to use for progress output. + --columns max Use maximum number of columns for progress output. + --stderr Write to STDERR instead of STDOUT. + --stop-on-error Stop execution upon first error. + --stop-on-failure Stop execution upon first error or failure. + --stop-on-risky Stop execution upon first risky test. + --stop-on-skipped Stop execution upon first skipped test. + --stop-on-incomplete Stop execution upon first incomplete test. + -v|--verbose Output more verbose information. + --debug Display debugging information during test execution. + + --loader TestSuiteLoader implementation to use. + --repeat Runs the test(s) repeatedly. + --tap Report test execution progress in TAP format. + --testdox Report test execution progress in TestDox format. + --printer TestListener implementation to use. + +Configuration Options: + + --bootstrap A "bootstrap" PHP file that is run before the tests. + -c|--configuration Read configuration from XML file. + --no-configuration Ignore default configuration file (phpunit.xml). + --no-coverage Ignore code coverage configuration. + --include-path Prepend PHP's include_path with given path(s). + -d key[=value] Sets a php.ini value. + +Miscellaneous Options: + + -h|--help Prints this usage information. + --version Prints the version and exits. diff --git a/vendor/phpunit/phpunit/tests/TextUI/ini-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/ini-isolation.phpt new file mode 100644 index 000000000..76b88ac1f --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/ini-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --process-isolation -d default_mimetype=application/x-test IniTest ../_files/IniTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/list-groups.phpt b/vendor/phpunit/phpunit/tests/TextUI/list-groups.phpt new file mode 100644 index 000000000..fba986854 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/list-groups.phpt @@ -0,0 +1,19 @@ +--TEST-- +phpunit --list-groups BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Available test group(s): + - balanceCannotBecomeNegative + - balanceIsInitiallyZero + - specification diff --git a/vendor/phpunit/phpunit/tests/TextUI/log-json-no-pretty-print.phpt b/vendor/phpunit/phpunit/tests/TextUI/log-json-no-pretty-print.phpt new file mode 100644 index 000000000..33ed4ed4e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/log-json-no-pretty-print.phpt @@ -0,0 +1,27 @@ +--TEST-- +phpunit --log-json php://stdout BankAccountTest ../_files/BankAccountTest.php +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +{"event":"suiteStart","suite":"BankAccountTest","tests":3}{"event":"testStart","suite":"BankAccountTest","test":"BankAccountTest::testBalanceIsInitiallyZero"}.{"event":"test","suite":"BankAccountTest","test":"BankAccountTest::testBalanceIsInitiallyZero","status":"pass","time":%f,"trace":[],"message":"","output":""}{"event":"testStart","suite":"BankAccountTest","test":"BankAccountTest::testBalanceCannotBecomeNegative"}.{"event":"test","suite":"BankAccountTest","test":"BankAccountTest::testBalanceCannotBecomeNegative","status":"pass","time":%f,"trace":[],"message":"","output":""}{"event":"testStart","suite":"BankAccountTest","test":"BankAccountTest::testBalanceCannotBecomeNegative2"}.{"event":"test","suite":"BankAccountTest","test":"BankAccountTest::testBalanceCannotBecomeNegative2","status":"pass","time":%f,"trace":[],"message":"","output":""} + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/log-json-post-66021.phpt b/vendor/phpunit/phpunit/tests/TextUI/log-json-post-66021.phpt new file mode 100644 index 000000000..b045617c4 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/log-json-post-66021.phpt @@ -0,0 +1,72 @@ +--TEST-- +phpunit --log-json php://stdout BankAccountTest ../_files/BankAccountTest.php +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +{ + "event": "suiteStart", + "suite": "BankAccountTest", + "tests": 3 +}{ + "event": "testStart", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceIsInitiallyZero" +}.{ + "event": "test", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceIsInitiallyZero", + "status": "pass", + "time": %f, + "trace": [], + "message": "", + "output": "" +}{ + "event": "testStart", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceCannotBecomeNegative" +}.{ + "event": "test", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceCannotBecomeNegative", + "status": "pass", + "time": %f, + "trace": [], + "message": "", + "output": "" +}{ + "event": "testStart", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceCannotBecomeNegative2" +}.{ + "event": "test", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceCannotBecomeNegative2", + "status": "pass", + "time": %f, + "trace": [], + "message": "", + "output": "" +} + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/log-json-pre-66021.phpt b/vendor/phpunit/phpunit/tests/TextUI/log-json-pre-66021.phpt new file mode 100644 index 000000000..1b2b37c01 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/log-json-pre-66021.phpt @@ -0,0 +1,78 @@ +--TEST-- +phpunit --log-json php://stdout BankAccountTest ../_files/BankAccountTest.php +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +{ + "event": "suiteStart", + "suite": "BankAccountTest", + "tests": 3 +}{ + "event": "testStart", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceIsInitiallyZero" +}.{ + "event": "test", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceIsInitiallyZero", + "status": "pass", + "time": %f, + "trace": [ + + ], + "message": "", + "output": "" +}{ + "event": "testStart", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceCannotBecomeNegative" +}.{ + "event": "test", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceCannotBecomeNegative", + "status": "pass", + "time": %f, + "trace": [ + + ], + "message": "", + "output": "" +}{ + "event": "testStart", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceCannotBecomeNegative2" +}.{ + "event": "test", + "suite": "BankAccountTest", + "test": "BankAccountTest::testBalanceCannotBecomeNegative2", + "status": "pass", + "time": %f, + "trace": [ + + ], + "message": "", + "output": "" +} + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/log-junit.phpt b/vendor/phpunit/phpunit/tests/TextUI/log-junit.phpt new file mode 100644 index 000000000..70dbcbeac --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/log-junit.phpt @@ -0,0 +1,59 @@ +--TEST-- +phpunit --log-junit php://stdout StatusTest ../_files/StatusTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +.FEIS. + + + + + StatusTest::testFailure +Failed asserting that false is true. + +%s/StatusTest.php:%d + + + + StatusTest::testError +Exception: + +%s/StatusTest.php:%d + + + + + + + +Time: %s, Memory: %s + +There was 1 error: + +1) StatusTest::testError +Exception: + +%s/StatusTest.php:%d + +-- + +There was 1 failure: + +1) StatusTest::testFailure +Failed asserting that false is true. + +%s/StatusTest.php:%d + +FAILURES! +Tests: 6, Assertions: 2, Errors: 1, Failures: 1, Skipped: 1, Incomplete: 1. \ No newline at end of file diff --git a/vendor/phpunit/phpunit/tests/TextUI/log-tap.phpt b/vendor/phpunit/phpunit/tests/TextUI/log-tap.phpt new file mode 100644 index 000000000..e9221ee4e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/log-tap.phpt @@ -0,0 +1,26 @@ +--TEST-- +phpunit --log-tap php://stdout BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +TAP version 13 +.ok 1 - BankAccountTest::testBalanceIsInitiallyZero +.ok 2 - BankAccountTest::testBalanceCannotBecomeNegative +.ok 3 - BankAccountTest::testBalanceCannotBecomeNegative2 +1..3 + + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/options-after-arguments.phpt b/vendor/phpunit/phpunit/tests/TextUI/options-after-arguments.phpt new file mode 100644 index 000000000..e7f2cec86 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/options-after-arguments.phpt @@ -0,0 +1,19 @@ +--TEST-- +phpunit BankAccountTest ../_files/BankAccountTest.php --colors +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +%s[30;42mOK (3 tests, 3 assertions)%s[0m diff --git a/vendor/phpunit/phpunit/tests/TextUI/output-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/output-isolation.phpt new file mode 100644 index 000000000..5226b257a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/output-isolation.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --process-isolation --filter testExpectOutputStringFooActualFoo ../_files/OutputTestCase.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +. + +Time: %s, Memory: %s + +OK (1 test, 1 assertion) diff --git a/vendor/phpunit/phpunit/tests/TextUI/repeat.phpt b/vendor/phpunit/phpunit/tests/TextUI/repeat.phpt new file mode 100644 index 000000000..8be67ea4f --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/repeat.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --repeat 3 BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +......... + +Time: %s, Memory: %s + +OK (9 tests, 9 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-incomplete.phpt b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-incomplete.phpt new file mode 100644 index 000000000..04239246d --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-incomplete.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --report-useless-tests IncompleteTest ../_files/IncompleteTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +I + +Time: %s, Memory: %s + +OK, but incomplete, skipped, or risky tests! +Tests: 1, Assertions: 0, Incomplete: 1. diff --git a/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-isolation.phpt new file mode 100644 index 000000000..ff6a0d1e4 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-isolation.phpt @@ -0,0 +1,22 @@ +--TEST-- +phpunit --report-useless-tests --process-isolation IncompleteTest ../_files/IncompleteTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +R + +Time: %s, Memory: %s + +OK, but incomplete, skipped, or risky tests! +Tests: 1, Assertions: 0, Risky: 1. diff --git a/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests.phpt b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests.phpt new file mode 100644 index 000000000..f98127828 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --report-useless-tests NothingTest ../_files/NothingTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +R + +Time: %s, Memory: %s + +OK, but incomplete, skipped, or risky tests! +Tests: 1, Assertions: 0, Risky: 1. diff --git a/vendor/phpunit/phpunit/tests/TextUI/tap.phpt b/vendor/phpunit/phpunit/tests/TextUI/tap.phpt new file mode 100644 index 000000000..ca5676df5 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/tap.phpt @@ -0,0 +1,18 @@ +--TEST-- +phpunit --tap BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +TAP version 13 +ok 1 - BankAccountTest::testBalanceIsInitiallyZero +ok 2 - BankAccountTest::testBalanceCannotBecomeNegative +ok 3 - BankAccountTest::testBalanceCannotBecomeNegative2 +1..3 diff --git a/vendor/phpunit/phpunit/tests/TextUI/test-suffix-multiple.phpt b/vendor/phpunit/phpunit/tests/TextUI/test-suffix-multiple.phpt new file mode 100644 index 000000000..6509b68f7 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/test-suffix-multiple.phpt @@ -0,0 +1,20 @@ +--TEST-- +phpunit --test-suffix .test.php,.my.php ../_files/ +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +..... + +Time: %s, Memory: %s + +OK (5 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/test-suffix-single.phpt b/vendor/phpunit/phpunit/tests/TextUI/test-suffix-single.phpt new file mode 100644 index 000000000..137a3e519 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/test-suffix-single.phpt @@ -0,0 +1,20 @@ +--TEST-- +phpunit --test-suffix .test.php ../_files/ +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +... + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/testdox-html.phpt b/vendor/phpunit/phpunit/tests/TextUI/testdox-html.phpt new file mode 100644 index 000000000..c5ebeef23 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/testdox-html.phpt @@ -0,0 +1,21 @@ +--TEST-- +phpunit --testdox-html php://stdout BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +

BankAccount

    ...
  • Balance is initially zero
  • Balance cannot become negative
+ +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/testdox-text.phpt b/vendor/phpunit/phpunit/tests/TextUI/testdox-text.phpt new file mode 100644 index 000000000..bb36acfb3 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/testdox-text.phpt @@ -0,0 +1,25 @@ +--TEST-- +phpunit --testdox-text php://stdout BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +BankAccount +... [x] Balance is initially zero + [x] Balance cannot become negative + + + +Time: %s, Memory: %s + +OK (3 tests, 3 assertions) diff --git a/vendor/phpunit/phpunit/tests/TextUI/testdox.phpt b/vendor/phpunit/phpunit/tests/TextUI/testdox.phpt new file mode 100644 index 000000000..fb24e94a7 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/TextUI/testdox.phpt @@ -0,0 +1,19 @@ +--TEST-- +phpunit --testdox php://stdout BankAccountTest ../_files/BankAccountTest.php +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +BankAccount + [x] Balance is initially zero + [x] Balance cannot become negative + diff --git a/vendor/phpunit/phpunit/tests/Util/ConfigurationTest.php b/vendor/phpunit/phpunit/tests/Util/ConfigurationTest.php new file mode 100644 index 000000000..0cdd95e1a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Util/ConfigurationTest.php @@ -0,0 +1,504 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 3.3.0 + */ +class Util_ConfigurationTest extends PHPUnit_Framework_TestCase +{ + protected $configuration; + + protected function setUp() + { + $this->configuration = PHPUnit_Util_Configuration::getInstance( + dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.xml' + ); + } + + /** + * @covers PHPUnit_Util_Configuration::getInstance + * @expectedException PHPUnit_Framework_Exception + */ + public function testExceptionIsThrownForNotExistingConfigurationFile() + { + PHPUnit_Util_Configuration::getInstance('not_existing_file.xml'); + } + + /** + * @covers PHPUnit_Util_Configuration::getPHPUnitConfiguration + */ + public function testShouldReadColorsWhenTrueInConfigurationfile() + { + $configurationFilename = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.colors.true.xml'; + $configurationInstance = PHPUnit_Util_Configuration::getInstance($configurationFilename); + $configurationValues = $configurationInstance->getPHPUnitConfiguration(); + + $this->assertEquals(PHPUnit_TextUI_ResultPrinter::COLOR_AUTO, $configurationValues['colors']); + } + + /** + * @covers PHPUnit_Util_Configuration::getPHPUnitConfiguration + */ + public function testShouldReadColorsWhenFalseInConfigurationfile() + { + $configurationFilename = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.colors.false.xml'; + $configurationInstance = PHPUnit_Util_Configuration::getInstance($configurationFilename); + $configurationValues = $configurationInstance->getPHPUnitConfiguration(); + + $this->assertEquals(PHPUnit_TextUI_ResultPrinter::COLOR_NEVER, $configurationValues['colors']); + } + + /** + * @covers PHPUnit_Util_Configuration::getPHPUnitConfiguration + */ + public function testShouldReadColorsWhenEmptyInConfigurationfile() + { + $configurationFilename = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.colors.empty.xml'; + $configurationInstance = PHPUnit_Util_Configuration::getInstance($configurationFilename); + $configurationValues = $configurationInstance->getPHPUnitConfiguration(); + + $this->assertEquals(PHPUnit_TextUI_ResultPrinter::COLOR_NEVER, $configurationValues['colors']); + } + + /** + * @covers PHPUnit_Util_Configuration::getPHPUnitConfiguration + */ + public function testShouldReadColorsWhenInvalidInConfigurationfile() + { + $configurationFilename = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.colors.invalid.xml'; + $configurationInstance = PHPUnit_Util_Configuration::getInstance($configurationFilename); + $configurationValues = $configurationInstance->getPHPUnitConfiguration(); + + $this->assertEquals(PHPUnit_TextUI_ResultPrinter::COLOR_NEVER, $configurationValues['colors']); + } + + /** + * @covers PHPUnit_Util_Configuration::getFilterConfiguration + */ + public function testFilterConfigurationIsReadCorrectly() + { + $this->assertEquals( + array( + 'blacklist' => + array( + 'include' => + array( + 'directory' => + array( + 0 => + array( + 'path' => '/path/to/files', + 'prefix' => '', + 'suffix' => '.php', + 'group' => 'DEFAULT' + ), + ), + 'file' => + array( + 0 => '/path/to/file', + 1 => '/path/to/file', + ), + ), + 'exclude' => + array( + 'directory' => + array( + 0 => + array( + 'path' => '/path/to/files', + 'prefix' => '', + 'suffix' => '.php', + 'group' => 'DEFAULT' + ), + ), + 'file' => + array( + 0 => '/path/to/file', + ), + ), + ), + 'whitelist' => + array( + 'addUncoveredFilesFromWhitelist' => true, + 'processUncoveredFilesFromWhitelist' => false, + 'include' => + array( + 'directory' => + array( + 0 => + array( + 'path' => '/path/to/files', + 'prefix' => '', + 'suffix' => '.php', + 'group' => 'DEFAULT' + ), + ), + 'file' => + array( + 0 => '/path/to/file', + ), + ), + 'exclude' => + array( + 'directory' => + array( + 0 => + array( + 'path' => '/path/to/files', + 'prefix' => '', + 'suffix' => '.php', + 'group' => 'DEFAULT' + ), + ), + 'file' => + array( + 0 => '/path/to/file', + ), + ), + ), + ), + $this->configuration->getFilterConfiguration() + ); + } + + /** + * @covers PHPUnit_Util_Configuration::getGroupConfiguration + */ + public function testGroupConfigurationIsReadCorrectly() + { + $this->assertEquals( + array( + 'include' => + array( + 0 => 'name', + ), + 'exclude' => + array( + 0 => 'name', + ), + ), + $this->configuration->getGroupConfiguration() + ); + } + + /** + * @covers PHPUnit_Util_Configuration::getListenerConfiguration + */ + public function testListenerConfigurationIsReadCorrectly() + { + $dir = __DIR__; + $includePath = ini_get('include_path'); + + ini_set('include_path', $dir . PATH_SEPARATOR . $includePath); + + $this->assertEquals( + array( + 0 => + array( + 'class' => 'MyListener', + 'file' => '/optional/path/to/MyListener.php', + 'arguments' => + array( + 0 => + array( + 0 => 'Sebastian', + ), + 1 => 22, + 2 => 'April', + 3 => 19.78, + 4 => null, + 5 => new stdClass, + 6 => dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'MyTestFile.php', + 7 => dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'MyRelativePath', + ), + ), + array( + 'class' => 'IncludePathListener', + 'file' => __FILE__, + 'arguments' => array() + ), + array( + 'class' => 'CompactArgumentsListener', + 'file' => '/CompactArgumentsListener.php', + 'arguments' => + array( + 0 => 42 + ), + ), + ), + $this->configuration->getListenerConfiguration() + ); + + ini_set('include_path', $includePath); + } + + /** + * @covers PHPUnit_Util_Configuration::getLoggingConfiguration + */ + public function testLoggingConfigurationIsReadCorrectly() + { + $this->assertEquals( + array( + 'lowUpperBound' => '50', + 'highLowerBound' => '90', + 'coverage-html' => '/tmp/report', + 'coverage-clover' => '/tmp/clover.xml', + 'json' => '/tmp/logfile.json', + 'plain' => '/tmp/logfile.txt', + 'tap' => '/tmp/logfile.tap', + 'logIncompleteSkipped' => false, + 'junit' => '/tmp/logfile.xml', + 'testdox-html' => '/tmp/testdox.html', + 'testdox-text' => '/tmp/testdox.txt', + ), + $this->configuration->getLoggingConfiguration() + ); + } + + /** + * @covers PHPUnit_Util_Configuration::getPHPConfiguration + */ + public function testPHPConfigurationIsReadCorrectly() + { + $this->assertEquals( + array( + 'include_path' => + array( + dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . '.', + '/path/to/lib' + ), + 'ini' => array('foo' => 'bar'), + 'const' => array('FOO' => false, 'BAR' => true), + 'var' => array('foo' => false), + 'env' => array('foo' => true), + 'post' => array('foo' => 'bar'), + 'get' => array('foo' => 'bar'), + 'cookie' => array('foo' => 'bar'), + 'server' => array('foo' => 'bar'), + 'files' => array('foo' => 'bar'), + 'request'=> array('foo' => 'bar'), + ), + $this->configuration->getPHPConfiguration() + ); + } + + /** + * @backupGlobals enabled + * @covers PHPUnit_Util_Configuration::handlePHPConfiguration + */ + public function testPHPConfigurationIsHandledCorrectly() + { + $this->configuration->handlePHPConfiguration(); + + $path = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . '.' . PATH_SEPARATOR . '/path/to/lib'; + $this->assertStringStartsWith($path, ini_get('include_path')); + $this->assertEquals(false, FOO); + $this->assertEquals(true, BAR); + $this->assertEquals(false, $GLOBALS['foo']); + $this->assertEquals(true, $_ENV['foo']); + $this->assertEquals(true, getenv('foo')); + $this->assertEquals('bar', $_POST['foo']); + $this->assertEquals('bar', $_GET['foo']); + $this->assertEquals('bar', $_COOKIE['foo']); + $this->assertEquals('bar', $_SERVER['foo']); + $this->assertEquals('bar', $_FILES['foo']); + $this->assertEquals('bar', $_REQUEST['foo']); + } + + /** + * @backupGlobals enabled + * + * @see https://github.com/sebastianbergmann/phpunit/issues/1181 + */ + public function testHandlePHPConfigurationDoesNotOverwrittenExistingEnvArrayVariables() + { + $_ENV['foo'] = false; + $this->configuration->handlePHPConfiguration(); + + $this->assertEquals(false, $_ENV['foo']); + $this->assertEquals(true, getenv('foo')); + } + + /** + * @backupGlobals enabled + * + * @see https://github.com/sebastianbergmann/phpunit/issues/1181 + */ + public function testHandlePHPConfigurationDoesNotOverriteVariablesFromPutEnv() + { + putenv('foo=putenv'); + $this->configuration->handlePHPConfiguration(); + + $this->assertEquals(true, $_ENV['foo']); + $this->assertEquals('putenv', getenv('foo')); + } + + /** + * @covers PHPUnit_Util_Configuration::getPHPUnitConfiguration + */ + public function testPHPUnitConfigurationIsReadCorrectly() + { + $this->assertEquals( + array( + 'backupGlobals' => true, + 'backupStaticAttributes' => false, + 'disallowChangesToGlobalState' => false, + 'bootstrap' => '/path/to/bootstrap.php', + 'cacheTokens' => false, + 'columns' => 80, + 'colors' => 'never', + 'stderr' => false, + 'convertErrorsToExceptions' => true, + 'convertNoticesToExceptions' => true, + 'convertWarningsToExceptions' => true, + 'forceCoversAnnotation' => false, + 'mapTestClassNameToCoveredClassName' => false, + 'printerClass' => 'PHPUnit_TextUI_ResultPrinter', + 'stopOnFailure' => false, + 'reportUselessTests' => false, + 'strictCoverage' => false, + 'disallowTestOutput' => false, + 'enforceTimeLimit' => false, + 'disallowTodoAnnotatedTests' => false, + 'testSuiteLoaderClass' => 'PHPUnit_Runner_StandardTestSuiteLoader', + 'verbose' => false, + 'timeoutForSmallTests' => 1, + 'timeoutForMediumTests' => 10, + 'timeoutForLargeTests' => 60 + ), + $this->configuration->getPHPUnitConfiguration() + ); + } + + /** + * @covers PHPUnit_Util_Configuration::getSeleniumBrowserConfiguration + */ + public function testSeleniumBrowserConfigurationIsReadCorrectly() + { + $this->assertEquals( + array( + 0 => + array( + 'name' => 'Firefox on Linux', + 'browser' => '*firefox /usr/lib/firefox/firefox-bin', + 'host' => 'my.linux.box', + 'port' => 4444, + 'timeout' => 30000, + ), + ), + $this->configuration->getSeleniumBrowserConfiguration() + ); + } + + /** + * @covers PHPUnit_Util_Configuration::getInstance + */ + public function testXincludeInConfiguration() + { + $configurationWithXinclude = PHPUnit_Util_Configuration::getInstance( + dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration_xinclude.xml' + ); + + $this->assertConfigurationEquals( + $this->configuration, + $configurationWithXinclude + ); + } + + /** + * @ticket 1311 + * @covers PHPUnit_Util_Configuration::getLoggingConfiguration + * @covers PHPUnit_Util_Configuration::getPHPConfiguration + * @covers PHPUnit_Util_Configuration::getPHPUnitConfiguration + * @covers PHPUnit_Util_Configuration::getTestSuiteConfiguration + * @covers PHPUnit_Util_Configuration::getFilterConfiguration + * + * @uses PHPUnit_Util_Configuration::getInstance + */ + public function testWithEmptyConfigurations() + { + $emptyConfiguration = PHPUnit_Util_Configuration::getInstance( + dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration_empty.xml' + ); + + $logging = $emptyConfiguration->getLoggingConfiguration(); + $this->assertEmpty($logging); + + $php = $emptyConfiguration->getPHPConfiguration(); + $this->assertEmpty($php['include_path']); + + $phpunit = $emptyConfiguration->getPHPUnitConfiguration(); + $this->assertArrayNotHasKey('bootstrap', $phpunit); + $this->assertArrayNotHasKey('testSuiteLoaderFile', $phpunit); + $this->assertArrayNotHasKey('printerFile', $phpunit); + + $suite = $emptyConfiguration->getTestSuiteConfiguration(); + $this->assertEmpty($suite->getGroups()); + + $filter = $emptyConfiguration->getFilterConfiguration(); + $this->assertEmpty($filter['blacklist']['include']['directory']); + $this->assertEmpty($filter['blacklist']['include']['file']); + $this->assertEmpty($filter['blacklist']['exclude']['directory']); + $this->assertEmpty($filter['blacklist']['exclude']['file']); + $this->assertEmpty($filter['whitelist']['include']['directory']); + $this->assertEmpty($filter['whitelist']['include']['file']); + $this->assertEmpty($filter['whitelist']['exclude']['directory']); + $this->assertEmpty($filter['whitelist']['exclude']['file']); + } + + /** + * Asserts that the values in $actualConfiguration equal $expectedConfiguration. + * + * @param PHPUnit_Util_Configuration $expectedConfiguration + * @param PHPUnit_Util_Configuration $actualConfiguration + */ + protected function assertConfigurationEquals(PHPUnit_Util_Configuration $expectedConfiguration, PHPUnit_Util_Configuration $actualConfiguration) + { + $this->assertEquals( + $expectedConfiguration->getFilterConfiguration(), + $actualConfiguration->getFilterConfiguration() + ); + + $this->assertEquals( + $expectedConfiguration->getGroupConfiguration(), + $actualConfiguration->getGroupConfiguration() + ); + + $this->assertEquals( + $expectedConfiguration->getListenerConfiguration(), + $actualConfiguration->getListenerConfiguration() + ); + + $this->assertEquals( + $expectedConfiguration->getLoggingConfiguration(), + $actualConfiguration->getLoggingConfiguration() + ); + + $this->assertEquals( + $expectedConfiguration->getPHPConfiguration(), + $actualConfiguration->getPHPConfiguration() + ); + + $this->assertEquals( + $expectedConfiguration->getPHPUnitConfiguration(), + $actualConfiguration->getPHPUnitConfiguration() + ); + + $this->assertEquals( + $expectedConfiguration->getSeleniumBrowserConfiguration(), + $actualConfiguration->getSeleniumBrowserConfiguration() + ); + + $this->assertEquals( + $expectedConfiguration->getTestSuiteConfiguration(), + $actualConfiguration->getTestSuiteConfiguration() + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/Util/GetoptTest.php b/vendor/phpunit/phpunit/tests/Util/GetoptTest.php new file mode 100644 index 000000000..8e7ad4dcf --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Util/GetoptTest.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + */ +class Util_GetoptTest extends PHPUnit_Framework_TestCase +{ + public function testItIncludeTheLongOptionsAfterTheArgument() + { + $args = array( + 'command', + 'myArgument', + '--colors', + ); + $actual = PHPUnit_Util_Getopt::getopt($args, '', array('colors==')); + + $expected = array( + array( + array( + '--colors', + null, + ), + ), + array( + 'myArgument', + ), + ); + + $this->assertEquals($expected, $actual); + } + + public function testItIncludeTheShortOptionsAfterTheArgument() + { + $args = array( + 'command', + 'myArgument', + '-v', + ); + $actual = PHPUnit_Util_Getopt::getopt($args, 'v'); + + $expected = array( + array( + array( + 'v', + null, + ), + ), + array( + 'myArgument', + ), + ); + + $this->assertEquals($expected, $actual); + } +} diff --git a/vendor/phpunit/phpunit/tests/Util/GlobalStateTest.php b/vendor/phpunit/phpunit/tests/Util/GlobalStateTest.php new file mode 100644 index 000000000..5810ee396 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Util/GlobalStateTest.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + */ +class Util_GlobalStateTest extends PHPUnit_Framework_TestCase +{ + /** + * @covers PHPUnit_Util_GlobalState::processIncludedFilesAsString + */ + public function testIncludedFilesAsStringSkipsVfsProtocols() + { + $dir = __DIR__; + $files = array( + 'phpunit', // The 0 index is not used + $dir . '/ConfigurationTest.php', + $dir . '/GlobalStateTest.php', + 'vfs://' . $dir . '/RegexTest.php', + 'phpvfs53e46260465c7://' . $dir . '/TestTest.php', + 'file://' . $dir . '/XMLTest.php' + ); + + $this->assertEquals( + "require_once '" . $dir . "/ConfigurationTest.php';\n" . + "require_once '" . $dir . "/GlobalStateTest.php';\n" . + "require_once 'file://" . $dir . "/XMLTest.php';\n", PHPUnit_Util_GlobalState::processIncludedFilesAsString($files)); + } +} diff --git a/vendor/phpunit/phpunit/tests/Util/RegexTest.php b/vendor/phpunit/phpunit/tests/Util/RegexTest.php new file mode 100644 index 000000000..7242654fd --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Util/RegexTest.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 4.2.0 + */ +class Util_RegexTest extends PHPUnit_Framework_TestCase +{ + public function validRegexpProvider() + { + return array( + array('#valid regexp#', 'valid regexp', 1), + array(';val.*xp;', 'valid regexp', 1), + array('/val.*xp/i', 'VALID REGEXP', 1), + array('/a val.*p/','valid regexp', 0), + ); + } + + public function invalidRegexpProvider() + { + return array( + array('valid regexp', 'valid regexp'), + array(';val.*xp', 'valid regexp'), + array('val.*xp/i', 'VALID REGEXP'), + ); + } + + /** + * @dataProvider validRegexpProvider + * @covers PHPUnit_Util_Regex::pregMatchSafe + */ + public function testValidRegex($pattern, $subject, $return) + { + $this->assertEquals($return, PHPUnit_Util_Regex::pregMatchSafe($pattern, $subject)); + } + + /** + * @dataProvider invalidRegexpProvider + * @covers PHPUnit_Util_Regex::pregMatchSafe + */ + public function testInvalidRegex($pattern, $subject) + { + $this->assertFalse(PHPUnit_Util_Regex::pregMatchSafe($pattern, $subject)); + } +} diff --git a/vendor/phpunit/phpunit/tests/Util/TestDox/NamePrettifierTest.php b/vendor/phpunit/phpunit/tests/Util/TestDox/NamePrettifierTest.php new file mode 100644 index 000000000..729e8ac2f --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Util/TestDox/NamePrettifierTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 2.1.0 + */ +class Util_TestDox_NamePrettifierTest extends PHPUnit_Framework_TestCase +{ + protected $namePrettifier; + + protected function setUp() + { + $this->namePrettifier = new PHPUnit_Util_TestDox_NamePrettifier; + } + + /** + * @covers PHPUnit_Util_TestDox_NamePrettifier::prettifyTestClass + */ + public function testTitleHasSensibleDefaults() + { + $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('FooTest')); + $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('TestFoo')); + $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('TestFooTest')); + $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('Test\FooTest')); + } + + /** + * @covers PHPUnit_Util_TestDox_NamePrettifier::prettifyTestClass + */ + public function testCaterForUserDefinedSuffix() + { + $this->namePrettifier->setSuffix('TestCase'); + $this->namePrettifier->setPrefix(null); + + $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('FooTestCase')); + $this->assertEquals('TestFoo', $this->namePrettifier->prettifyTestClass('TestFoo')); + $this->assertEquals('FooTest', $this->namePrettifier->prettifyTestClass('FooTest')); + } + + /** + * @covers PHPUnit_Util_TestDox_NamePrettifier::prettifyTestClass + */ + public function testCaterForUserDefinedPrefix() + { + $this->namePrettifier->setSuffix(null); + $this->namePrettifier->setPrefix('XXX'); + + $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('XXXFoo')); + $this->assertEquals('TestXXX', $this->namePrettifier->prettifyTestClass('TestXXX')); + $this->assertEquals('XXX', $this->namePrettifier->prettifyTestClass('XXXXXX')); + } + + /** + * @covers PHPUnit_Util_TestDox_NamePrettifier::prettifyTestMethod + */ + public function testTestNameIsConvertedToASentence() + { + $this->assertEquals('This is a test', $this->namePrettifier->prettifyTestMethod('testThisIsATest')); + $this->assertEquals('This is a test', $this->namePrettifier->prettifyTestMethod('testThisIsATest2')); + $this->assertEquals('This is a test', $this->namePrettifier->prettifyTestMethod('this_is_a_test')); + $this->assertEquals('Foo for bar is 0', $this->namePrettifier->prettifyTestMethod('testFooForBarIs0')); + $this->assertEquals('Foo for baz is 1', $this->namePrettifier->prettifyTestMethod('testFooForBazIs1')); + } + + /** + * @covers PHPUnit_Util_TestDox_NamePrettifier::prettifyTestMethod + * @ticket 224 + */ + public function testTestNameIsNotGroupedWhenNotInSequence() + { + $this->assertEquals('Sets redirect header on 301', $this->namePrettifier->prettifyTestMethod('testSetsRedirectHeaderOn301')); + $this->assertEquals('Sets redirect header on 302', $this->namePrettifier->prettifyTestMethod('testSetsRedirectHeaderOn302')); + } +} diff --git a/vendor/phpunit/phpunit/tests/Util/TestTest.php b/vendor/phpunit/phpunit/tests/Util/TestTest.php new file mode 100644 index 000000000..2b425364a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Util/TestTest.php @@ -0,0 +1,685 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (!defined('TEST_FILES_PATH')) { + define( + 'TEST_FILES_PATH', + dirname(__DIR__) . DIRECTORY_SEPARATOR . + '_files' . DIRECTORY_SEPARATOR + ); +} + +require TEST_FILES_PATH . 'CoverageNamespacedFunctionTest.php'; +require TEST_FILES_PATH . 'NamespaceCoveredFunction.php'; + +/** + * @since Class available since Release 3.3.6 + */ +class Util_TestTest extends PHPUnit_Framework_TestCase +{ + /** + * @covers PHPUnit_Util_Test::getExpectedException + * + * @todo Split up in separate tests + */ + public function testGetExpectedException() + { + $this->assertArraySubset( + array('class' => 'FooBarBaz', 'code' => null, 'message' => ''), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testOne') + ); + + $this->assertArraySubset( + array('class' => 'Foo_Bar_Baz', 'code' => null, 'message' => ''), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testTwo') + ); + + $this->assertArraySubset( + array('class' => 'Foo\Bar\Baz', 'code' => null, 'message' => ''), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testThree') + ); + + $this->assertArraySubset( + array('class' => 'ほげ', 'code' => null, 'message' => ''), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testFour') + ); + + $this->assertArraySubset( + array('class' => 'Class', 'code' => 1234, 'message' => 'Message'), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testFive') + ); + + $this->assertArraySubset( + array('class' => 'Class', 'code' => 1234, 'message' => 'Message'), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testSix') + ); + + $this->assertArraySubset( + array('class' => 'Class', 'code' => 'ExceptionCode', 'message' => 'Message'), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testSeven') + ); + + $this->assertArraySubset( + array('class' => 'Class', 'code' => 0, 'message' => 'Message'), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testEight') + ); + + $this->assertArraySubset( + array('class' => 'Class', 'code' => ExceptionTest::ERROR_CODE, 'message' => ExceptionTest::ERROR_MESSAGE), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testNine') + ); + + $this->assertArraySubset( + array('class' => 'Class', 'code' => null, 'message' => ''), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testSingleLine') + ); + + $this->assertArraySubset( + array('class' => 'Class', 'code' => My\Space\ExceptionNamespaceTest::ERROR_CODE, 'message' => My\Space\ExceptionNamespaceTest::ERROR_MESSAGE), + PHPUnit_Util_Test::getExpectedException('My\Space\ExceptionNamespaceTest', 'testConstants') + ); + + // Ensure the Class::CONST expression is only evaluated when the constant really exists + $this->assertArraySubset( + array('class' => 'Class', 'code' => 'ExceptionTest::UNKNOWN_CODE_CONSTANT', 'message' => 'ExceptionTest::UNKNOWN_MESSAGE_CONSTANT'), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testUnknownConstants') + ); + + $this->assertArraySubset( + array('class' => 'Class', 'code' => 'My\Space\ExceptionNamespaceTest::UNKNOWN_CODE_CONSTANT', 'message' => 'My\Space\ExceptionNamespaceTest::UNKNOWN_MESSAGE_CONSTANT'), + PHPUnit_Util_Test::getExpectedException('My\Space\ExceptionNamespaceTest', 'testUnknownConstants') + ); + } + + /** + * @covers PHPUnit_Util_Test::getExpectedException + */ + public function testGetExpectedRegExp() + { + $this->assertArraySubset( + array('message_regex' => '#regex#'), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testWithRegexMessage') + ); + + $this->assertArraySubset( + array('message_regex' => '#regex#'), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testWithRegexMessageFromClassConstant') + ); + + $this->assertArraySubset( + array('message_regex' => 'ExceptionTest::UNKNOWN_MESSAGE_REGEX_CONSTANT'), + PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testWithUnknowRegexMessageFromClassConstant') + ); + } + + /** + * @covers PHPUnit_Util_Test::getRequirements + * @dataProvider requirementsProvider + */ + public function testGetRequirements($test, $result) + { + $this->assertEquals( + $result, + PHPUnit_Util_Test::getRequirements('RequirementsTest', $test) + ); + } + + public function requirementsProvider() + { + return array( + array('testOne', array()), + array('testTwo', array('PHPUnit' => '1.0')), + array('testThree', array('PHP' => '2.0')), + array('testFour', array('PHPUnit' => '2.0', 'PHP' => '1.0')), + array('testFive', array('PHP' => '5.4.0RC6')), + array('testSix', array('PHP' => '5.4.0-alpha1')), + array('testSeven', array('PHP' => '5.4.0beta2')), + array('testEight', array('PHP' => '5.4-dev')), + array('testNine', array('functions' => array('testFunc'))), + array('testTen', array('extensions' => array('testExt'))), + array('testEleven', array('OS' => '/Linux/i')), + array( + 'testSpace', + array( + 'extensions' => array('spl'), + 'OS' => '/.*/i' + ) + ), + array( + 'testAllPossibleRequirements', + array( + 'PHP' => '99-dev', + 'PHPUnit' => '9-dev', + 'OS' => '/DOESNOTEXIST/i', + 'functions' => array( + 'testFuncOne', + 'testFuncTwo', + ), + 'extensions' => array( + 'testExtOne', + 'testExtTwo', + ) + ) + ) + ); + } + + /** + * @covers PHPUnit_Util_Test::getRequirements + */ + public function testGetRequirementsMergesClassAndMethodDocBlocks() + { + $expectedAnnotations = array( + 'PHP' => '5.4', + 'PHPUnit' => '3.7', + 'OS' => '/WINNT/i', + 'functions' => array( + 'testFuncClass', + 'testFuncMethod', + ), + 'extensions' => array( + 'testExtClass', + 'testExtMethod', + ) + ); + + $this->assertEquals( + $expectedAnnotations, + PHPUnit_Util_Test::getRequirements('RequirementsClassDocBlockTest', 'testMethod') + ); + } + + /** + * @covers PHPUnit_Util_Test::getMissingRequirements + * @dataProvider missingRequirementsProvider + */ + public function testGetMissingRequirements($test, $result) + { + $this->assertEquals( + $result, + PHPUnit_Util_Test::getMissingRequirements('RequirementsTest', $test) + ); + } + + public function missingRequirementsProvider() + { + return array( + array('testOne', array()), + array('testNine', array('Function testFunc is required.')), + array('testTen', array('Extension testExt is required.')), + array('testAlwaysSkip', array('PHPUnit 1111111 (or later) is required.')), + array('testAlwaysSkip2', array('PHP 9999999 (or later) is required.')), + array('testAlwaysSkip3', array('Operating system matching /DOESNOTEXIST/i is required.')), + array('testAllPossibleRequirements', array( + 'PHP 99-dev (or later) is required.', + 'PHPUnit 9-dev (or later) is required.', + 'Operating system matching /DOESNOTEXIST/i is required.', + 'Function testFuncOne is required.', + 'Function testFuncTwo is required.', + 'Extension testExtOne is required.', + 'Extension testExtTwo is required.', + )), + ); + } + + /** + * @coversNothing + * + * @todo This test does not really test functionality of PHPUnit_Util_Test + */ + public function testGetProvidedDataRegEx() + { + $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider method', $matches); + $this->assertEquals(1, $result); + $this->assertEquals('method', $matches[1]); + + $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider class::method', $matches); + $this->assertEquals(1, $result); + $this->assertEquals('class::method', $matches[1]); + + $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider namespace\class::method', $matches); + $this->assertEquals(1, $result); + $this->assertEquals('namespace\class::method', $matches[1]); + + $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider namespace\namespace\class::method', $matches); + $this->assertEquals(1, $result); + $this->assertEquals('namespace\namespace\class::method', $matches[1]); + + $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider メソッド', $matches); + $this->assertEquals(1, $result); + $this->assertEquals('メソッド', $matches[1]); + } + + /** + * @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation + */ + public function testTestWithEmptyAnnotation() + { + $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**\n * @anotherAnnotation\n */"); + $this->assertNull($result); + } + + /** + * @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation + */ + public function testTestWithSimpleCase() + { + $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/** + * @testWith [1] + */'); + $this->assertEquals(array(array(1)), $result); + } + + /** + * @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation + */ + public function testTestWithMultiLineMultiParameterCase() + { + $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/** + * @testWith [1, 2] + * [3, 4] + */'); + $this->assertEquals(array(array(1, 2), array(3, 4)), $result); + } + + /** + * @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation + */ + public function testTestWithVariousTypes() + { + $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/** + * @testWith ["ab"] + * [true] + * [null] + */'); + $this->assertEquals(array(array('ab'), array(true), array(null)), $result); + } + + /** + * @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation + */ + public function testTestWithAnnotationAfter() + { + $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/** + * @testWith [1] + * [2] + * @annotation + */'); + $this->assertEquals(array(array(1), array(2)), $result); + } + + /** + * @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation + */ + public function testTestWithSimpleTextAfter() + { + $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/** + * @testWith [1] + * [2] + * blah blah + */'); + $this->assertEquals(array(array(1), array(2)), $result); + } + + /** + * @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation + */ + public function testTestWithCharacterEscape() + { + $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/** + * @testWith ["\"", "\""] + */'); + $this->assertEquals(array(array('"', '"')), $result); + } + + /** + * @covers PHPUnit_Util_Test::getDataFromTestWithAnnotation + */ + public function testTestWithThrowsProperExceptionIfDatasetCannotBeParsed() + { + $this->setExpectedExceptionRegExp( + 'PHPUnit_Framework_Exception', + '/^The dataset for the @testWith annotation cannot be parsed:/' + ); + PHPUnit_Util_Test::getDataFromTestWithAnnotation('/** + * @testWith [s] + */'); + } + + public function testTestWithThrowsProperExceptionIfMultiLineDatasetCannotBeParsed() + { + $this->setExpectedExceptionRegExp( + 'PHPUnit_Framework_Exception', + '/^The dataset for the @testWith annotation cannot be parsed:/' + ); + PHPUnit_Util_Test::getDataFromTestWithAnnotation('/** + * @testWith ["valid"] + * [invalid] + */'); + } + + /** + * @covers PHPUnit_Util_Test::getDependencies + * + * @todo Not sure what this test tests (name is misleading at least) + */ + public function testParseAnnotation() + { + $this->assertEquals( + array('Foo', 'ほげ'), + PHPUnit_Util_Test::getDependencies(get_class($this), 'methodForTestParseAnnotation') + ); + } + + /** + * @depends Foo + * @depends ほげ + * + * @todo Remove fixture from test class + */ + public function methodForTestParseAnnotation() + { + } + + /** + * @covers PHPUnit_Util_Test::getDependencies + */ + public function testParseAnnotationThatIsOnlyOneLine() + { + $this->assertEquals( + array('Bar'), + PHPUnit_Util_Test::getDependencies(get_class($this), 'methodForTestParseAnnotationThatIsOnlyOneLine') + ); + } + + /** @depends Bar */ + public function methodForTestParseAnnotationThatIsOnlyOneLine() + { + // TODO Remove fixture from test class + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + * @covers PHPUnit_Util_Test::resolveElementToReflectionObjects + * @dataProvider getLinesToBeCoveredProvider + */ + public function testGetLinesToBeCovered($test, $lines) + { + if (strpos($test, 'Namespace') === 0) { + $expected = array( + TEST_FILES_PATH . 'NamespaceCoveredClass.php' => $lines + ); + } elseif ($test === 'CoverageNoneTest') { + $expected = array(); + } elseif ($test === 'CoverageNothingTest') { + $expected = false; + } elseif ($test === 'CoverageFunctionTest') { + $expected = array( + TEST_FILES_PATH . 'CoveredFunction.php' => $lines + ); + } else { + $expected = array(TEST_FILES_PATH . 'CoveredClass.php' => $lines); + } + + $this->assertEquals( + $expected, + PHPUnit_Util_Test::getLinesToBeCovered( + $test, 'testSomething' + ) + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + * @covers PHPUnit_Util_Test::resolveElementToReflectionObjects + * @expectedException PHPUnit_Framework_CodeCoverageException + */ + public function testGetLinesToBeCovered2() + { + PHPUnit_Util_Test::getLinesToBeCovered( + 'NotExistingCoveredElementTest', 'testOne' + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + * @covers PHPUnit_Util_Test::resolveElementToReflectionObjects + * @expectedException PHPUnit_Framework_CodeCoverageException + */ + public function testGetLinesToBeCovered3() + { + PHPUnit_Util_Test::getLinesToBeCovered( + 'NotExistingCoveredElementTest', 'testTwo' + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + * @covers PHPUnit_Util_Test::resolveElementToReflectionObjects + * @expectedException PHPUnit_Framework_CodeCoverageException + */ + public function testGetLinesToBeCovered4() + { + PHPUnit_Util_Test::getLinesToBeCovered( + 'NotExistingCoveredElementTest', 'testThree' + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + */ + public function testGetLinesToBeCoveredSkipsNonExistentMethods() + { + $this->assertSame( + array(), + PHPUnit_Util_Test::getLinesToBeCovered( + 'NotExistingCoveredElementTest', + 'methodDoesNotExist' + ) + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + * @expectedException PHPUnit_Framework_CodeCoverageException + */ + public function testTwoCoversDefaultClassAnnoationsAreNotAllowed() + { + PHPUnit_Util_Test::getLinesToBeCovered( + 'CoverageTwoDefaultClassAnnotations', + 'testSomething' + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + */ + public function testFunctionParenthesesAreAllowed() + { + $this->assertSame( + array(TEST_FILES_PATH . 'CoveredFunction.php' => range(2, 4)), + PHPUnit_Util_Test::getLinesToBeCovered( + 'CoverageFunctionParenthesesTest', + 'testSomething' + ) + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + */ + public function testFunctionParenthesesAreAllowedWithWhitespace() + { + $this->assertSame( + array(TEST_FILES_PATH . 'CoveredFunction.php' => range(2, 4)), + PHPUnit_Util_Test::getLinesToBeCovered( + 'CoverageFunctionParenthesesWhitespaceTest', + 'testSomething' + ) + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + */ + public function testMethodParenthesesAreAllowed() + { + $this->assertSame( + array(TEST_FILES_PATH . 'CoveredClass.php' => range(31, 35)), + PHPUnit_Util_Test::getLinesToBeCovered( + 'CoverageMethodParenthesesTest', + 'testSomething' + ) + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + */ + public function testMethodParenthesesAreAllowedWithWhitespace() + { + $this->assertSame( + array(TEST_FILES_PATH . 'CoveredClass.php' => range(31, 35)), + PHPUnit_Util_Test::getLinesToBeCovered( + 'CoverageMethodParenthesesWhitespaceTest', + 'testSomething' + ) + ); + } + + /** + * @covers PHPUnit_Util_Test::getLinesToBeCovered + * @covers PHPUnit_Util_Test::getLinesToBeCoveredOrUsed + */ + public function testNamespacedFunctionCanBeCoveredOrUsed() + { + $this->assertEquals( + array( + TEST_FILES_PATH . 'NamespaceCoveredFunction.php' => range(4, 7) + ), + PHPUnit_Util_Test::getLinesToBeCovered( + 'CoverageNamespacedFunctionTest', + 'testFunc' + ) + ); + } + + public function getLinesToBeCoveredProvider() + { + return array( + array( + 'CoverageNoneTest', + array() + ), + array( + 'CoverageClassExtendedTest', + array_merge(range(19, 36), range(2, 17)) + ), + array( + 'CoverageClassTest', + range(19, 36) + ), + array( + 'CoverageMethodTest', + range(31, 35) + ), + array( + 'CoverageMethodOneLineAnnotationTest', + range(31, 35) + ), + array( + 'CoverageNotPrivateTest', + array_merge(range(25, 29), range(31, 35)) + ), + array( + 'CoverageNotProtectedTest', + array_merge(range(21, 23), range(31, 35)) + ), + array( + 'CoverageNotPublicTest', + array_merge(range(21, 23), range(25, 29)) + ), + array( + 'CoveragePrivateTest', + range(21, 23) + ), + array( + 'CoverageProtectedTest', + range(25, 29) + ), + array( + 'CoveragePublicTest', + range(31, 35) + ), + array( + 'CoverageFunctionTest', + range(2, 4) + ), + array( + 'NamespaceCoverageClassExtendedTest', + array_merge(range(21, 38), range(4, 19)) + ), + array( + 'NamespaceCoverageClassTest', + range(21, 38) + ), + array( + 'NamespaceCoverageMethodTest', + range(33, 37) + ), + array( + 'NamespaceCoverageNotPrivateTest', + array_merge(range(27, 31), range(33, 37)) + ), + array( + 'NamespaceCoverageNotProtectedTest', + array_merge(range(23, 25), range(33, 37)) + ), + array( + 'NamespaceCoverageNotPublicTest', + array_merge(range(23, 25), range(27, 31)) + ), + array( + 'NamespaceCoveragePrivateTest', + range(23, 25) + ), + array( + 'NamespaceCoverageProtectedTest', + range(27, 31) + ), + array( + 'NamespaceCoveragePublicTest', + range(33, 37) + ), + array( + 'NamespaceCoverageCoversClassTest', + array_merge(range(23, 25), range(27, 31), range(33, 37), range(6, 8), range(10, 13), range(15, 18)) + ), + array( + 'NamespaceCoverageCoversClassPublicTest', + range(33, 37) + ), + array( + 'CoverageNothingTest', + false + ) + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/Util/XMLTest.php b/vendor/phpunit/phpunit/tests/Util/XMLTest.php new file mode 100644 index 000000000..f4c3bd17a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/Util/XMLTest.php @@ -0,0 +1,363 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @since Class available since Release 3.3.0 + * @covers PHPUnit_Util_XML + */ +class Util_XMLTest extends PHPUnit_Framework_TestCase +{ + public function testAssertValidKeysValidKeys() + { + $options = array('testA' => 1, 'testB' => 2, 'testC' => 3); + $valid = array('testA', 'testB', 'testC'); + $expected = array('testA' => 1, 'testB' => 2, 'testC' => 3); + $validated = PHPUnit_Util_XML::assertValidKeys($options, $valid); + + $this->assertEquals($expected, $validated); + } + + public function testAssertValidKeysValidKeysEmpty() + { + $options = array('testA' => 1, 'testB' => 2); + $valid = array('testA', 'testB', 'testC'); + $expected = array('testA' => 1, 'testB' => 2, 'testC' => null); + $validated = PHPUnit_Util_XML::assertValidKeys($options, $valid); + + $this->assertEquals($expected, $validated); + } + + public function testAssertValidKeysDefaultValuesA() + { + $options = array('testA' => 1, 'testB' => 2); + $valid = array('testA' => 23, 'testB' => 24, 'testC' => 25); + $expected = array('testA' => 1, 'testB' => 2, 'testC' => 25); + $validated = PHPUnit_Util_XML::assertValidKeys($options, $valid); + + $this->assertEquals($expected, $validated); + } + + public function testAssertValidKeysDefaultValuesB() + { + $options = array(); + $valid = array('testA' => 23, 'testB' => 24, 'testC' => 25); + $expected = array('testA' => 23, 'testB' => 24, 'testC' => 25); + $validated = PHPUnit_Util_XML::assertValidKeys($options, $valid); + + $this->assertEquals($expected, $validated); + } + + public function testAssertValidKeysInvalidKey() + { + $options = array('testA' => 1, 'testB' => 2, 'testD' => 3); + $valid = array('testA', 'testB', 'testC'); + + try { + $validated = PHPUnit_Util_XML::assertValidKeys($options, $valid); + $this->fail(); + } catch (PHPUnit_Framework_Exception $e) { + $this->assertEquals('Unknown key(s): testD', $e->getMessage()); + } + } + + public function testAssertValidKeysInvalidKeys() + { + $options = array('testA' => 1, 'testD' => 2, 'testE' => 3); + $valid = array('testA', 'testB', 'testC'); + + try { + $validated = PHPUnit_Util_XML::assertValidKeys($options, $valid); + $this->fail(); + } catch (PHPUnit_Framework_Exception $e) { + $this->assertEquals('Unknown key(s): testD, testE', $e->getMessage()); + } + } + + public function testConvertAssertSelect() + { + $selector = 'div#folder.open a[href="http://www.xerox.com"][title="xerox"].selected.big > span + h1'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', + 'id' => 'folder', + 'class' => 'open', + 'descendant' => array('tag' => 'a', + 'class' => 'selected big', + 'attributes' => array('href' => 'http://www.xerox.com', + 'title' => 'xerox'), + 'child' => array('tag' => 'span', + 'adjacent-sibling' => array('tag' => 'h1')))); + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectElt() + { + $selector = 'div'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div'); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertClass() + { + $selector = '.foo'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('class' => 'foo'); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertId() + { + $selector = '#foo'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('id' => 'foo'); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertAttribute() + { + $selector = '[foo="bar"]'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('attributes' => array('foo' => 'bar')); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertAttributeSpaces() + { + $selector = '[foo="bar baz"] div[value="foo bar"]'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('attributes' => array('foo' => 'bar baz'), + 'descendant' => array('tag' => 'div', + 'attributes' => array('value' => 'foo bar'))); + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertAttributeMultipleSpaces() + { + $selector = '[foo="bar baz"] div[value="foo bar baz"]'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('attributes' => array('foo' => 'bar baz'), + 'descendant' => array('tag' => 'div', + 'attributes' => array('value' => 'foo bar baz'))); + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectEltClass() + { + $selector = 'div.foo'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', 'class' => 'foo'); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectEltId() + { + $selector = 'div#foo'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', 'id' => 'foo'); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectEltAttrEqual() + { + $selector = 'div[foo="bar"]'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', 'attributes' => array('foo' => 'bar')); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectEltMultiAttrEqual() + { + $selector = 'div[foo="bar"][baz="fob"]'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', 'attributes' => array('foo' => 'bar', 'baz' => 'fob')); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectEltAttrHasOne() + { + $selector = 'div[foo~="bar"]'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', 'attributes' => array('foo' => 'regexp:/.*\bbar\b.*/')); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectEltAttrContains() + { + $selector = 'div[foo*="bar"]'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', 'attributes' => array('foo' => 'regexp:/.*bar.*/')); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectEltChild() + { + $selector = 'div > a'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', 'child' => array('tag' => 'a')); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectEltAdjacentSibling() + { + $selector = 'div + a'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', 'adjacent-sibling' => array('tag' => 'a')); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectEltDescendant() + { + $selector = 'div a'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector); + $tag = array('tag' => 'div', 'descendant' => array('tag' => 'a')); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectContent() + { + $selector = '#foo'; + $content = 'div contents'; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector, $content); + $tag = array('id' => 'foo', 'content' => 'div contents'); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectTrue() + { + $selector = '#foo'; + $content = true; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector, $content); + $tag = array('id' => 'foo'); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertSelectFalse() + { + $selector = '#foo'; + $content = false; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector, $content); + $tag = array('id' => 'foo'); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertNumber() + { + $selector = '.foo'; + $content = 3; + $converted = PHPUnit_Util_XML::convertSelectToTag($selector, $content); + $tag = array('class' => 'foo'); + + $this->assertEquals($tag, $converted); + } + + public function testConvertAssertRange() + { + $selector = '#foo'; + $content = array('greater_than' => 5, 'less_than' => 10); + $converted = PHPUnit_Util_XML::convertSelectToTag($selector, $content); + $tag = array('id' => 'foo'); + + $this->assertEquals($tag, $converted); + } + + /** + * @dataProvider charProvider + */ + public function testPrepareString($char) + { + $e = null; + + $escapedString = PHPUnit_Util_XML::prepareString($char); + $xml = "$escapedString"; + $dom = new DomDocument('1.0', 'UTF-8'); + + try { + $dom->loadXML($xml); + } catch (Exception $e) { + } + + $this->assertNull($e, sprintf( + 'PHPUnit_Util_XML::prepareString("\x%02x") should not crash DomDocument', + ord($char) + )); + } + + public function charProvider() + { + $data = array(); + + for ($i = 0; $i < 256; $i++) { + $data[] = array(chr($i)); + } + + return $data; + } + + /** + * @expectedException PHPUnit_Framework_Exception + * @expectedExceptionMessage Could not load XML from empty string + */ + public function testLoadEmptyString() + { + PHPUnit_Util_XML::load(''); + } + + /** + * @expectedException PHPUnit_Framework_Exception + * @expectedExceptionMessage Could not load XML from array + */ + public function testLoadArray() + { + PHPUnit_Util_XML::load(array(1, 2, 3)); + } + + /** + * @expectedException PHPUnit_Framework_Exception + * @expectedExceptionMessage Could not load XML from boolean + */ + public function testLoadBoolean() + { + PHPUnit_Util_XML::load(false); + } + + public function testNestedXmlToVariable() + { + $xml = 'foobar'; + $dom = new DOMDocument(); + $dom->loadXML($xml); + + $expected = array( + 'a' => array( + 'b' => 'foo', + ), + 'c' => 'bar', + ); + + $actual = PHPUnit_Util_XML::xmlToVariable($dom->documentElement); + + $this->assertSame($expected, $actual); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/AbstractTest.php b/vendor/phpunit/phpunit/tests/_files/AbstractTest.php new file mode 100644 index 000000000..556e7dbc0 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/AbstractTest.php @@ -0,0 +1,7 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * An author. + * + * @since Class available since Release 3.6.0 + */ +class Author +{ + // the order of properties is important for testing the cycle! + public $books = array(); + + private $name = ''; + + public function __construct($name) + { + $this->name = $name; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/BankAccount.php b/vendor/phpunit/phpunit/tests/_files/BankAccount.php new file mode 100644 index 000000000..30596a45f --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/BankAccount.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +class BankAccountException extends RuntimeException +{ +} + +/** + * A bank account. + * + * @since Class available since Release 2.3.0 + */ +class BankAccount +{ + /** + * The bank account's balance. + * + * @var float + */ + protected $balance = 0; + + /** + * Returns the bank account's balance. + * + * @return float + */ + public function getBalance() + { + return $this->balance; + } + + /** + * Sets the bank account's balance. + * + * @param float $balance + * + * @throws BankAccountException + */ + protected function setBalance($balance) + { + if ($balance >= 0) { + $this->balance = $balance; + } else { + throw new BankAccountException; + } + } + + /** + * Deposits an amount of money to the bank account. + * + * @param float $balance + * + * @throws BankAccountException + */ + public function depositMoney($balance) + { + $this->setBalance($this->getBalance() + $balance); + + return $this->getBalance(); + } + + /** + * Withdraws an amount of money from the bank account. + * + * @param float $balance + * + * @throws BankAccountException + */ + public function withdrawMoney($balance) + { + $this->setBalance($this->getBalance() - $balance); + + return $this->getBalance(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/BankAccountTest.php b/vendor/phpunit/phpunit/tests/_files/BankAccountTest.php new file mode 100644 index 000000000..b8e7061ea --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/BankAccountTest.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Tests for the BankAccount class. + * + * @since Class available since Release 2.3.0 + */ +class BankAccountTest extends PHPUnit_Framework_TestCase +{ + protected $ba; + + protected function setUp() + { + $this->ba = new BankAccount; + } + + /** + * @covers BankAccount::getBalance + * @group balanceIsInitiallyZero + * @group specification + */ + public function testBalanceIsInitiallyZero() + { + $this->assertEquals(0, $this->ba->getBalance()); + } + + /** + * @covers BankAccount::withdrawMoney + * @group balanceCannotBecomeNegative + * @group specification + */ + public function testBalanceCannotBecomeNegative() + { + try { + $this->ba->withdrawMoney(1); + } catch (BankAccountException $e) { + $this->assertEquals(0, $this->ba->getBalance()); + + return; + } + + $this->fail(); + } + + /** + * @covers BankAccount::depositMoney + * @group balanceCannotBecomeNegative + * @group specification + */ + public function testBalanceCannotBecomeNegative2() + { + try { + $this->ba->depositMoney(-1); + } catch (BankAccountException $e) { + $this->assertEquals(0, $this->ba->getBalance()); + + return; + } + + $this->fail(); + } + + /* + * @covers BankAccount::getBalance + * @covers BankAccount::depositMoney + * @covers BankAccount::withdrawMoney + * @group balanceCannotBecomeNegative + */ + /* + public function testDepositingAndWithdrawingMoneyWorks() + { + $this->assertEquals(0, $this->ba->getBalance()); + $this->ba->depositMoney(1); + $this->assertEquals(1, $this->ba->getBalance()); + $this->ba->withdrawMoney(1); + $this->assertEquals(0, $this->ba->getBalance()); + } + */ +} diff --git a/vendor/phpunit/phpunit/tests/_files/BankAccountTest.test.php b/vendor/phpunit/phpunit/tests/_files/BankAccountTest.test.php new file mode 100644 index 000000000..371cc7711 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/BankAccountTest.test.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Tests for the BankAccount class. + * + * @since Class available since Release 2.3.0 + */ +class BankAccountWithCustomExtensionTest extends PHPUnit_Framework_TestCase +{ + protected $ba; + + protected function setUp() + { + $this->ba = new BankAccount; + } + + /** + * @covers BankAccount::getBalance + * @group balanceIsInitiallyZero + * @group specification + */ + public function testBalanceIsInitiallyZero() + { + $this->assertEquals(0, $this->ba->getBalance()); + } + + /** + * @covers BankAccount::withdrawMoney + * @group balanceCannotBecomeNegative + * @group specification + */ + public function testBalanceCannotBecomeNegative() + { + try { + $this->ba->withdrawMoney(1); + } catch (BankAccountException $e) { + $this->assertEquals(0, $this->ba->getBalance()); + + return; + } + + $this->fail(); + } + + /** + * @covers BankAccount::depositMoney + * @group balanceCannotBecomeNegative + * @group specification + */ + public function testBalanceCannotBecomeNegative2() + { + try { + $this->ba->depositMoney(-1); + } catch (BankAccountException $e) { + $this->assertEquals(0, $this->ba->getBalance()); + + return; + } + + $this->fail(); + } + + /* + * @covers BankAccount::getBalance + * @covers BankAccount::depositMoney + * @covers BankAccount::withdrawMoney + * @group balanceCannotBecomeNegative + */ + /* + public function testDepositingAndWithdrawingMoneyWorks() + { + $this->assertEquals(0, $this->ba->getBalance()); + $this->ba->depositMoney(1); + $this->assertEquals(1, $this->ba->getBalance()); + $this->ba->withdrawMoney(1); + $this->assertEquals(0, $this->ba->getBalance()); + } + */ +} diff --git a/vendor/phpunit/phpunit/tests/_files/BaseTestListenerSample.php b/vendor/phpunit/phpunit/tests/_files/BaseTestListenerSample.php new file mode 100644 index 000000000..7753b280a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/BaseTestListenerSample.php @@ -0,0 +1,11 @@ +endCount++; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/BeforeAndAfterTest.php b/vendor/phpunit/phpunit/tests/_files/BeforeAndAfterTest.php new file mode 100644 index 000000000..0b52526ae --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/BeforeAndAfterTest.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A book. + * + * @since Class available since Release 3.6.0 + */ +class Book +{ + // the order of properties is important for testing the cycle! + public $author = null; +} diff --git a/vendor/phpunit/phpunit/tests/_files/Calculator.php b/vendor/phpunit/phpunit/tests/_files/Calculator.php new file mode 100644 index 000000000..e269bd6ca --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/Calculator.php @@ -0,0 +1,14 @@ +assertTrue(true); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/ClassWithNonPublicAttributes.php b/vendor/phpunit/phpunit/tests/_files/ClassWithNonPublicAttributes.php new file mode 100644 index 000000000..abc8ff66d --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/ClassWithNonPublicAttributes.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A class with a __toString() method. + * + * @since Class available since Release 3.6.0 + */ +class ClassWithToString +{ + public function __toString() + { + return 'string representation'; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/ConcreteTest.my.php b/vendor/phpunit/phpunit/tests/_files/ConcreteTest.my.php new file mode 100644 index 000000000..fe01ceed5 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/ConcreteTest.my.php @@ -0,0 +1,7 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageClassTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageClassTest.php new file mode 100644 index 000000000..7f569ae60 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageClassTest.php @@ -0,0 +1,12 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesTest.php new file mode 100644 index 000000000..33b5fe3de --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesTest.php @@ -0,0 +1,11 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesTest.php new file mode 100644 index 000000000..422300457 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesTest.php @@ -0,0 +1,12 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesWhitespaceTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesWhitespaceTest.php new file mode 100644 index 000000000..d1be1c6cf --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesWhitespaceTest.php @@ -0,0 +1,12 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageMethodTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageMethodTest.php new file mode 100644 index 000000000..167b3db4c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageMethodTest.php @@ -0,0 +1,12 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNamespacedFunctionTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNamespacedFunctionTest.php new file mode 100644 index 000000000..9fc056fa3 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageNamespacedFunctionTest.php @@ -0,0 +1,11 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNotPrivateTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNotPrivateTest.php new file mode 100644 index 000000000..12b56e80e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageNotPrivateTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNotProtectedTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNotProtectedTest.php new file mode 100644 index 000000000..c69d261de --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageNotProtectedTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNotPublicTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNotPublicTest.php new file mode 100644 index 000000000..aebfe4bd9 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageNotPublicTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNothingTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNothingTest.php new file mode 100644 index 000000000..5d5680d93 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageNothingTest.php @@ -0,0 +1,13 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoveragePrivateTest.php b/vendor/phpunit/phpunit/tests/_files/CoveragePrivateTest.php new file mode 100644 index 000000000..f09560d3a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoveragePrivateTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageProtectedTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageProtectedTest.php new file mode 100644 index 000000000..9b3acbf6c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageProtectedTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoveragePublicTest.php b/vendor/phpunit/phpunit/tests/_files/CoveragePublicTest.php new file mode 100644 index 000000000..480a522b4 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoveragePublicTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageTwoDefaultClassAnnotations.php b/vendor/phpunit/phpunit/tests/_files/CoverageTwoDefaultClassAnnotations.php new file mode 100644 index 000000000..1011769f7 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoverageTwoDefaultClassAnnotations.php @@ -0,0 +1,17 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoveredClass.php b/vendor/phpunit/phpunit/tests/_files/CoveredClass.php new file mode 100644 index 000000000..f382ce99b --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoveredClass.php @@ -0,0 +1,36 @@ +privateMethod(); + } + + public function publicMethod() + { + $this->protectedMethod(); + } +} + +class CoveredClass extends CoveredParentClass +{ + private function privateMethod() + { + } + + protected function protectedMethod() + { + parent::protectedMethod(); + $this->privateMethod(); + } + + public function publicMethod() + { + parent::publicMethod(); + $this->protectedMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/CoveredFunction.php b/vendor/phpunit/phpunit/tests/_files/CoveredFunction.php new file mode 100644 index 000000000..9989eb02e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/CoveredFunction.php @@ -0,0 +1,4 @@ +assertTrue(true); + } + + public static function provider() + { + $obj2 = new \stdClass(); + $obj2->foo = 'bar'; + + $obj3 = (object) array(1,2,"Test\r\n",4,5,6,7,8); + + $obj = new \stdClass(); + //@codingStandardsIgnoreStart + $obj->null = null; + //@codingStandardsIgnoreEnd + $obj->boolean = true; + $obj->integer = 1; + $obj->double = 1.2; + $obj->string = '1'; + $obj->text = "this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext"; + $obj->object = $obj2; + $obj->objectagain = $obj2; + $obj->array = array('foo' => 'bar'); + $obj->self = $obj; + + $storage = new \SplObjectStorage(); + $storage->attach($obj2); + $storage->foo = $obj2; + + return array( + array(null, true, 1, 1.0), + array(1.2, fopen('php://memory', 'r'), '1'), + array(array(array(1,2,3), array(3,4,5))), + // \n\r and \r is converted to \n + array("this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext"), + array(new \stdClass(), $obj, array(), $storage, $obj3), + array(chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5), implode('', array_map('chr', range(0x0e, 0x1f)))), + array(chr(0x00) . chr(0x09)) + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderFilterTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderFilterTest.php new file mode 100644 index 000000000..a872bc992 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/DataProviderFilterTest.php @@ -0,0 +1,39 @@ +assertTrue($truth); + } + + public static function truthProvider() + { + return array( + array(true), + array(true), + array(true), + array(true) + ); + } + + /** + * @dataProvider falseProvider + */ + public function testFalse($false) + { + $this->assertFalse($false); + } + + public static function falseProvider() + { + return array( + 'false test' => array(false), + 'false test 2' => array(false), + 'other false test' => array(false), + 'other false test2'=> array(false) + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderIncompleteTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderIncompleteTest.php new file mode 100644 index 000000000..e0efb5bc0 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/DataProviderIncompleteTest.php @@ -0,0 +1,37 @@ +assertTrue(true); + } + + /** + * @dataProvider providerMethod + */ + public function testAdd($a, $b, $c) + { + $this->assertEquals($c, $a + $b); + } + + public function incompleteTestProviderMethod() + { + $this->markTestIncomplete('incomplete'); + + return array( + array(0, 0, 0), + array(0, 1, 1), + ); + } + + public static function providerMethod() + { + return array( + array(0, 0, 0), + array(0, 1, 1), + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderSkippedTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderSkippedTest.php new file mode 100644 index 000000000..ec67ce55f --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/DataProviderSkippedTest.php @@ -0,0 +1,37 @@ +assertTrue(true); + } + + /** + * @dataProvider providerMethod + */ + public function testAdd($a, $b, $c) + { + $this->assertEquals($c, $a + $b); + } + + public function skippedTestProviderMethod() + { + $this->markTestSkipped('skipped'); + + return array( + array(0, 0, 0), + array(0, 1, 1), + ); + } + + public static function providerMethod() + { + return array( + array(0, 0, 0), + array(0, 1, 1), + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderTest.php new file mode 100644 index 000000000..d940a0595 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/DataProviderTest.php @@ -0,0 +1,21 @@ +assertEquals($c, $a + $b); + } + + public static function providerMethod() + { + return array( + array(0, 0, 0), + array(0, 1, 1), + array(1, 1, 3), + array(1, 0, 1) + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/DependencyFailureTest.php b/vendor/phpunit/phpunit/tests/_files/DependencyFailureTest.php new file mode 100644 index 000000000..d83aecd82 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/DependencyFailureTest.php @@ -0,0 +1,22 @@ +fail(); + } + + /** + * @depends testOne + */ + public function testTwo() + { + } + + /** + * @depends testTwo + */ + public function testThree() + { + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/DependencySuccessTest.php b/vendor/phpunit/phpunit/tests/_files/DependencySuccessTest.php new file mode 100644 index 000000000..0e4b5ddeb --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/DependencySuccessTest.php @@ -0,0 +1,21 @@ +addTestSuite('DependencySuccessTest'); + $suite->addTestSuite('DependencyFailureTest'); + + return $suite; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/DoubleTestCase.php b/vendor/phpunit/phpunit/tests/_files/DoubleTestCase.php new file mode 100644 index 000000000..b1f00a8ff --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/DoubleTestCase.php @@ -0,0 +1,25 @@ +testCase = $testCase; + } + + public function count() + { + return 2; + } + + public function run(PHPUnit_Framework_TestResult $result = null) + { + $result->startTest($this); + + $this->testCase->runBare(); + $this->testCase->runBare(); + + $result->endTest($this, 0); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/DummyException.php b/vendor/phpunit/phpunit/tests/_files/DummyException.php new file mode 100644 index 000000000..29a69b997 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/DummyException.php @@ -0,0 +1,5 @@ +setUp = true; + } + + protected function assertPreConditions() + { + $this->assertPreConditions = true; + } + + public function testSomething() + { + $this->testSomething = true; + } + + protected function assertPostConditions() + { + $this->assertPostConditions = true; + throw new Exception; + } + + protected function tearDown() + { + $this->tearDown = true; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPreConditionsTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPreConditionsTest.php new file mode 100644 index 000000000..a375d0508 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPreConditionsTest.php @@ -0,0 +1,35 @@ +setUp = true; + } + + protected function assertPreConditions() + { + $this->assertPreConditions = true; + throw new Exception; + } + + public function testSomething() + { + $this->testSomething = true; + } + + protected function assertPostConditions() + { + $this->assertPostConditions = true; + } + + protected function tearDown() + { + $this->tearDown = true; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionInSetUpTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionInSetUpTest.php new file mode 100644 index 000000000..193b9a822 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/ExceptionInSetUpTest.php @@ -0,0 +1,35 @@ +setUp = true; + throw new Exception; + } + + protected function assertPreConditions() + { + $this->assertPreConditions = true; + } + + public function testSomething() + { + $this->testSomething = true; + } + + protected function assertPostConditions() + { + $this->assertPostConditions = true; + } + + protected function tearDown() + { + $this->tearDown = true; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionInTearDownTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionInTearDownTest.php new file mode 100644 index 000000000..5ee4a9d13 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/ExceptionInTearDownTest.php @@ -0,0 +1,35 @@ +setUp = true; + } + + protected function assertPreConditions() + { + $this->assertPreConditions = true; + } + + public function testSomething() + { + $this->testSomething = true; + } + + protected function assertPostConditions() + { + $this->assertPostConditions = true; + } + + protected function tearDown() + { + $this->tearDown = true; + throw new Exception; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionInTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionInTest.php new file mode 100644 index 000000000..32c7e24a8 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/ExceptionInTest.php @@ -0,0 +1,35 @@ +setUp = true; + } + + protected function assertPreConditions() + { + $this->assertPreConditions = true; + } + + public function testSomething() + { + $this->testSomething = true; + throw new Exception; + } + + protected function assertPostConditions() + { + $this->assertPostConditions = true; + } + + protected function tearDown() + { + $this->tearDown = true; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionNamespaceTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionNamespaceTest.php new file mode 100644 index 000000000..22f3760b5 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/ExceptionNamespaceTest.php @@ -0,0 +1,38 @@ +assertEquals(array(1), array(2), 'message'); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $message = $e->getMessage() . $e->getComparisonFailure()->getDiff(); + throw new PHPUnit_Framework_Exception("Child exception\n$message", 101, $e); + } + } + + public function testNestedExceptions() + { + $exceptionThree = new Exception('Three'); + $exceptionTwo = new InvalidArgumentException('Two', 0, $exceptionThree); + $exceptionOne = new Exception('One', 0, $exceptionTwo); + throw $exceptionOne; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionTest.php new file mode 100644 index 000000000..021380529 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/ExceptionTest.php @@ -0,0 +1,139 @@ +fail(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/FailureTest.php b/vendor/phpunit/phpunit/tests/_files/FailureTest.php new file mode 100644 index 000000000..e9df755ae --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/FailureTest.php @@ -0,0 +1,75 @@ +assertEquals(array(1), array(2), 'message'); + } + + public function testAssertIntegerEqualsInteger() + { + $this->assertEquals(1, 2, 'message'); + } + + public function testAssertObjectEqualsObject() + { + $a = new StdClass; + $a->foo = 'bar'; + + $b = new StdClass; + $b->bar = 'foo'; + + $this->assertEquals($a, $b, 'message'); + } + + public function testAssertNullEqualsString() + { + $this->assertEquals(null, 'bar', 'message'); + } + + public function testAssertStringEqualsString() + { + $this->assertEquals('foo', 'bar', 'message'); + } + + public function testAssertTextEqualsText() + { + $this->assertEquals("foo\nbar\n", "foo\nbaz\n", 'message'); + } + + public function testAssertStringMatchesFormat() + { + $this->assertStringMatchesFormat('*%s*', '**', 'message'); + } + + public function testAssertNumericEqualsNumeric() + { + $this->assertEquals(1, 2, 'message'); + } + + public function testAssertTextSameText() + { + $this->assertSame('foo', 'bar', 'message'); + } + + public function testAssertObjectSameObject() + { + $this->assertSame(new StdClass, new StdClass, 'message'); + } + + public function testAssertObjectSameNull() + { + $this->assertSame(new StdClass, null, 'message'); + } + + public function testAssertFloatSameFloat() + { + $this->assertSame(1.0, 1.5, 'message'); + } + + // Note that due to the implementation of this assertion it counts as 2 asserts + public function testAssertStringMatchesFormatFile() + { + $this->assertStringMatchesFormatFile(__DIR__ . '/expectedFileFormat.txt', '...BAR...'); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/FatalTest.php b/vendor/phpunit/phpunit/tests/_files/FatalTest.php new file mode 100644 index 000000000..bf005f992 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/FatalTest.php @@ -0,0 +1,13 @@ +markTestIncomplete('Test incomplete'); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceA.php b/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceA.php new file mode 100644 index 000000000..e189b7d2a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceA.php @@ -0,0 +1,7 @@ +assertEquals('application/x-test', ini_get('default_mimetype')); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/IsolationTest.php b/vendor/phpunit/phpunit/tests/_files/IsolationTest.php new file mode 100644 index 000000000..df95c9168 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/IsolationTest.php @@ -0,0 +1,13 @@ +assertFalse($this->isInIsolation()); + } + + public function testIsInIsolationReturnsTrue() + { + $this->assertTrue($this->isInIsolation()); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/JsonData/arrayObject.json b/vendor/phpunit/phpunit/tests/_files/JsonData/arrayObject.json new file mode 100644 index 000000000..8a74fc587 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/JsonData/arrayObject.json @@ -0,0 +1 @@ +["Mascott", "Tux", "OS", "Linux"] diff --git a/vendor/phpunit/phpunit/tests/_files/JsonData/simpleObject.json b/vendor/phpunit/phpunit/tests/_files/JsonData/simpleObject.json new file mode 100644 index 000000000..27085be25 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/JsonData/simpleObject.json @@ -0,0 +1 @@ +{"Mascott":"Tux"} \ No newline at end of file diff --git a/vendor/phpunit/phpunit/tests/_files/MockRunner.php b/vendor/phpunit/phpunit/tests/_files/MockRunner.php new file mode 100644 index 000000000..b3bc0cc48 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/MockRunner.php @@ -0,0 +1,7 @@ +assertEquals('foo', $a); + $this->assertEquals('bar', $b); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassExtendedTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassExtendedTest.php new file mode 100644 index 000000000..d0954cba9 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassExtendedTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassTest.php new file mode 100644 index 000000000..63912c089 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassTest.php @@ -0,0 +1,12 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassPublicTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassPublicTest.php new file mode 100644 index 000000000..45f583b77 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassPublicTest.php @@ -0,0 +1,15 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassTest.php new file mode 100644 index 000000000..b33674546 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassTest.php @@ -0,0 +1,20 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageMethodTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageMethodTest.php new file mode 100644 index 000000000..35dfb8b1d --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageMethodTest.php @@ -0,0 +1,12 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPrivateTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPrivateTest.php new file mode 100644 index 000000000..552c9ec50 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPrivateTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotProtectedTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotProtectedTest.php new file mode 100644 index 000000000..33fc8c72c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotProtectedTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPublicTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPublicTest.php new file mode 100644 index 000000000..ccbc5009c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPublicTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePrivateTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePrivateTest.php new file mode 100644 index 000000000..cce7ba9d6 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePrivateTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageProtectedTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageProtectedTest.php new file mode 100644 index 000000000..dbbcc1c31 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageProtectedTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePublicTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePublicTest.php new file mode 100644 index 000000000..bf1bff8c4 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePublicTest.php @@ -0,0 +1,12 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredClass.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredClass.php new file mode 100644 index 000000000..5bd0ddfb2 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredClass.php @@ -0,0 +1,38 @@ +privateMethod(); + } + + public function publicMethod() + { + $this->protectedMethod(); + } +} + +class CoveredClass extends CoveredParentClass +{ + private function privateMethod() + { + } + + protected function protectedMethod() + { + parent::protectedMethod(); + $this->privateMethod(); + } + + public function publicMethod() + { + parent::publicMethod(); + $this->protectedMethod(); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredFunction.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredFunction.php new file mode 100644 index 000000000..afc00d7c3 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredFunction.php @@ -0,0 +1,7 @@ + + */ + public function testThree() + { + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/NotPublicTestCase.php b/vendor/phpunit/phpunit/tests/_files/NotPublicTestCase.php new file mode 100644 index 000000000..a39101000 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/NotPublicTestCase.php @@ -0,0 +1,11 @@ +expectOutputString('foo'); + print 'foo'; + } + + public function testExpectOutputStringFooActualBar() + { + $this->expectOutputString('foo'); + print 'bar'; + } + + public function testExpectOutputRegexFooActualFoo() + { + $this->expectOutputRegex('/foo/'); + print 'foo'; + } + + public function testExpectOutputRegexFooActualBar() + { + $this->expectOutputRegex('/foo/'); + print 'bar'; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/OverrideTestCase.php b/vendor/phpunit/phpunit/tests/_files/OverrideTestCase.php new file mode 100644 index 000000000..fcc276c50 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/OverrideTestCase.php @@ -0,0 +1,7 @@ +container = array(); + } + public function offsetSet($offset, $value) + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + public function offsetExists($offset) + { + return isset($this->container[$offset]); + } + public function offsetUnset($offset) + { + unset($this->container[$offset]); + } + public function offsetGet($offset) + { + return isset($this->container[$offset]) ? $this->container[$offset] : null; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/SampleClass.php b/vendor/phpunit/phpunit/tests/_files/SampleClass.php new file mode 100644 index 000000000..06c51c510 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/SampleClass.php @@ -0,0 +1,14 @@ +a = $a; + $this->b = $b; + $this->c = $c; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/Singleton.php b/vendor/phpunit/phpunit/tests/_files/Singleton.php new file mode 100644 index 000000000..bfdf3bb0a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/Singleton.php @@ -0,0 +1,22 @@ +assertEquals(0, count($stack)); + + array_push($stack, 'foo'); + $this->assertEquals('foo', $stack[count($stack)-1]); + $this->assertEquals(1, count($stack)); + + return $stack; + } + + /** + * @depends testPush + */ + public function testPop(array $stack) + { + $this->assertEquals('foo', array_pop($stack)); + $this->assertEquals(0, count($stack)); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/StatusTest.php b/vendor/phpunit/phpunit/tests/_files/StatusTest.php new file mode 100644 index 000000000..a267bb727 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/StatusTest.php @@ -0,0 +1,32 @@ +assertTrue(true); + } + + public function testFailure() + { + $this->assertTrue(false); + } + + public function testError() + { + throw new \Exception; + } + + public function testIncomplete() + { + $this->markTestIncomplete(); + } + + public function testSkipped() + { + $this->markTestSkipped(); + } + + public function testRisky() + { + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/Struct.php b/vendor/phpunit/phpunit/tests/_files/Struct.php new file mode 100644 index 000000000..12977a996 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/Struct.php @@ -0,0 +1,10 @@ +var = $var; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/Success.php b/vendor/phpunit/phpunit/tests/_files/Success.php new file mode 100644 index 000000000..6d3dd6188 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/Success.php @@ -0,0 +1,7 @@ +assertTrue(true); + } + + public function testTwo() + { + print __METHOD__ . "\n"; + $this->assertTrue(false); + } + + protected function assertPostConditions() + { + print __METHOD__ . "\n"; + } + + protected function tearDown() + { + print __METHOD__ . "\n"; + } + + public static function tearDownAfterClass() + { + print __METHOD__ . "\n"; + } + + protected function onNotSuccessfulTest(Exception $e) + { + print __METHOD__ . "\n"; + throw $e; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/TestIncomplete.php b/vendor/phpunit/phpunit/tests/_files/TestIncomplete.php new file mode 100644 index 000000000..743a761cc --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/TestIncomplete.php @@ -0,0 +1,8 @@ +markTestIncomplete('Incomplete test'); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/TestIterator.php b/vendor/phpunit/phpunit/tests/_files/TestIterator.php new file mode 100644 index 000000000..01135e3b3 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/TestIterator.php @@ -0,0 +1,36 @@ +array = $array; + } + + public function rewind() + { + $this->position = 0; + } + + public function valid() + { + return $this->position < count($this->array); + } + + public function key() + { + return $this->position; + } + + public function current() + { + return $this->array[$this->position]; + } + + public function next() + { + $this->position++; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/TestIterator2.php b/vendor/phpunit/phpunit/tests/_files/TestIterator2.php new file mode 100644 index 000000000..3b47fa367 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/TestIterator2.php @@ -0,0 +1,35 @@ +data = $array; + } + + public function current() + { + return current($this->data); + } + + public function next() + { + next($this->data); + } + + public function key() + { + return key($this->data); + } + + public function valid() + { + return key($this->data) !== null; + } + + public function rewind() + { + reset($this->data); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/TestSkipped.php b/vendor/phpunit/phpunit/tests/_files/TestSkipped.php new file mode 100644 index 000000000..c2d68b246 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/TestSkipped.php @@ -0,0 +1,8 @@ +markTestSkipped('Skipped test'); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/TestTestError.php b/vendor/phpunit/phpunit/tests/_files/TestTestError.php new file mode 100644 index 000000000..6f61b8ed6 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/TestTestError.php @@ -0,0 +1,8 @@ +assertEquals($c, $a + $b); + } + + public static function providerMethod() + { + return array( + array(0, 0, 0), + array(0, 1, 1), + array(1, 1, 3), + array(1, 0, 1) + ); + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/ThrowExceptionTestCase.php b/vendor/phpunit/phpunit/tests/_files/ThrowExceptionTestCase.php new file mode 100644 index 000000000..1d2a769ae --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/ThrowExceptionTestCase.php @@ -0,0 +1,8 @@ +wasRun = true; + } +} diff --git a/vendor/phpunit/phpunit/tests/_files/bar.xml b/vendor/phpunit/phpunit/tests/_files/bar.xml new file mode 100644 index 000000000..5d3fa282a --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/bar.xml @@ -0,0 +1 @@ + diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.colors.empty.xml b/vendor/phpunit/phpunit/tests/_files/configuration.colors.empty.xml new file mode 100644 index 000000000..5f9e05565 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/configuration.colors.empty.xml @@ -0,0 +1 @@ + diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.colors.false.xml b/vendor/phpunit/phpunit/tests/_files/configuration.colors.false.xml new file mode 100644 index 000000000..dcd4aa47e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/configuration.colors.false.xml @@ -0,0 +1 @@ + diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.colors.invalid.xml b/vendor/phpunit/phpunit/tests/_files/configuration.colors.invalid.xml new file mode 100644 index 000000000..c5bd6990e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/configuration.colors.invalid.xml @@ -0,0 +1 @@ + diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.colors.true.xml b/vendor/phpunit/phpunit/tests/_files/configuration.colors.true.xml new file mode 100644 index 000000000..1efe41325 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/configuration.colors.true.xml @@ -0,0 +1 @@ + diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.custom-printer.xml b/vendor/phpunit/phpunit/tests/_files/configuration.custom-printer.xml new file mode 100644 index 000000000..7a5a1f1d9 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/configuration.custom-printer.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.xml b/vendor/phpunit/phpunit/tests/_files/configuration.xml new file mode 100644 index 000000000..7a23dae07 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/configuration.xml @@ -0,0 +1,123 @@ + + + + + + /path/to/files + /path/to/MyTest.php + + + + + + name + + + name + + + + + + /path/to/files + /path/to/file + + /path/to/file + + + /path/to/files + /path/to/file + + + + /path/to/files + /path/to/file + + /path/to/files + /path/to/file + + + + + + + + + + Sebastian + + + 22 + April + 19.78 + + + MyTestFile.php + MyRelativePath + + + + 42 + + + + + + + + + + + + + + + . + /path/to/lib + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/phpunit/tests/_files/configuration_empty.xml b/vendor/phpunit/phpunit/tests/_files/configuration_empty.xml new file mode 100644 index 000000000..13c8b71d5 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/configuration_empty.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/phpunit/tests/_files/configuration_xinclude.xml b/vendor/phpunit/phpunit/tests/_files/configuration_xinclude.xml new file mode 100644 index 000000000..43076297d --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/configuration_xinclude.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + . + /path/to/lib + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/phpunit/tests/_files/expectedFileFormat.txt b/vendor/phpunit/phpunit/tests/_files/expectedFileFormat.txt new file mode 100644 index 000000000..b7d6715e2 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/expectedFileFormat.txt @@ -0,0 +1 @@ +FOO diff --git a/vendor/phpunit/phpunit/tests/_files/foo.xml b/vendor/phpunit/phpunit/tests/_files/foo.xml new file mode 100644 index 000000000..f1999f80c --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/foo.xml @@ -0,0 +1 @@ + diff --git a/vendor/phpunit/phpunit/tests/_files/structureAttributesAreSameButValuesAreNot.xml b/vendor/phpunit/phpunit/tests/_files/structureAttributesAreSameButValuesAreNot.xml new file mode 100644 index 000000000..a5d9ab335 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/structureAttributesAreSameButValuesAreNot.xml @@ -0,0 +1,10 @@ + + + + + + + Image 1: Dette er en test caption + + + diff --git a/vendor/phpunit/phpunit/tests/_files/structureExpected.xml b/vendor/phpunit/phpunit/tests/_files/structureExpected.xml new file mode 100644 index 000000000..d9001059e --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/structureExpected.xml @@ -0,0 +1,10 @@ + + + + + + + Image 1: Dette er en test caption + + + diff --git a/vendor/phpunit/phpunit/tests/_files/structureIgnoreTextNodes.xml b/vendor/phpunit/phpunit/tests/_files/structureIgnoreTextNodes.xml new file mode 100644 index 000000000..0771b60ca --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/structureIgnoreTextNodes.xml @@ -0,0 +1,13 @@ + + + + textnode + + textnode + + textnode + Image 1: Dette er en test caption + textnode + + + diff --git a/vendor/phpunit/phpunit/tests/_files/structureIsSameButDataIsNot.xml b/vendor/phpunit/phpunit/tests/_files/structureIsSameButDataIsNot.xml new file mode 100644 index 000000000..2ba21b981 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/structureIsSameButDataIsNot.xml @@ -0,0 +1,10 @@ + + + + + + + Image is not the same 1: Dette er en test caption + + + diff --git a/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfAttributes.xml b/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfAttributes.xml new file mode 100644 index 000000000..af9b97416 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfAttributes.xml @@ -0,0 +1,10 @@ + + + + + + + Image 1: Dette er en test caption + + + diff --git a/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfNodes.xml b/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfNodes.xml new file mode 100644 index 000000000..9a394e232 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfNodes.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/vendor/phpunit/phpunit/tests/bootstrap.php b/vendor/phpunit/phpunit/tests/bootstrap.php new file mode 100644 index 000000000..cc79889b7 --- /dev/null +++ b/vendor/phpunit/phpunit/tests/bootstrap.php @@ -0,0 +1,6 @@ + [ + 'src/', + 'vendor/dnoegel/php-xdg-base-dir/src/', + 'vendor/doctrine/instantiator/src/', + 'vendor/hoa/console/', + 'vendor/jakub-onderka/php-console-color/src/', + 'vendor/jakub-onderka/php-console-highlighter/src/', + 'vendor/nikic/php-parser/lib/', + 'vendor/phpdocumentor/reflection-docblock/', + 'vendor/symfony/console/', + 'vendor/symfony/filesystem/', + 'vendor/symfony/finder/', + 'vendor/symfony/var-dumper/', + ], + + // A directory list that defines files that will be excluded + // from static analysis, but whose class and method + // information should be included. + // + // Generally, you'll want to include the directories for + // third-party code (such as "vendor/") in this list. + // + // n.b.: If you'd like to parse but not analyze 3rd + // party code, directories containing that code + // should be added to both the `directory_list` + // and `exclude_analysis_directory_list` arrays. + "exclude_analysis_directory_list" => [ + 'vendor/' + ], +]; diff --git a/vendor/psy/psysh/.php_cs b/vendor/psy/psysh/.php_cs new file mode 100644 index 000000000..4b82f8534 --- /dev/null +++ b/vendor/psy/psysh/.php_cs @@ -0,0 +1,44 @@ +level(FixerInterface::SYMFONY_LEVEL) + ->fixers(array( + 'align_double_arrow', + 'concat_with_spaces', + 'header_comment', + 'long_array_syntax', + 'ordered_use', + 'strict', + '-concat_without_spaces', + '-method_argument_space', + '-pre_increment', + '-unalign_double_arrow', + '-unalign_equals', + '-no_empty_comment', // stop removing slashes in the middle of multi-line comments + )) + ->setUsingLinter(false); + +$finder = $config->getFinder() + ->in(__DIR__) + ->name('.php_cs') + ->name('build-manual') + ->name('build-phar') + ->exclude('build-vendor'); + +return $config; diff --git a/vendor/psy/psysh/.styleci.yml b/vendor/psy/psysh/.styleci.yml new file mode 100644 index 000000000..c6fa14691 --- /dev/null +++ b/vendor/psy/psysh/.styleci.yml @@ -0,0 +1,22 @@ +preset: symfony + +enabled: + - align_double_arrow + - concat_with_spaces + - long_array_syntax + - ordered_use + - strict + +disabled: + - concat_without_spaces + - method_argument_space + - pre_increment + - unalign_double_arrow + - unalign_equals + +finder: + name: + - "*.php" + - ".php_cs" + - "build-manual" + - "build-phar" diff --git a/vendor/psy/psysh/.travis.yml b/vendor/psy/psysh/.travis.yml new file mode 100644 index 000000000..187ae933d --- /dev/null +++ b/vendor/psy/psysh/.travis.yml @@ -0,0 +1,35 @@ +sudo: false +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - hhvm + # - hhvm-nightly + +matrix: + allow_failures: + - php: hhvm + - php: hhvm-nightly + +install: travis_retry composer update --no-interaction --prefer-source + +script: vendor/bin/phpunit + +before_deploy: bin/package -v $TRAVIS_TAG + +deploy: + provider: releases + api_key: + secure: LL8koDM1xDqzF9t0URHvmMPyWjojyd4PeZ7IW7XYgyvD6n1H6GYrVAeKCh5wfUKFbwHoa9s5AAn6pLzra00bODVkPTmUH+FSMWz9JKLw9ODAn8HvN7C+IooxmeClGHFZc0TfHfya8/D1E9C1iXtGGEoE/GqtaYq/z0C1DLpO0OU= + file_glob: true + file: dist/psysh-*.tar.gz + skip_cleanup: true + on: + tags: true + repo: bobthecow/psysh + condition: ($TRAVIS_PHP_VERSION = 5.3* || $TRAVIS_PHP_VERSION = 7.1*) diff --git a/vendor/psy/psysh/CONTRIBUTING.md b/vendor/psy/psysh/CONTRIBUTING.md new file mode 100644 index 000000000..a5c726ba2 --- /dev/null +++ b/vendor/psy/psysh/CONTRIBUTING.md @@ -0,0 +1,18 @@ +## Code style + +Please make your code look like the other code in the project. PsySH follows [PSR-1](http://php-fig.org/psr/psr-1/) and [PSR-2](http://php-fig.org/psr/psr-2/). The easiest way to do make sure you're following the coding standard is to run `vendor/bin/php-cs-fixer fix` before committing. + +## Branching model + +Please branch off and send pull requests to the `develop` branch. + +## Building the manual + +```sh +svn co https://svn.php.net/repository/phpdoc/en/trunk/reference/ php_manual +bin/build_manual phpdoc_manual ~/.local/share/psysh/php_manual.sqlite +``` + +To build the manual for another language, switch out `en` above for `de`, `es`, or any of the other languages listed in the docs. + +[Partial or outdated documentation is available for other languages](http://www.php.net/manual/help-translate.php) but these translations are outdated, so their content may be completely wrong or insecure! diff --git a/vendor/psy/psysh/README.md b/vendor/psy/psysh/README.md new file mode 100644 index 000000000..45dd6a3b2 --- /dev/null +++ b/vendor/psy/psysh/README.md @@ -0,0 +1,33 @@ +# PsySH + +PsySH is a runtime developer console, interactive debugger and [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) for PHP. Learn more at [psysh.org](http://psysh.org/) and [in the manual](https://github.com/bobthecow/psysh/wiki/Home). + + +[![Package version](https://img.shields.io/packagist/v/psy/psysh.svg?style=flat-square)](https://packagist.org/packages/psy/psysh) +[![Monthly downloads](http://img.shields.io/packagist/dm/psy/psysh.svg?style=flat-square)](https://packagist.org/packages/psy/psysh) +[![Made out of awesome](https://img.shields.io/badge/made_out_of_awesome-✓-brightgreen.svg?style=flat-square)](http://psysh.org) + +[![Build status](https://img.shields.io/travis/bobthecow/psysh/master.svg?style=flat-square)](http://travis-ci.org/bobthecow/psysh) +[![StyleCI](https://styleci.io/repos/4549925/shield)](https://styleci.io/repos/4549925) + + + + +## [PsySH manual](https://github.com/bobthecow/psysh/wiki/Home) + +### [💾 Installation](https://github.com/bobthecow/psysh/wiki/Installation) + * [📕 PHP manual installation](https://github.com/bobthecow/psysh/wiki/PHP-manual) + +### [🖥 Usage](https://github.com/bobthecow/psysh/wiki/Usage) + * [✨ Magic variables](https://github.com/bobthecow/psysh/wiki/Magic-variables) + * [⏳ Managing history](https://github.com/bobthecow/psysh/wiki/History) + * [💲 System shell integration](https://github.com/bobthecow/psysh/wiki/Shell-integration) + * [🎥 Tutorials & guides](https://github.com/bobthecow/psysh/wiki/Tutorials) + +### [📢 Commands](https://github.com/bobthecow/psysh/wiki/Commands) + +### [🛠 Configuration](https://github.com/bobthecow/psysh/wiki/Configuration) + * [🎛 Config options](https://github.com/bobthecow/psysh/wiki/Config-options) + * [📄 Sample config file](https://github.com/bobthecow/psysh/wiki/Sample-config) + +### [🔌 Integrations](https://github.com/bobthecow/psysh/wiki/Integrations) diff --git a/vendor/psy/psysh/bin/build b/vendor/psy/psysh/bin/build index 3a3c34f92..1c1540304 100755 --- a/vendor/psy/psysh/bin/build +++ b/vendor/psy/psysh/bin/build @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -ev +set -e cd "${BASH_SOURCE%/*}/.." diff --git a/vendor/psy/psysh/bin/build-manual b/vendor/psy/psysh/bin/build-manual index e9ce518da..20fbfa4c2 100755 --- a/vendor/psy/psysh/bin/build-manual +++ b/vendor/psy/psysh/bin/build-manual @@ -85,7 +85,7 @@ function extract_paragraphs($element) foreach ($element->getElementsByTagName('para') as $p) { $text = ''; foreach ($p->childNodes as $child) { - // @todo: figure out if there's something we can do with tables. + // @todo figure out if there's something we can do with tables. if ($child instanceof DOMElement && $child->tagName === 'table') { continue; } diff --git a/vendor/psy/psysh/bin/build-phar b/vendor/psy/psysh/bin/build-phar index e5151eeaa..43db2f6b7 100755 --- a/vendor/psy/psysh/bin/build-phar +++ b/vendor/psy/psysh/bin/build-phar @@ -1,4 +1,4 @@ -#!/usr/bin/env php -d phar.readonly=Off +#!/usr/bin/env php + + + ./test + + + + + ./src/Psy + + + diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner.php b/vendor/psy/psysh/src/Psy/CodeCleaner.php index d2c152303..15cc16729 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner.php @@ -25,9 +25,11 @@ use Psy\CodeCleaner\ImplicitReturnPass; use Psy\CodeCleaner\InstanceOfPass; use Psy\CodeCleaner\LeavePsyshAlonePass; use Psy\CodeCleaner\LegacyEmptyPass; +use Psy\CodeCleaner\LoopContextPass; use Psy\CodeCleaner\MagicConstantsPass; use Psy\CodeCleaner\NamespacePass; use Psy\CodeCleaner\PassableByReferencePass; +use Psy\CodeCleaner\RequirePass; use Psy\CodeCleaner\StaticConstructorPass; use Psy\CodeCleaner\StrictTypesPass; use Psy\CodeCleaner\UseStatementPass; @@ -88,9 +90,11 @@ class CodeCleaner new InstanceOfPass(), new LeavePsyshAlonePass(), new LegacyEmptyPass(), + new LoopContextPass(), new ImplicitReturnPass(), new UseStatementPass(), // must run before namespace and validation passes new NamespacePass($this), // must run after the implicit return pass + new RequirePass(), new StrictTypesPass(), new StaticConstructorPass(), new ValidFunctionNamePass(), diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/AbstractClassPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/AbstractClassPass.php index a6a20c00c..fad6d8f56 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/AbstractClassPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/AbstractClassPass.php @@ -12,7 +12,7 @@ namespace Psy\CodeCleaner; use PhpParser\Node; -use PhpParser\Node\Stmt\Class_ as ClassStmt; +use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use Psy\Exception\FatalErrorException; @@ -31,7 +31,7 @@ class AbstractClassPass extends CodeCleanerPass */ public function enterNode(Node $node) { - if ($node instanceof ClassStmt) { + if ($node instanceof Class_) { $this->class = $node; $this->abstractMethods = array(); } elseif ($node instanceof ClassMethod) { @@ -40,7 +40,8 @@ class AbstractClassPass extends CodeCleanerPass $this->abstractMethods[] = $name; if ($node->stmts !== null) { - throw new FatalErrorException(sprintf('Abstract function %s cannot contain body', $name)); + $msg = sprintf('Abstract function %s cannot contain body', $name); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } } @@ -53,16 +54,17 @@ class AbstractClassPass extends CodeCleanerPass */ public function leaveNode(Node $node) { - if ($node instanceof ClassStmt) { + if ($node instanceof Class_) { $count = count($this->abstractMethods); if ($count > 0 && !$node->isAbstract()) { - throw new FatalErrorException(sprintf( + $msg = sprintf( 'Class %s contains %d abstract method%s must therefore be declared abstract or implement the remaining methods (%s)', $node->name, $count, - ($count === 0) ? '' : 's', + ($count === 1) ? '' : 's', implode(', ', $this->abstractMethods) - )); + ); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/AssignThisVariablePass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/AssignThisVariablePass.php index 68beb3bad..b1b3eaf1d 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/AssignThisVariablePass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/AssignThisVariablePass.php @@ -11,7 +11,7 @@ namespace Psy\CodeCleaner; -use PhpParser\Node as Node; +use PhpParser\Node; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\Variable; use Psy\Exception\FatalErrorException; @@ -33,7 +33,7 @@ class AssignThisVariablePass extends CodeCleanerPass public function enterNode(Node $node) { if ($node instanceof Assign && $node->var instanceof Variable && $node->var->name === 'this') { - throw new FatalErrorException('Cannot re-assign $this'); + throw new FatalErrorException('Cannot re-assign $this', 0, E_ERROR, null, $node->getLine()); } } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/CallTimePassByReferencePass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/CallTimePassByReferencePass.php index 19f85349f..5a5eeba12 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/CallTimePassByReferencePass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/CallTimePassByReferencePass.php @@ -12,7 +12,7 @@ namespace Psy\CodeCleaner; use PhpParser\Node; -use PhpParser\Node\Expr\FuncCall as FunctionCall; +use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; use Psy\Exception\FatalErrorException; @@ -26,6 +26,8 @@ use Psy\Exception\FatalErrorException; */ class CallTimePassByReferencePass extends CodeCleanerPass { + const EXCEPTION_MESSAGE = 'Call-time pass-by-reference has been removed'; + /** * Validate of use call-time pass-by-reference. * @@ -39,13 +41,13 @@ class CallTimePassByReferencePass extends CodeCleanerPass return; } - if (!$node instanceof FunctionCall && !$node instanceof MethodCall && !$node instanceof StaticCall) { + if (!$node instanceof FuncCall && !$node instanceof MethodCall && !$node instanceof StaticCall) { return; } foreach ($node->args as $arg) { if ($arg->byRef) { - throw new FatalErrorException('Call-time pass-by-reference has been removed'); + throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); } } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/CalledClassPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/CalledClassPass.php index 5204898c7..4a0f7ea8e 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/CalledClassPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/CalledClassPass.php @@ -15,8 +15,8 @@ use PhpParser\Node; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name; -use PhpParser\Node\Stmt\Class_ as ClassStmt; -use PhpParser\Node\Stmt\Trait_ as TraitStmt; +use PhpParser\Node\Stmt\Class_; +use PhpParser\Node\Stmt\Trait_; use Psy\Exception\ErrorException; /** @@ -42,13 +42,13 @@ class CalledClassPass extends CodeCleanerPass */ public function enterNode(Node $node) { - if ($node instanceof ClassStmt || $node instanceof TraitStmt) { + if ($node instanceof Class_ || $node instanceof Trait_) { $this->inClass = true; } elseif ($node instanceof FuncCall && !$this->inClass) { // We'll give any args at all (besides null) a pass. // Technically we should be checking whether the args are objects, but this will do for now. // - // TODO: switch this to actually validate args when we get context-aware code cleaner passes. + // @todo switch this to actually validate args when we get context-aware code cleaner passes. if (!empty($node->args) && !$this->isNull($node->args[0])) { return; } @@ -71,7 +71,7 @@ class CalledClassPass extends CodeCleanerPass */ public function leaveNode(Node $node) { - if ($node instanceof ClassStmt) { + if ($node instanceof Class_) { $this->inClass = false; } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/ExitPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/ExitPass.php index 44e6df0d9..bdd132a7f 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/ExitPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/ExitPass.php @@ -12,12 +12,9 @@ namespace Psy\CodeCleaner; use PhpParser\Node; -use PhpParser\Node\Arg; use PhpParser\Node\Expr\Exit_; -use PhpParser\Node\Expr\New_; -use PhpParser\Node\Name; -use PhpParser\Node\Scalar\String_; -use PhpParser\Node\Stmt\Throw_; +use PhpParser\Node\Expr\StaticCall; +use PhpParser\Node\Name\FullyQualified as FullyQualifiedName; class ExitPass extends CodeCleanerPass { @@ -29,9 +26,7 @@ class ExitPass extends CodeCleanerPass public function leaveNode(Node $node) { if ($node instanceof Exit_) { - $args = array(new Arg(new String_('Goodbye.'))); - - return new Throw_(new New_(new Name('Psy\Exception\BreakException'), $args)); + return new StaticCall(new FullyQualifiedName('Psy\Exception\BreakException'), 'exitShell'); } } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/FinalClassPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/FinalClassPass.php index 57f7ab72d..c509bef50 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/FinalClassPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/FinalClassPass.php @@ -12,7 +12,7 @@ namespace Psy\CodeCleaner; use PhpParser\Node; -use PhpParser\Node\Stmt\Class_ as ClassStmt; +use PhpParser\Node\Stmt\Class_; use Psy\Exception\FatalErrorException; /** @@ -37,12 +37,12 @@ class FinalClassPass extends CodeCleanerPass */ public function enterNode(Node $node) { - if ($node instanceof ClassStmt) { + if ($node instanceof Class_) { if ($node->extends) { $extends = (string) $node->extends; if ($this->isFinalClass($extends)) { $msg = sprintf('Class %s may not inherit from final class (%s)', $node->name, $extends); - throw new FatalErrorException($msg); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionReturnInWriteContextPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionReturnInWriteContextPass.php index fd3430eaa..de2530619 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionReturnInWriteContextPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionReturnInWriteContextPass.php @@ -12,11 +12,11 @@ namespace Psy\CodeCleaner; use PhpParser\Node; -use PhpParser\Node\Expr\Array_ as ArrayNode; -use PhpParser\Node\Expr\Assign as AssignNode; -use PhpParser\Node\Expr\Empty_ as EmptyNode; -use PhpParser\Node\Expr\FuncCall as FunctionCall; -use PhpParser\Node\Expr\Isset_ as IssetNode; +use PhpParser\Node\Expr\Array_; +use PhpParser\Node\Expr\Assign; +use PhpParser\Node\Expr\Empty_; +use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Expr\Isset_; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; use Psy\Exception\FatalErrorException; @@ -28,6 +28,7 @@ use Psy\Exception\FatalErrorException; */ class FunctionReturnInWriteContextPass extends CodeCleanerPass { + const PHP55_MESSAGE = 'Cannot use isset() on the result of a function call (you can use "null !== func()" instead)'; const EXCEPTION_MESSAGE = "Can't use function return value in write context"; private $isPhp55; @@ -49,34 +50,31 @@ class FunctionReturnInWriteContextPass extends CodeCleanerPass */ public function enterNode(Node $node) { - if ($node instanceof ArrayNode || $this->isCallNode($node)) { - $items = $node instanceof ArrayNode ? $node->items : $node->args; + if ($node instanceof Array_ || $this->isCallNode($node)) { + $items = $node instanceof Array_ ? $node->items : $node->args; foreach ($items as $item) { if ($item->byRef && $this->isCallNode($item->value)) { - throw new FatalErrorException(self::EXCEPTION_MESSAGE); + throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); } } - } elseif ($node instanceof IssetNode) { + } elseif ($node instanceof Isset_) { foreach ($node->vars as $var) { if (!$this->isCallNode($var)) { continue; } - if ($this->isPhp55) { - throw new FatalErrorException('Cannot use isset() on the result of a function call (you can use "null !== func()" instead)'); - } else { - throw new FatalErrorException(self::EXCEPTION_MESSAGE); - } + $msg = $this->isPhp55 ? self::PHP55_MESSAGE : self::EXCEPTION_MESSAGE; + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } - } elseif ($node instanceof EmptyNode && !$this->isPhp55 && $this->isCallNode($node->expr)) { - throw new FatalErrorException(self::EXCEPTION_MESSAGE); - } elseif ($node instanceof AssignNode && $this->isCallNode($node->var)) { - throw new FatalErrorException(self::EXCEPTION_MESSAGE); + } elseif ($node instanceof Empty_ && !$this->isPhp55 && $this->isCallNode($node->expr)) { + throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); + } elseif ($node instanceof Assign && $this->isCallNode($node->var)) { + throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); } } private function isCallNode(Node $node) { - return $node instanceof FunctionCall || $node instanceof MethodCall || $node instanceof StaticCall; + return $node instanceof FuncCall || $node instanceof MethodCall || $node instanceof StaticCall; } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/ImplicitReturnPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/ImplicitReturnPass.php index 431b9c467..c738bdc12 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/ImplicitReturnPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/ImplicitReturnPass.php @@ -13,7 +13,14 @@ namespace Psy\CodeCleaner; use PhpParser\Node\Expr; use PhpParser\Node\Expr\Exit_; -use PhpParser\Node\Stmt\Return_ as ReturnStmt; +use PhpParser\Node\Expr\New_; +use PhpParser\Node\Name\FullyQualified as FullyQualifiedName; +use PhpParser\Node\Stmt; +use PhpParser\Node\Stmt\Break_; +use PhpParser\Node\Stmt\If_; +use PhpParser\Node\Stmt\Namespace_; +use PhpParser\Node\Stmt\Return_; +use PhpParser\Node\Stmt\Switch_; /** * Add an implicit "return" to the last statement, provided it can be returned. @@ -22,16 +29,72 @@ class ImplicitReturnPass extends CodeCleanerPass { /** * @param array $nodes + * + * @return array */ public function beforeTraverse(array $nodes) { + return $this->addImplicitReturn($nodes); + } + + /** + * @param array $nodes + * + * @return array + */ + private function addImplicitReturn(array $nodes) + { + // If nodes is empty, it can't have a return value. + if (empty($nodes)) { + return array(new Return_(new New_(new FullyQualifiedName('Psy\CodeCleaner\NoReturnValue')))); + } + $last = end($nodes); - if ($last instanceof Expr && !($last instanceof Exit_)) { - $nodes[count($nodes) - 1] = new ReturnStmt($last, array( + // Special case a few types of statements to add an implicit return + // value (even though they technically don't have any return value) + // because showing a return value in these instances is useful and not + // very surprising. + if ($last instanceof If_) { + $last->stmts = $this->addImplicitReturn($last->stmts); + + foreach ($last->elseifs as $elseif) { + $elseif->stmts = $this->addImplicitReturn($elseif->stmts); + } + + if ($last->else) { + $last->else->stmts = $this->addImplicitReturn($last->else->stmts); + } + } elseif ($last instanceof Switch_) { + foreach ($last->cases as $case) { + // only add an implicit return to cases which end in break + $caseLast = end($case->stmts); + if ($caseLast instanceof Break_) { + $case->stmts = $this->addImplicitReturn(array_slice($case->stmts, 0, -1)); + $case->stmts[] = $caseLast; + } + } + } elseif ($last instanceof Expr && !($last instanceof Exit_)) { + $nodes[count($nodes) - 1] = new Return_($last, array( 'startLine' => $last->getLine(), 'endLine' => $last->getLine(), )); + } elseif ($last instanceof Namespace_) { + $last->stmts = $this->addImplicitReturn($last->stmts); + } + + // Return a "no return value" for all non-expression statements, so that + // PsySH can suppress the `null` that `eval()` returns otherwise. + // + // Note that statements special cased above (if/elseif/else, switch) + // _might_ implicitly return a value before this catch-all return is + // reached. + // + // We're not adding a fallback return after namespace statements, + // because code outside namespace statements doesn't really work, and + // there's already an implicit return in the namespace statement anyway. + if ($last instanceof Stmt && !$last instanceof Return_ && !$last instanceof Namespace_) { + $nodes[] = new Return_(new New_(new FullyQualifiedName('Psy\CodeCleaner\NoReturnValue'))); } return $nodes; diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/InstanceOfPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/InstanceOfPass.php index 7c2ae7bb3..78ce98e93 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/InstanceOfPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/InstanceOfPass.php @@ -13,7 +13,7 @@ namespace Psy\CodeCleaner; use PhpParser\Node; use PhpParser\Node\Expr\ConstFetch; -use PhpParser\Node\Expr\Instanceof_ as InstanceofStmt; +use PhpParser\Node\Expr\Instanceof_; use PhpParser\Node\Scalar; use PhpParser\Node\Scalar\Encapsed; use Psy\Exception\FatalErrorException; @@ -25,6 +25,8 @@ use Psy\Exception\FatalErrorException; */ class InstanceOfPass extends CodeCleanerPass { + const EXCEPTION_MSG = 'instanceof expects an object instance, constant given'; + /** * Validate that the instanceof statement does not receive a scalar value or a non-class constant. * @@ -34,12 +36,12 @@ class InstanceOfPass extends CodeCleanerPass */ public function enterNode(Node $node) { - if (!$node instanceof InstanceofStmt) { + if (!$node instanceof Instanceof_) { return; } if (($node->expr instanceof Scalar && !$node->expr instanceof Encapsed) || $node->expr instanceof ConstFetch) { - throw new FatalErrorException('instanceof expects an object instance, constant given'); + throw new FatalErrorException(self::EXCEPTION_MSG, 0, E_ERROR, null, $node->getLine()); } } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/LegacyEmptyPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/LegacyEmptyPass.php index f0c89402c..dc5a01ed7 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/LegacyEmptyPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/LegacyEmptyPass.php @@ -12,7 +12,7 @@ namespace Psy\CodeCleaner; use PhpParser\Node; -use PhpParser\Node\Expr\Empty_ as ExprEmpty; +use PhpParser\Node\Expr\Empty_; use PhpParser\Node\Expr\Variable; use Psy\Exception\ParseErrorException; @@ -35,7 +35,7 @@ class LegacyEmptyPass extends CodeCleanerPass return; } - if (!$node instanceof ExprEmpty) { + if (!$node instanceof Empty_) { return; } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/LoopContextPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/LoopContextPass.php new file mode 100644 index 000000000..e8f65bb9e --- /dev/null +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/LoopContextPass.php @@ -0,0 +1,109 @@ +isPHP54 = version_compare(PHP_VERSION, '5.4.0', '>='); + } + + /** + * {@inheritdoc} + */ + public function beforeTraverse(array $nodes) + { + $this->loopDepth = 0; + } + + /** + * @throws FatalErrorException if the node is a break or continue in a non-loop or switch context + * @throws FatalErrorException if the node is trying to break out of more nested structures than exist + * @throws FatalErrorException if the node is a break or continue and has a non-numeric argument + * @throws FatalErrorException if the node is a break or continue and has an argument less than 1 + * + * @param Node $node + */ + public function enterNode(Node $node) + { + switch (true) { + case $node instanceof Do_: + case $node instanceof For_: + case $node instanceof Foreach_: + case $node instanceof Switch_: + case $node instanceof While_: + $this->loopDepth++; + break; + + case $node instanceof Break_: + case $node instanceof Continue_: + $operator = $node instanceof Break_ ? 'break' : 'continue'; + + if ($this->loopDepth === 0) { + $msg = sprintf("'%s' not in the 'loop' or 'switch' context", $operator); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); + } + + if ($node->num instanceof LNumber || $node->num instanceof DNumber) { + $num = $node->num->value; + if ($this->isPHP54 && ($node->num instanceof DNumber || $num < 1)) { + $msg = sprintf("'%s' operator accepts only positive numbers", $operator); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); + } + + if ($num > $this->loopDepth) { + $msg = sprintf("Cannot '%s' %d levels", $operator, $num); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); + } + } elseif ($node->num && $this->isPHP54) { + $msg = sprintf("'%s' operator with non-constant operand is no longer supported", $operator); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); + } + break; + } + } + + /** + * @param Node $node + */ + public function leaveNode(Node $node) + { + switch (true) { + case $node instanceof Do_: + case $node instanceof For_: + case $node instanceof Foreach_: + case $node instanceof Switch_: + case $node instanceof While_: + $this->loopDepth--; + break; + } + } +} diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/MagicConstantsPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/MagicConstantsPass.php index 3a6cd603c..328eb256a 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/MagicConstantsPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/MagicConstantsPass.php @@ -16,7 +16,7 @@ use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name; use PhpParser\Node\Scalar\MagicConst\Dir; use PhpParser\Node\Scalar\MagicConst\File; -use PhpParser\Node\Scalar\String_ as StringNode; +use PhpParser\Node\Scalar\String_; /** * Swap out __DIR__ and __FILE__ magic constants with our best guess? @@ -29,14 +29,14 @@ class MagicConstantsPass extends CodeCleanerPass * * @param Node $node * - * @return null|FuncCall|StringNode + * @return null|FuncCall|String_ */ public function enterNode(Node $node) { if ($node instanceof Dir) { return new FuncCall(new Name('getcwd'), array(), $node->getAttributes()); } elseif ($node instanceof File) { - return new StringNode('', $node->getAttributes()); + return new String_('', $node->getAttributes()); } } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/NamespaceAwarePass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/NamespaceAwarePass.php index 5982e4f3a..4a76d0f64 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/NamespaceAwarePass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/NamespaceAwarePass.php @@ -14,7 +14,7 @@ namespace Psy\CodeCleaner; use PhpParser\Node; use PhpParser\Node\Name; use PhpParser\Node\Name\FullyQualified as FullyQualifiedName; -use PhpParser\Node\Stmt\Namespace_ as NamespaceStmt; +use PhpParser\Node\Stmt\Namespace_; /** * Abstract namespace-aware code cleaner pass. @@ -25,10 +25,10 @@ abstract class NamespaceAwarePass extends CodeCleanerPass protected $currentScope; /** - * TODO: should this be final? Extending classes should be sure to either + * @todo should this be final? Extending classes should be sure to either * use afterTraverse or call parent::beforeTraverse() when overloading. * - * Reset the namespace and the current scope before beginning analysis. + * Reset the namespace and the current scope before beginning analysis */ public function beforeTraverse(array $nodes) { @@ -37,14 +37,14 @@ abstract class NamespaceAwarePass extends CodeCleanerPass } /** - * TODO: should this be final? Extending classes should be sure to either use - * leaveNode or call parent::enterNode() when overloading. + * @todo should this be final? Extending classes should be sure to either use + * leaveNode or call parent::enterNode() when overloading * * @param Node $node */ public function enterNode(Node $node) { - if ($node instanceof NamespaceStmt) { + if ($node instanceof Namespace_) { $this->namespace = isset($node->name) ? $node->name->parts : array(); } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/NamespacePass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/NamespacePass.php index 40cc6bb3e..37ef9f240 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/NamespacePass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/NamespacePass.php @@ -12,7 +12,7 @@ namespace Psy\CodeCleaner; use PhpParser\Node\Name; -use PhpParser\Node\Stmt\Namespace_ as NamespaceStmt; +use PhpParser\Node\Stmt\Namespace_; use Psy\CodeCleaner; /** @@ -49,19 +49,17 @@ class NamespacePass extends CodeCleanerPass */ public function beforeTraverse(array $nodes) { - $first = reset($nodes); - if (count($nodes) === 1 && $first instanceof NamespaceStmt && empty($first->stmts)) { - $this->setNamespace($first->name); - } else { - foreach ($nodes as $key => $node) { - if ($node instanceof NamespaceStmt) { - $this->setNamespace(null); - } elseif ($this->namespace !== null) { - $nodes[$key] = new NamespaceStmt($this->namespace, array($node)); - } - } + if (empty($nodes)) { + return $nodes; } + $last = end($nodes); + if (!$last instanceof Namespace_) { + return $this->namespace ? array(new Namespace_($this->namespace, $nodes)) : $nodes; + } + + $this->setNamespace($last->name); + return $nodes; } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/NoReturnValue.php b/vendor/psy/psysh/src/Psy/CodeCleaner/NoReturnValue.php new file mode 100644 index 000000000..3784f4b35 --- /dev/null +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/NoReturnValue.php @@ -0,0 +1,24 @@ +name; - // if function name is an expression or a variable, give it a pass for now. - if ($name instanceof Expr || $name instanceof Variable) { + if ($node->name instanceof Expr || $node->name instanceof Variable) { return; } + $name = (string) $node->name; + + if ($name === 'array_multisort') { + return $this->validateArrayMultisort($node); + } + try { - $refl = new \ReflectionFunction(implode('\\', $name->parts)); + $refl = new \ReflectionFunction($name); } catch (\ReflectionException $e) { // Well, we gave it a shot! return; @@ -55,7 +59,7 @@ class PassableByReferencePass extends CodeCleanerPass if (array_key_exists($key, $node->args)) { $arg = $node->args[$key]; if ($param->isPassedByReference() && !$this->isPassableByReference($arg)) { - throw new FatalErrorException(self::EXCEPTION_MESSAGE); + throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); } } } @@ -73,4 +77,33 @@ class PassableByReferencePass extends CodeCleanerPass $arg->value instanceof MethodCall || $arg->value instanceof StaticCall; } + + /** + * Because array_multisort has a problematic signature... + * + * The argument order is all sorts of wonky, and whether something is passed + * by reference or not depends on the values of the two arguments before it. + * We'll do a good faith attempt at validating this, but err on the side of + * permissive. + * + * This is why you don't design languages where core code and extensions can + * implement APIs that wouldn't be possible in userland code. + * + * @throws FatalErrorException for clearly invalid arguments + * + * @param Node $node + */ + private function validateArrayMultisort(Node $node) + { + $nonPassable = 2; // start with 2 because the first one has to be passable by reference + foreach ($node->args as $arg) { + if ($this->isPassableByReference($arg)) { + $nonPassable = 0; + } elseif (++$nonPassable > 2) { + // There can be *at most* two non-passable-by-reference args in a row. This is about + // as close as we can get to validating the arguments for this function :-/ + throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); + } + } + } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/RequirePass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/RequirePass.php new file mode 100644 index 000000000..6d205e6d2 --- /dev/null +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/RequirePass.php @@ -0,0 +1,98 @@ +isRequireNode($node)) { + return; + } + + /* + * rewrite + * + * $foo = require $bar + * + * to + * + * $foo = Psy\CodeCleaner\RequirePass::resolve($bar) + */ + return new StaticCall( + new FullyQualifiedName('Psy\CodeCleaner\RequirePass'), + 'resolve', + array(new Arg($node->expr), new Arg(new LNumber($node->getLine()))), + $node->getAttributes() + ); + } + + /** + * Runtime validation that $file can be resolved as an include path. + * + * If $file can be resolved, return $file. Otherwise throw a fatal error exception. + * + * @throws FatalErrorException when unable to resolve include path for $file + * @throws ErrorException if $file is empty and E_WARNING is included in error_reporting level + * + * @param string $file + * @param int $lineNumber Line number of the original require expression + * + * @return string Exactly the same as $file + */ + public static function resolve($file, $lineNumber = null) + { + $file = (string) $file; + + if ($file === '') { + // @todo Shell::handleError would be better here, because we could + // fake the file and line number, but we can't call it statically. + // So we're duplicating some of the logics here. + if (E_WARNING & error_reporting()) { + ErrorException::throwException(E_WARNING, 'Filename cannot be empty', null, $lineNumber); + } else { + // @todo trigger an error as fallback? this is pretty ugly… + // trigger_error('Filename cannot be empty', E_USER_WARNING); + } + } + + if ($file === '' || !stream_resolve_include_path($file)) { + $msg = sprintf("Failed opening required '%s'", $file); + throw new FatalErrorException($msg, 0, E_ERROR, null, $lineNumber); + } + + return $file; + } + + private function isRequireNode(Node $node) + { + return $node instanceof Include_ && in_array($node->type, self::$requireTypes); + } +} diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/StaticConstructorPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/StaticConstructorPass.php index f0748a42b..d1c72c23c 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/StaticConstructorPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/StaticConstructorPass.php @@ -12,9 +12,9 @@ namespace Psy\CodeCleaner; use PhpParser\Node; -use PhpParser\Node\Stmt\Class_ as ClassStmt; +use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; -use PhpParser\Node\Stmt\Namespace_ as NamespaceStmt; +use PhpParser\Node\Stmt\Namespace_; use Psy\Exception\FatalErrorException; /** @@ -51,9 +51,9 @@ class StaticConstructorPass extends CodeCleanerPass */ public function enterNode(Node $node) { - if ($node instanceof NamespaceStmt) { + if ($node instanceof Namespace_) { $this->namespace = isset($node->name) ? $node->name->parts : array(); - } elseif ($node instanceof ClassStmt) { + } elseif ($node instanceof Class_) { // Bail early if this is PHP 5.3.3 and we have a namespaced class if (!empty($this->namespace) && $this->isPHP533) { return; @@ -76,11 +76,12 @@ class StaticConstructorPass extends CodeCleanerPass } if ($constructor && $constructor->isStatic()) { - throw new FatalErrorException(sprintf( + $msg = sprintf( 'Constructor %s::%s() cannot be static', implode('\\', array_merge($this->namespace, (array) $node->name)), $constructor->name - )); + ); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/StrictTypesPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/StrictTypesPass.php index c75d00779..5966f0c51 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/StrictTypesPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/StrictTypesPass.php @@ -12,7 +12,7 @@ namespace Psy\CodeCleaner; use PhpParser\Node\Scalar\LNumber; -use PhpParser\Node\Stmt\Declare_ as DeclareStmt; +use PhpParser\Node\Stmt\Declare_; use PhpParser\Node\Stmt\DeclareDeclare; use Psy\Exception\FatalErrorException; @@ -28,6 +28,8 @@ use Psy\Exception\FatalErrorException; */ class StrictTypesPass extends CodeCleanerPass { + const EXCEPTION_MESSAGE = 'strict_types declaration must have 0 or 1 as its value'; + private $strictTypes = false; /** @@ -49,12 +51,12 @@ class StrictTypesPass extends CodeCleanerPass $prependStrictTypes = $this->strictTypes; foreach ($nodes as $key => $node) { - if ($node instanceof DeclareStmt) { + if ($node instanceof Declare_) { foreach ($node->declares as $declare) { if ($declare->key === 'strict_types') { $value = $declare->value; if (!$value instanceof LNumber || ($value->value !== 0 && $value->value !== 1)) { - throw new FatalErrorException('strict_types declaration must have 0 or 1 as its value'); + throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); } $this->strictTypes = $value->value === 1; @@ -65,8 +67,8 @@ class StrictTypesPass extends CodeCleanerPass if ($prependStrictTypes) { $first = reset($nodes); - if (!$first instanceof DeclareStmt) { - $declare = new DeclareStmt(array(new DeclareDeclare('strict_types', new LNumber(1)))); + if (!$first instanceof Declare_) { + $declare = new Declare_(array(new DeclareDeclare('strict_types', new LNumber(1)))); array_unshift($nodes, $declare); } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/UseStatementPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/UseStatementPass.php index 93bc7cb70..c1ce64d3e 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/UseStatementPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/UseStatementPass.php @@ -14,9 +14,9 @@ namespace Psy\CodeCleaner; use PhpParser\Node; use PhpParser\Node\Name; use PhpParser\Node\Name\FullyQualified as FullyQualifiedName; -use PhpParser\Node\Stmt\GroupUse as GroupUseStmt; -use PhpParser\Node\Stmt\Namespace_ as NamespaceStmt; -use PhpParser\Node\Stmt\Use_ as UseStmt; +use PhpParser\Node\Stmt\GroupUse; +use PhpParser\Node\Stmt\Namespace_; +use PhpParser\Node\Stmt\Use_; /** * Provide implicit use statements for subsequent execution. @@ -28,7 +28,7 @@ use PhpParser\Node\Stmt\Use_ as UseStmt; * ... which it then applies implicitly to all future evaluated code, until the * current namespace is replaced by another namespace. */ -class UseStatementPass extends NamespaceAwarePass +class UseStatementPass extends CodeCleanerPass { private $aliases = array(); private $lastAliases = array(); @@ -45,7 +45,7 @@ class UseStatementPass extends NamespaceAwarePass */ public function enterNode(Node $node) { - if ($node instanceof NamespaceStmt) { + if ($node instanceof Namespace_) { // If this is the same namespace as last namespace, let's do ourselves // a favor and reload all the aliases... if (strtolower($node->name) === strtolower($this->lastNamespace)) { @@ -64,7 +64,7 @@ class UseStatementPass extends NamespaceAwarePass */ public function leaveNode(Node $node) { - if ($node instanceof UseStmt) { + if ($node instanceof Use_) { // Store a reference to every "use" statement, because we'll need // them in a bit. foreach ($node->uses as $use) { @@ -72,7 +72,7 @@ class UseStatementPass extends NamespaceAwarePass } return false; - } elseif ($node instanceof GroupUseStmt) { + } elseif ($node instanceof GroupUse) { // Expand every "use" statement in the group into a full, standalone // "use" and store 'em with the others. foreach ($node->uses as $use) { @@ -83,7 +83,7 @@ class UseStatementPass extends NamespaceAwarePass } return false; - } elseif ($node instanceof NamespaceStmt) { + } elseif ($node instanceof Namespace_) { // Start fresh, since we're done with this namespace. $this->lastNamespace = $node->name; $this->lastAliases = $this->aliases; diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/ValidClassNamePass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/ValidClassNamePass.php index eddf60e18..c91471efc 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/ValidClassNamePass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/ValidClassNamePass.php @@ -14,16 +14,16 @@ namespace Psy\CodeCleaner; use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Expr\ClassConstFetch; -use PhpParser\Node\Expr\New_ as NewExpr; +use PhpParser\Node\Expr\New_; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Stmt; -use PhpParser\Node\Stmt\Class_ as ClassStmt; -use PhpParser\Node\Stmt\Do_ as DoStmt; -use PhpParser\Node\Stmt\If_ as IfStmt; -use PhpParser\Node\Stmt\Interface_ as InterfaceStmt; -use PhpParser\Node\Stmt\Switch_ as SwitchStmt; -use PhpParser\Node\Stmt\Trait_ as TraitStmt; -use PhpParser\Node\Stmt\While_ as WhileStmt; +use PhpParser\Node\Stmt\Class_; +use PhpParser\Node\Stmt\Do_; +use PhpParser\Node\Stmt\If_; +use PhpParser\Node\Stmt\Interface_; +use PhpParser\Node\Stmt\Switch_; +use PhpParser\Node\Stmt\Trait_; +use PhpParser\Node\Stmt\While_; use Psy\Exception\FatalErrorException; /** @@ -62,14 +62,14 @@ class ValidClassNamePass extends NamespaceAwarePass if (self::isConditional($node)) { $this->conditionalScopes++; } else { - // TODO: add an "else" here which adds a runtime check for instances where we can't tell + // @todo add an "else" here which adds a runtime check for instances where we can't tell // whether a class is being redefined by static analysis alone. if ($this->conditionalScopes === 0) { - if ($node instanceof ClassStmt) { + if ($node instanceof Class_) { $this->validateClassStatement($node); - } elseif ($node instanceof InterfaceStmt) { + } elseif ($node instanceof Interface_) { $this->validateInterfaceStatement($node); - } elseif ($node instanceof TraitStmt) { + } elseif ($node instanceof Trait_) { $this->validateTraitStatement($node); } } @@ -91,7 +91,7 @@ class ValidClassNamePass extends NamespaceAwarePass { if (self::isConditional($node)) { $this->conditionalScopes--; - } elseif ($node instanceof NewExpr) { + } elseif ($node instanceof New_) { $this->validateNewExpression($node); } elseif ($node instanceof ClassConstFetch) { $this->validateClassConstFetchExpression($node); @@ -102,18 +102,18 @@ class ValidClassNamePass extends NamespaceAwarePass private static function isConditional(Node $node) { - return $node instanceof IfStmt || - $node instanceof WhileStmt || - $node instanceof DoStmt || - $node instanceof SwitchStmt; + return $node instanceof If_ || + $node instanceof While_ || + $node instanceof Do_ || + $node instanceof Switch_; } /** * Validate a class definition statement. * - * @param ClassStmt $stmt + * @param Class_ $stmt */ - protected function validateClassStatement(ClassStmt $stmt) + protected function validateClassStatement(Class_ $stmt) { $this->ensureCanDefine($stmt); if (isset($stmt->extends)) { @@ -125,9 +125,9 @@ class ValidClassNamePass extends NamespaceAwarePass /** * Validate an interface definition statement. * - * @param InterfaceStmt $stmt + * @param Interface_ $stmt */ - protected function validateInterfaceStatement(InterfaceStmt $stmt) + protected function validateInterfaceStatement(Interface_ $stmt) { $this->ensureCanDefine($stmt); $this->ensureInterfacesExist($stmt->extends, $stmt); @@ -136,9 +136,9 @@ class ValidClassNamePass extends NamespaceAwarePass /** * Validate a trait definition statement. * - * @param TraitStmt $stmt + * @param Trait_ $stmt */ - protected function validateTraitStatement(TraitStmt $stmt) + protected function validateTraitStatement(Trait_ $stmt) { $this->ensureCanDefine($stmt); } @@ -146,12 +146,12 @@ class ValidClassNamePass extends NamespaceAwarePass /** * Validate a `new` expression. * - * @param NewExpr $stmt + * @param New_ $stmt */ - protected function validateNewExpression(NewExpr $stmt) + protected function validateNewExpression(New_ $stmt) { // if class name is an expression or an anonymous class, give it a pass for now - if (!$stmt->class instanceof Expr && !$stmt->class instanceof ClassStmt) { + if (!$stmt->class instanceof Expr && !$stmt->class instanceof Class_) { $this->ensureClassExists($this->getFullyQualifiedName($stmt->class), $stmt); } } @@ -309,11 +309,11 @@ class ValidClassNamePass extends NamespaceAwarePass */ protected function getScopeType(Stmt $stmt) { - if ($stmt instanceof ClassStmt) { + if ($stmt instanceof Class_) { return self::CLASS_TYPE; - } elseif ($stmt instanceof InterfaceStmt) { + } elseif ($stmt instanceof Interface_) { return self::INTERFACE_TYPE; - } elseif ($stmt instanceof TraitStmt) { + } elseif ($stmt instanceof Trait_) { return self::TRAIT_TYPE; } } @@ -388,6 +388,6 @@ class ValidClassNamePass extends NamespaceAwarePass */ protected function createError($msg, $stmt) { - return new FatalErrorException($msg, 0, 1, null, $stmt->getLine()); + return new FatalErrorException($msg, 0, E_ERROR, null, $stmt->getLine()); } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/ValidConstantPass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/ValidConstantPass.php index abc4d5467..e84f3de66 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/ValidConstantPass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/ValidConstantPass.php @@ -45,7 +45,8 @@ class ValidConstantPass extends NamespaceAwarePass if ($node instanceof ConstFetch && count($node->name->parts) > 1) { $name = $this->getFullyQualifiedName($node->name); if (!defined($name)) { - throw new FatalErrorException(sprintf('Undefined constant %s', $name), 0, 1, null, $node->getLine()); + $msg = sprintf('Undefined constant %s', $name); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } elseif ($node instanceof ClassConstFetch) { $this->validateClassConstFetchExpression($node); @@ -73,11 +74,11 @@ class ValidConstantPass extends NamespaceAwarePass // if the class doesn't exist, don't throw an exception… it might be // defined in the same line it's used or something stupid like that. if (class_exists($className) || interface_exists($className)) { - $constName = sprintf('%s::%s', $className, $stmt->name); - if (!defined($constName)) { + $refl = new \ReflectionClass($className); + if (!$refl->hasConstant($stmt->name)) { $constType = class_exists($className) ? 'Class' : 'Interface'; - $msg = sprintf('%s constant \'%s\' not found', $constType, $constName); - throw new FatalErrorException($msg, 0, 1, null, $stmt->getLine()); + $msg = sprintf('%s constant \'%s::%s\' not found', $constType, $className, $stmt->name); + throw new FatalErrorException($msg, 0, E_ERROR, null, $stmt->getLine()); } } } diff --git a/vendor/psy/psysh/src/Psy/CodeCleaner/ValidFunctionNamePass.php b/vendor/psy/psysh/src/Psy/CodeCleaner/ValidFunctionNamePass.php index 6eca1fa32..8b4e184a9 100644 --- a/vendor/psy/psysh/src/Psy/CodeCleaner/ValidFunctionNamePass.php +++ b/vendor/psy/psysh/src/Psy/CodeCleaner/ValidFunctionNamePass.php @@ -15,11 +15,11 @@ use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\Variable; -use PhpParser\Node\Stmt\Do_ as DoStmt; -use PhpParser\Node\Stmt\Function_ as FunctionStmt; -use PhpParser\Node\Stmt\If_ as IfStmt; -use PhpParser\Node\Stmt\Switch_ as SwitchStmt; -use PhpParser\Node\Stmt\While_ as WhileStmt; +use PhpParser\Node\Stmt\Do_; +use PhpParser\Node\Stmt\Function_; +use PhpParser\Node\Stmt\If_; +use PhpParser\Node\Stmt\Switch_; +use PhpParser\Node\Stmt\While_; use Psy\Exception\FatalErrorException; /** @@ -43,16 +43,16 @@ class ValidFunctionNamePass extends NamespaceAwarePass if (self::isConditional($node)) { $this->conditionalScopes++; - } elseif ($node instanceof FunctionStmt) { + } elseif ($node instanceof Function_) { $name = $this->getFullyQualifiedName($node->name); - // TODO: add an "else" here which adds a runtime check for instances where we can't tell + // @todo add an "else" here which adds a runtime check for instances where we can't tell // whether a function is being redefined by static analysis alone. if ($this->conditionalScopes === 0) { if (function_exists($name) || isset($this->currentScope[strtolower($name)])) { $msg = sprintf('Cannot redeclare %s()', $name); - throw new FatalErrorException($msg, 0, 1, null, $node->getLine()); + throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } @@ -81,7 +81,7 @@ class ValidFunctionNamePass extends NamespaceAwarePass $inScope = isset($this->currentScope[strtolower($fullName)]); if (!$inScope && !function_exists($shortName) && !function_exists($fullName)) { $message = sprintf('Call to undefined function %s()', $name); - throw new FatalErrorException($message, 0, 1, null, $node->getLine()); + throw new FatalErrorException($message, 0, E_ERROR, null, $node->getLine()); } } } @@ -89,9 +89,9 @@ class ValidFunctionNamePass extends NamespaceAwarePass private static function isConditional(Node $node) { - return $node instanceof IfStmt || - $node instanceof WhileStmt || - $node instanceof DoStmt || - $node instanceof SwitchStmt; + return $node instanceof If_ || + $node instanceof While_ || + $node instanceof Do_ || + $node instanceof Switch_; } } diff --git a/vendor/psy/psysh/src/Psy/Command/DocCommand.php b/vendor/psy/psysh/src/Psy/Command/DocCommand.php index 2b485980a..6b3f2fd62 100644 --- a/vendor/psy/psysh/src/Psy/Command/DocCommand.php +++ b/vendor/psy/psysh/src/Psy/Command/DocCommand.php @@ -74,7 +74,7 @@ HELP if (empty($doc) && !$db) { $output->writeln('PHP manual not found'); $output->writeln(' To document core PHP functionality, download the PHP reference manual:'); - $output->writeln(' https://github.com/bobthecow/psysh#downloading-the-manual'); + $output->writeln(' https://github.com/bobthecow/dotfiles/wiki/PHP-manual'); } else { $output->writeln($doc); } diff --git a/vendor/psy/psysh/src/Psy/Command/HistoryCommand.php b/vendor/psy/psysh/src/Psy/Command/HistoryCommand.php index f987ec0e4..da2d32743 100644 --- a/vendor/psy/psysh/src/Psy/Command/HistoryCommand.php +++ b/vendor/psy/psysh/src/Psy/Command/HistoryCommand.php @@ -11,6 +11,7 @@ namespace Psy\Command; +use Psy\Input\FilterOptions; use Psy\Output\ShellOutput; use Psy\Readline\Readline; use Symfony\Component\Console\Formatter\OutputFormatter; @@ -25,6 +26,18 @@ use Symfony\Component\Console\Output\OutputInterface; */ class HistoryCommand extends Command { + private $filter; + + /** + * {@inheritdoc} + */ + public function __construct($name = null) + { + $this->filter = new FilterOptions(); + + parent::__construct($name); + } + /** * Set the Shell's Readline service. * @@ -40,6 +53,8 @@ class HistoryCommand extends Command */ protected function configure() { + list($grep, $insensitive, $invert) = FilterOptions::getOptions(); + $this ->setName('history') ->setAliases(array('hist')) @@ -48,9 +63,9 @@ class HistoryCommand extends Command new InputOption('head', 'H', InputOption::VALUE_REQUIRED, 'Display the first N items.'), new InputOption('tail', 'T', InputOption::VALUE_REQUIRED, 'Display the last N items.'), - new InputOption('grep', 'G', InputOption::VALUE_REQUIRED, 'Show lines matching the given pattern (string or regex).'), - new InputOption('insensitive', 'i', InputOption::VALUE_NONE, 'Case insensitive search (requires --grep).'), - new InputOption('invert', 'v', InputOption::VALUE_NONE, 'Inverted search (requires --grep).'), + $grep, + $insensitive, + $invert, new InputOption('no-numbers', 'N', InputOption::VALUE_NONE, 'Omit line numbers.'), @@ -87,24 +102,13 @@ HELP ); $highlighted = false; - $invert = $input->getOption('invert'); - $insensitive = $input->getOption('insensitive'); - if ($pattern = $input->getOption('grep')) { - if (substr($pattern, 0, 1) !== '/' || substr($pattern, -1) !== '/' || strlen($pattern) < 3) { - $pattern = '/' . preg_quote($pattern, '/') . '/'; - } - - if ($insensitive) { - $pattern .= 'i'; - } - - $this->validateRegex($pattern); - + $this->filter->bind($input); + if ($this->filter->hasFilter()) { $matches = array(); $highlighted = array(); foreach ($history as $i => $line) { - if (preg_match($pattern, $line, $matches) xor $invert) { - if (!$invert) { + if ($this->filter->match($line, $matches)) { + if (isset($matches[0])) { $chunks = explode($matches[0], $history[$i]); $chunks = array_map(array(__CLASS__, 'escape'), $chunks); $glue = sprintf('%s', self::escape($matches[0])); @@ -115,10 +119,6 @@ HELP unset($history[$i]); } } - } elseif ($invert) { - throw new \InvalidArgumentException('Cannot use -v without --grep.'); - } elseif ($insensitive) { - throw new \InvalidArgumentException('Cannot use -i without --grep.'); } if ($save = $input->getOption('save')) { @@ -183,6 +183,9 @@ HELP { $history = $this->readline->listHistory(); + // don't show the current `history` invocation + array_pop($history); + if ($show) { list($start, $end) = $this->extractRange($show); $length = $end - $start; @@ -207,24 +210,6 @@ HELP return array_slice($history, $start, $length, true); } - /** - * Validate that $pattern is a valid regular expression. - * - * @param string $pattern - * - * @return bool - */ - private function validateRegex($pattern) - { - set_error_handler(array('Psy\Exception\ErrorException', 'throwException')); - try { - preg_match($pattern, ''); - } catch (ErrorException $e) { - throw new RuntimeException(str_replace('preg_match(): ', 'Invalid regular expression: ', $e->getRawMessage())); - } - restore_error_handler(); - } - /** * Validate that only one of the given $options is set. * diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand.php b/vendor/psy/psysh/src/Psy/Command/ListCommand.php index e463366b6..cd38eb59d 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand.php @@ -22,6 +22,7 @@ use Psy\Command\ListCommand\PropertyEnumerator; use Psy\Command\ListCommand\TraitEnumerator; use Psy\Command\ListCommand\VariableEnumerator; use Psy\Exception\RuntimeException; +use Psy\Input\FilterOptions; use Psy\VarDumper\Presenter; use Psy\VarDumper\PresenterAware; use Symfony\Component\Console\Formatter\OutputFormatter; @@ -54,6 +55,8 @@ class ListCommand extends ReflectingCommand implements PresenterAware */ protected function configure() { + list($grep, $insensitive, $invert) = FilterOptions::getOptions(); + $this ->setName('ls') ->setAliases(array('list', 'dir')) @@ -72,9 +75,9 @@ class ListCommand extends ReflectingCommand implements PresenterAware new InputOption('properties', 'p', InputOption::VALUE_NONE, 'Display class or object properties (public properties by default).'), new InputOption('methods', 'm', InputOption::VALUE_NONE, 'Display class or object methods (public methods by default).'), - new InputOption('grep', 'G', InputOption::VALUE_REQUIRED, 'Limit to items matching the given pattern (string or regex).'), - new InputOption('insensitive', 'i', InputOption::VALUE_NONE, 'Case-insensitive search (requires --grep).'), - new InputOption('invert', 'v', InputOption::VALUE_NONE, 'Inverted search (requires --grep).'), + $grep, + $insensitive, + $invert, new InputOption('globals', 'g', InputOption::VALUE_NONE, 'Include global variables.'), new InputOption('internal', 'n', InputOption::VALUE_NONE, 'Limit to internal functions and classes.'), @@ -123,7 +126,7 @@ HELP $reflector = null; } - // TODO: something cleaner than this :-/ + // @todo something cleaner than this :-/ if ($input->getOption('long')) { $output->startPaging(); } @@ -237,15 +240,6 @@ HELP */ private function validateInput(InputInterface $input) { - // grep, invert and insensitive - if (!$input->getOption('grep')) { - foreach (array('invert', 'insensitive') as $option) { - if ($input->getOption($option)) { - throw new RuntimeException('--' . $option . ' does not make sense without --grep'); - } - } - } - if (!$input->getArgument('target')) { // if no target is passed, there can be no properties or methods foreach (array('properties', 'methods', 'no-inherit') as $option) { diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassConstantEnumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassConstantEnumerator.php index 9a494f53f..ff3e7ea74 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassConstantEnumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassConstantEnumerator.php @@ -32,7 +32,7 @@ class ClassConstantEnumerator extends Enumerator // We can only list constants on actual class (or object) reflectors. if (!$reflector instanceof \ReflectionClass) { - // TODO: handle ReflectionExtension as well + // @todo handle ReflectionExtension as well return; } @@ -77,7 +77,7 @@ class ClassConstantEnumerator extends Enumerator $constants[$name] = $constReflector; } - // TODO: this should be natcasesort + // @todo this should be natcasesort ksort($constants); return $constants; diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassEnumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassEnumerator.php index 27a459433..038b46432 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassEnumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassEnumerator.php @@ -25,7 +25,7 @@ class ClassEnumerator extends Enumerator { // only list classes when no Reflector is present. // - // TODO: make a NamespaceReflector and pass that in for commands like: + // @todo make a NamespaceReflector and pass that in for commands like: // // ls --classes Foo // diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/ConstantEnumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/ConstantEnumerator.php index 4ec7d7426..e8479f2d2 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/ConstantEnumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/ConstantEnumerator.php @@ -25,7 +25,7 @@ class ConstantEnumerator extends Enumerator { // only list constants when no Reflector is present. // - // TODO: make a NamespaceReflector and pass that in for commands like: + // @todo make a NamespaceReflector and pass that in for commands like: // // ls --constants Foo // diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/Enumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/Enumerator.php index 5e612cb08..2508f96fb 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/Enumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/Enumerator.php @@ -12,6 +12,7 @@ namespace Psy\Command\ListCommand; use Psy\Formatter\SignatureFormatter; +use Psy\Input\FilterOptions; use Psy\Util\Mirror; use Psy\VarDumper\Presenter; use Symfony\Component\Console\Input\InputInterface; @@ -30,12 +31,9 @@ abstract class Enumerator const IS_CLASS = 'class'; const IS_FUNCTION = 'function'; + private $filter; private $presenter; - private $filter = false; - private $invertFilter = false; - private $pattern; - /** * Enumerator constructor. * @@ -43,6 +41,7 @@ abstract class Enumerator */ public function __construct(Presenter $presenter) { + $this->filter = new FilterOptions(); $this->presenter = $presenter; } @@ -57,7 +56,7 @@ abstract class Enumerator */ public function enumerate(InputInterface $input, \Reflector $reflector = null, $target = null) { - $this->setFilter($input); + $this->filter->bind($input); return $this->listItems($input, $reflector, $target); } @@ -85,53 +84,14 @@ abstract class Enumerator */ abstract protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null); - protected function presentRef($value) - { - return $this->presenter->presentRef($value); - } - protected function showItem($name) { - return $this->filter === false || (preg_match($this->pattern, $name) xor $this->invertFilter); - } - - private function setFilter(InputInterface $input) - { - if ($pattern = $input->getOption('grep')) { - if (substr($pattern, 0, 1) !== '/' || substr($pattern, -1) !== '/' || strlen($pattern) < 3) { - $pattern = '/' . preg_quote($pattern, '/') . '/'; - } - - if ($input->getOption('insensitive')) { - $pattern .= 'i'; - } - - $this->validateRegex($pattern); - - $this->filter = true; - $this->pattern = $pattern; - $this->invertFilter = $input->getOption('invert'); - } else { - $this->filter = false; - } + return $this->filter->match($name); } - /** - * Validate that $pattern is a valid regular expression. - * - * @param string $pattern - * - * @return bool - */ - private function validateRegex($pattern) + protected function presentRef($value) { - set_error_handler(array('Psy\Exception\ErrorException', 'throwException')); - try { - preg_match($pattern, ''); - } catch (ErrorException $e) { - throw new RuntimeException(str_replace('preg_match(): ', 'Invalid regular expression: ', $e->getRawMessage())); - } - restore_error_handler(); + return $this->presenter->presentRef($value); } protected function presentSignature($target) diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/FunctionEnumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/FunctionEnumerator.php index 6b5535235..40ba71c93 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/FunctionEnumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/FunctionEnumerator.php @@ -25,7 +25,7 @@ class FunctionEnumerator extends Enumerator { // only list functions when no Reflector is present. // - // TODO: make a NamespaceReflector and pass that in for commands like: + // @todo make a NamespaceReflector and pass that in for commands like: // // ls --functions Foo // diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/InterfaceEnumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/InterfaceEnumerator.php index 642085974..b89b7506b 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/InterfaceEnumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/InterfaceEnumerator.php @@ -25,7 +25,7 @@ class InterfaceEnumerator extends Enumerator { // only list interfaces when no Reflector is present. // - // TODO: make a NamespaceReflector and pass that in for commands like: + // @todo make a NamespaceReflector and pass that in for commands like: // // ls --interfaces Foo // diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/MethodEnumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/MethodEnumerator.php index 2df922f99..43867b965 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/MethodEnumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/MethodEnumerator.php @@ -77,7 +77,7 @@ class MethodEnumerator extends Enumerator } } - // TODO: this should be natcasesort + // @todo this should be natcasesort ksort($methods); return $methods; diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/PropertyEnumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/PropertyEnumerator.php index c4d86368f..f36a582ca 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/PropertyEnumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/PropertyEnumerator.php @@ -77,7 +77,7 @@ class PropertyEnumerator extends Enumerator } } - // TODO: this should be natcasesort + // @todo this should be natcasesort ksort($properties); return $properties; @@ -155,9 +155,21 @@ class PropertyEnumerator extends Enumerator */ protected function presentValue(\ReflectionProperty $property, $target) { + // If $target is a class, trait or interface (try to) get the default + // value for the property. if (!is_object($target)) { - // TODO: figure out if there's a way to return defaults when target - // is a class/interface/trait rather than an object. + try { + $refl = new \ReflectionClass($target); + $props = $refl->getDefaultProperties(); + if (array_key_exists($property->name, $props)) { + $suffix = $property->isStatic() ? '' : ' '; + + return $this->presentRef($props[$property->name]) . $suffix; + } + } catch (\Exception $e) { + // Well, we gave it a shot. + } + return ''; } diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/TraitEnumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/TraitEnumerator.php index 7f2578f1e..615bfd374 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/TraitEnumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/TraitEnumerator.php @@ -30,7 +30,7 @@ class TraitEnumerator extends Enumerator // only list traits when no Reflector is present. // - // TODO: make a NamespaceReflector and pass that in for commands like: + // @todo make a NamespaceReflector and pass that in for commands like: // // ls --traits Foo // diff --git a/vendor/psy/psysh/src/Psy/Command/ListCommand/VariableEnumerator.php b/vendor/psy/psysh/src/Psy/Command/ListCommand/VariableEnumerator.php index 313d8a809..ba16e7964 100644 --- a/vendor/psy/psysh/src/Psy/Command/ListCommand/VariableEnumerator.php +++ b/vendor/psy/psysh/src/Psy/Command/ListCommand/VariableEnumerator.php @@ -95,7 +95,7 @@ class VariableEnumerator extends Enumerator return -1; } - // TODO: this should be natcasesort + // @todo this should be natcasesort return strcasecmp($a, $b); }); @@ -128,7 +128,7 @@ class VariableEnumerator extends Enumerator $ret[$fname] = array( 'name' => $fname, 'style' => in_array($name, self::$specialNames) ? self::IS_PRIVATE : self::IS_PUBLIC, - 'value' => $this->presentRef($val), // TODO: add types to variable signatures + 'value' => $this->presentRef($val), ); } } diff --git a/vendor/psy/psysh/src/Psy/Command/ParseCommand.php b/vendor/psy/psysh/src/Psy/Command/ParseCommand.php index 429bd44ca..72fab26f3 100644 --- a/vendor/psy/psysh/src/Psy/Command/ParseCommand.php +++ b/vendor/psy/psysh/src/Psy/Command/ParseCommand.php @@ -13,6 +13,7 @@ namespace Psy\Command; use PhpParser\Node; use PhpParser\Parser; +use Psy\Input\CodeArgument; use Psy\ParserFactory; use Psy\VarDumper\Presenter; use Psy\VarDumper\PresenterAware; @@ -72,7 +73,7 @@ class ParseCommand extends Command implements PresenterAware protected function configure() { $definition = array( - new InputArgument('code', InputArgument::REQUIRED, 'PHP code to parse.'), + new CodeArgument('code', InputArgument::REQUIRED, 'PHP code to parse.'), new InputOption('depth', '', InputOption::VALUE_REQUIRED, 'Depth to parse', 10), ); diff --git a/vendor/psy/psysh/src/Psy/Command/ReflectingCommand.php b/vendor/psy/psysh/src/Psy/Command/ReflectingCommand.php index 995a59738..55c7005ae 100644 --- a/vendor/psy/psysh/src/Psy/Command/ReflectingCommand.php +++ b/vendor/psy/psysh/src/Psy/Command/ReflectingCommand.php @@ -62,7 +62,7 @@ abstract class ReflectingCommand extends Command implements ContextAware $matches = array(); switch (true) { case preg_match(self::SUPERGLOBAL, $valueName, $matches): - // TODO: maybe do something interesting with these at some point? + // @todo maybe do something interesting with these at some point? if (array_key_exists($matches[1], $GLOBALS)) { throw new RuntimeException('Unable to inspect a non-object'); } else { diff --git a/vendor/psy/psysh/src/Psy/Command/ShowCommand.php b/vendor/psy/psysh/src/Psy/Command/ShowCommand.php index 024b72c23..c4dab43d0 100644 --- a/vendor/psy/psysh/src/Psy/Command/ShowCommand.php +++ b/vendor/psy/psysh/src/Psy/Command/ShowCommand.php @@ -11,13 +11,17 @@ namespace Psy\Command; +use JakubOnderka\PhpConsoleHighlighter\Highlighter; use Psy\Configuration; +use Psy\ConsoleColorFactory; use Psy\Exception\RuntimeException; use Psy\Formatter\CodeFormatter; use Psy\Formatter\SignatureFormatter; use Psy\Output\ShellOutput; +use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; /** @@ -26,6 +30,9 @@ use Symfony\Component\Console\Output\OutputInterface; class ShowCommand extends ReflectingCommand { private $colorMode; + private $highlighter; + private $lastException; + private $lastExceptionIndex; /** * @param null|string $colorMode (default: null) @@ -45,16 +52,24 @@ class ShowCommand extends ReflectingCommand $this ->setName('show') ->setDefinition(array( - new InputArgument('value', InputArgument::REQUIRED, 'Function, class, instance, constant, method or property to show.'), + new InputArgument('value', InputArgument::OPTIONAL, 'Function, class, instance, constant, method or property to show.'), + new InputOption('ex', null, InputOption::VALUE_OPTIONAL, 'Show last exception context. Optionally specify a stack index.', 1), )) ->setDescription('Show the code for an object, class, constant, method or property.') ->setHelp( <<cat --ex defaults to showing the lines surrounding the location of the last +exception. Invoking it more than once travels up the exception's stack trace, +and providing a number shows the context of the given index of the trace. e.g. >>> show \$myObject >>> show Psy\Shell::debug +>>> show --ex +>>> show --ex 3 HELP ); } @@ -63,6 +78,38 @@ HELP * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) + { + // n.b. As far as I can tell, InputInterface doesn't want to tell me + // whether an option with an optional value was actually passed. If you + // call `$input->getOption('ex')`, it will return the default, both when + // `--ex` is specified with no value, and when `--ex` isn't specified at + // all. + // + // So we're doing something sneaky here. If we call `getOptions`, it'll + // return the default value when `--ex` is not present, and `null` if + // `--ex` is passed with no value. /shrug + $opts = $input->getOptions(); + + // Strict comparison to `1` (the default value) here, because `--ex 1` + // will come in as `"1"`. Now we can tell the difference between + // "no --ex present", because it's the integer 1, "--ex with no value", + // because it's `null`, and "--ex 1", because it's the string "1". + if ($opts['ex'] !== 1) { + if ($input->getArgument('value')) { + throw new \InvalidArgumentException('Too many arguments (supply either "value" or "--ex")'); + } + + return $this->writeExceptionContext($input, $output); + } + + if ($input->getArgument('value')) { + return $this->writeCodeContext($input, $output); + } + + throw new RuntimeException('Not enough arguments (missing: "value").'); + } + + private function writeCodeContext(InputInterface $input, OutputInterface $output) { list($value, $reflector) = $this->getTargetAndReflector($input->getArgument('value')); @@ -76,4 +123,150 @@ HELP throw $e; } } + + private function writeExceptionContext(InputInterface $input, OutputInterface $output) + { + $exception = $this->context->getLastException(); + if ($exception !== $this->lastException) { + $this->lastException = null; + $this->lastExceptionIndex = null; + } + + $opts = $input->getOptions(); + if ($opts['ex'] === null) { + if ($this->lastException && $this->lastExceptionIndex !== null) { + $index = $this->lastExceptionIndex + 1; + } else { + $index = 0; + } + } else { + $index = max(0, intval($input->getOption('ex')) - 1); + } + + $trace = $exception->getTrace(); + array_unshift($trace, array( + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + )); + + if ($index >= count($trace)) { + $index = 0; + } + + $this->lastException = $exception; + $this->lastExceptionIndex = $index; + + $output->writeln($this->getApplication()->formatException($exception)); + $output->writeln('--'); + $this->writeTraceLine($output, $trace, $index); + $this->writeTraceCodeSnippet($output, $trace, $index); + + $this->setCommandScopeVariablesFromContext($trace[$index]); + } + + private function writeTraceLine(OutputInterface $output, array $trace, $index) + { + $file = isset($trace[$index]['file']) ? $this->replaceCwd($trace[$index]['file']) : 'n/a'; + $line = isset($trace[$index]['line']) ? $trace[$index]['line'] : 'n/a'; + + $output->writeln(sprintf( + 'From %s:%d at level %d of backtrace (of %d).', + OutputFormatter::escape($file), + OutputFormatter::escape($line), + $index + 1, + count($trace) + )); + } + + private function replaceCwd($file) + { + if ($cwd = getcwd()) { + $cwd = rtrim($cwd, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + } + + if ($cwd === false) { + return $file; + } else { + return preg_replace('/^' . preg_quote($cwd, '/') . '/', '', $file); + } + } + + private function writeTraceCodeSnippet(OutputInterface $output, array $trace, $index) + { + if (!isset($trace[$index]['file'])) { + return; + } + + $file = $trace[$index]['file']; + if ($fileAndLine = $this->extractEvalFileAndLine($file)) { + list($file, $line) = $fileAndLine; + } else { + if (!isset($trace[$index]['line'])) { + return; + } + + $line = $trace[$index]['line']; + } + + if (is_file($file)) { + $code = @file_get_contents($file); + } + + if (empty($code)) { + return; + } + + $output->write($this->getHighlighter()->getCodeSnippet($code, $line, 5, 5), ShellOutput::OUTPUT_RAW); + } + + private function getHighlighter() + { + if (!$this->highlighter) { + $factory = new ConsoleColorFactory($this->colorMode); + $this->highlighter = new Highlighter($factory->getConsoleColor()); + } + + return $this->highlighter; + } + + private function setCommandScopeVariablesFromContext(array $context) + { + $vars = array(); + + // @todo __namespace? + if (isset($context['class'])) { + $vars['__class'] = $context['class']; + if (isset($context['function'])) { + $vars['__method'] = $context['function']; + } + } elseif (isset($context['function'])) { + $vars['__function'] = $context['function']; + } + + if (isset($context['file'])) { + $file = $context['file']; + if ($fileAndLine = $this->extractEvalFileAndLine($file)) { + list($file, $line) = $fileAndLine; + } elseif (isset($context['line'])) { + $line = $context['line']; + } + + if (is_file($file)) { + $vars['__file'] = $file; + if (isset($line)) { + $vars['__line'] = $line; + } + $vars['__dir'] = dirname($file); + } + } + + $this->context->setCommandScopeVariables($vars); + } + + private function extractEvalFileAndLine($file) + { + if (preg_match('/(.*)\\((\\d+)\\) : eval\\(\\)\'d code$/', $file, $matches)) { + return array($matches[1], $matches[2]); + } + } } diff --git a/vendor/psy/psysh/src/Psy/Command/SudoCommand.php b/vendor/psy/psysh/src/Psy/Command/SudoCommand.php new file mode 100644 index 000000000..1a0a65520 --- /dev/null +++ b/vendor/psy/psysh/src/Psy/Command/SudoCommand.php @@ -0,0 +1,143 @@ +parser = $parserFactory->createParser(); + + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor(new SudoVisitor()); + + $this->printer = new Printer(); + + parent::__construct($name); + } + + /** + * Set the Shell's Readline service. + * + * @param Readline $readline + */ + public function setReadline(Readline $readline) + { + $this->readline = $readline; + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('sudo') + ->setDefinition(array( + new CodeArgument('code', InputArgument::REQUIRED, 'Code to execute.'), + )) + ->setDescription('Evaluate PHP code, bypassing visibility restrictions.') + ->setHelp( + <<<'HELP' +Evaluate PHP code, bypassing visibility restrictions. + +e.g. +>>> $sekret->whisper("hi") +PHP error: Call to private method Sekret::whisper() from context '' on line 1 + +>>> sudo $sekret->whisper("hi") +=> "hi" + +>>> $sekret->word +PHP error: Cannot access private property Sekret::$word on line 1 + +>>> sudo $sekret->word +=> "hi" + +>>> $sekret->word = "please" +PHP error: Cannot access private property Sekret::$word on line 1 + +>>> sudo $sekret->word = "please" +=> "please" +HELP + ); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $code = $input->getArgument('code'); + + // special case for !! + if ($code === '!!') { + $history = $this->readline->listHistory(); + if (count($history) < 2) { + throw new \InvalidArgumentException('No previous command to replay'); + } + $code = $history[count($history) - 2]; + } + + if (strpos('traverser->traverse($this->parse($code)); + + $sudoCode = $this->printer->prettyPrint($nodes); + $this->getApplication()->addInput($sudoCode, true); + } + + /** + * Lex and parse a string of code into statements. + * + * @param string $code + * + * @return array Statements + */ + private function parse($code) + { + try { + return $this->parser->parse($code); + } catch (\PhpParser\Error $e) { + if (strpos($e->getMessage(), 'unexpected EOF') === false) { + throw $e; + } + + // If we got an unexpected EOF, let's try it again with a semicolon. + return $this->parser->parse($code . ';'); + } + } +} diff --git a/vendor/psy/psysh/src/Psy/Command/TraceCommand.php b/vendor/psy/psysh/src/Psy/Command/TraceCommand.php index 72db281dc..00e5903fd 100644 --- a/vendor/psy/psysh/src/Psy/Command/TraceCommand.php +++ b/vendor/psy/psysh/src/Psy/Command/TraceCommand.php @@ -11,6 +11,7 @@ namespace Psy\Command; +use Psy\Input\FilterOptions; use Psy\Output\ShellOutput; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Input\InputInterface; @@ -22,16 +23,34 @@ use Symfony\Component\Console\Output\OutputInterface; */ class TraceCommand extends Command { + protected $filter; + + /** + * {@inheritdoc} + */ + public function __construct($name = null) + { + $this->filter = new FilterOptions(); + + parent::__construct($name); + } + /** * {@inheritdoc} */ protected function configure() { + list($grep, $insensitive, $invert) = FilterOptions::getOptions(); + $this ->setName('trace') ->setDefinition(array( new InputOption('include-psy', 'p', InputOption::VALUE_NONE, 'Include Psy in the call stack.'), new InputOption('num', 'n', InputOption::VALUE_REQUIRED, 'Only include NUM lines.'), + + $grep, + $insensitive, + $invert, )) ->setDescription('Show the current call stack.') ->setHelp( @@ -52,6 +71,7 @@ HELP */ protected function execute(InputInterface $input, OutputInterface $output) { + $this->filter->bind($input); $trace = $this->getBacktrace(new \Exception(), $input->getOption('num'), $input->getOption('include-psy')); $output->page($trace, ShellOutput::NUMBER_LINES); } @@ -105,6 +125,16 @@ HELP $file = isset($trace[$i]['file']) ? $this->replaceCwd($cwd, $trace[$i]['file']) : 'n/a'; $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a'; + // Leave execution loop out of the `eval()'d code` lines + if (preg_match("#/Psy/ExecutionLoop/Loop.php\(\d+\) : eval\(\)'d code$#", $file)) { + $file = "eval()'d code"; + } + + // Skip any lines that don't match our filter options + if (!$this->filter->match(sprintf('%s%s%s() at %s:%s', $class, $type, $function, $file, $line))) { + continue; + } + $lines[] = sprintf( ' %s%s%s() at %s:%s', OutputFormatter::escape($class), diff --git a/vendor/psy/psysh/src/Psy/Command/WtfCommand.php b/vendor/psy/psysh/src/Psy/Command/WtfCommand.php index 7e3d08d1f..2e5c00ce1 100644 --- a/vendor/psy/psysh/src/Psy/Command/WtfCommand.php +++ b/vendor/psy/psysh/src/Psy/Command/WtfCommand.php @@ -13,6 +13,7 @@ namespace Psy\Command; use Psy\Context; use Psy\ContextAware; +use Psy\Input\FilterOptions; use Psy\Output\ShellOutput; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -46,12 +47,18 @@ class WtfCommand extends TraceCommand implements ContextAware */ protected function configure() { + list($grep, $insensitive, $invert) = FilterOptions::getOptions(); + $this ->setName('wtf') ->setAliases(array('last-exception', 'wtf?')) ->setDefinition(array( new InputArgument('incredulity', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Number of lines to show'), - new InputOption('verbose', 'v', InputOption::VALUE_NONE, 'Show entire backtrace.'), + new InputOption('all', 'a', InputOption::VALUE_NONE, 'Show entire backtrace.'), + + $grep, + $insensitive, + $invert, )) ->setDescription('Show the backtrace of the most recent exception.') ->setHelp( @@ -64,7 +71,7 @@ e.g. >>> wtf ? >>> wtf ?!???!?!? -To see the entire backtrace, pass the -v/--verbose flag: +To see the entire backtrace, pass the -a/--all flag: e.g. >>> wtf -v @@ -72,40 +79,47 @@ HELP ); } - /** - * {@inheritdoc} - * - * --verbose is not hidden for this option :) - * - * @return array - */ - protected function getHiddenOptions() - { - $options = parent::getHiddenOptions(); - unset($options[array_search('verbose', $options)]); - - return $options; - } - /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { + $this->filter->bind($input); + $incredulity = implode('', $input->getArgument('incredulity')); if (strlen(preg_replace('/[\\?!]/', '', $incredulity))) { throw new \InvalidArgumentException('Incredulity must include only "?" and "!".'); } $exception = $this->context->getLastException(); - $count = $input->getOption('verbose') ? PHP_INT_MAX : pow(2, max(0, (strlen($incredulity) - 1))); - $trace = $this->getBacktrace($exception, $count); + $count = $input->getOption('all') ? PHP_INT_MAX : max(3, pow(2, strlen($incredulity) + 1)); $shell = $this->getApplication(); - $output->page(function ($output) use ($exception, $trace, $shell) { - $shell->renderException($exception, $output); + $output->startPaging(); + do { + $traceCount = count($exception->getTrace()); + $showLines = $count; + // Show the whole trace if we'd only be hiding a few lines + if ($traceCount < max($count * 1.2, $count + 2)) { + $showLines = PHP_INT_MAX; + } + + $trace = $this->getBacktrace($exception, $showLines); + $moreLines = $traceCount - count($trace); + + $output->writeln($shell->formatException($exception)); $output->writeln('--'); $output->write($trace, true, ShellOutput::NUMBER_LINES); - }); + $output->writeln(''); + + if ($moreLines > 0) { + $output->writeln(sprintf( + '', + $moreLines + )); + $output->writeln(''); + } + } while ($exception = $exception->getPrevious()); + $output->stopPaging(); } } diff --git a/vendor/psy/psysh/src/Psy/Configuration.php b/vendor/psy/psysh/src/Psy/Configuration.php index e74e0934d..b76a15041 100644 --- a/vendor/psy/psysh/src/Psy/Configuration.php +++ b/vendor/psy/psysh/src/Psy/Configuration.php @@ -359,7 +359,7 @@ class Configuration } // Deprecation warning for incorrect psysh_history path. - // TODO: remove this before v0.9.0 + // @todo remove this before v0.9.0 $xdg = new Xdg(); $oldHistory = $xdg->getHomeConfigDir() . '/psysh_history'; if (@is_file($oldHistory)) { @@ -643,7 +643,7 @@ class Configuration return $this->useUnicode; } - // TODO: detect `chsh` != 65001 on Windows and return false + // @todo detect `chsh` != 65001 on Windows and return false return true; } diff --git a/vendor/psy/psysh/src/Psy/Exception/BreakException.php b/vendor/psy/psysh/src/Psy/Exception/BreakException.php index a0a2ec62c..4592c51fa 100644 --- a/vendor/psy/psysh/src/Psy/Exception/BreakException.php +++ b/vendor/psy/psysh/src/Psy/Exception/BreakException.php @@ -36,4 +36,16 @@ class BreakException extends \Exception implements Exception { return $this->rawMessage; } + + /** + * Throws BreakException. + * + * Since `throw` can not be inserted into arbitrary expressions, it wraps with function call. + * + * @throws BreakException + */ + public static function exitShell() + { + throw new self('Goodbye'); + } } diff --git a/vendor/psy/psysh/src/Psy/Exception/FatalErrorException.php b/vendor/psy/psysh/src/Psy/Exception/FatalErrorException.php index 6c0ef4605..5fe7fc61c 100644 --- a/vendor/psy/psysh/src/Psy/Exception/FatalErrorException.php +++ b/vendor/psy/psysh/src/Psy/Exception/FatalErrorException.php @@ -23,13 +23,18 @@ class FatalErrorException extends \ErrorException implements Exception * * @param string $message (default: "") * @param int $code (default: 0) - * @param int $severity (default: 9000) + * @param int $severity (default: 1) * @param string $filename (default: null) * @param int $lineno (default: null) * @param \Exception $previous (default: null) */ - public function __construct($message = '', $code = 0, $severity = 9000, $filename = null, $lineno = null, $previous = null) + public function __construct($message = '', $code = 0, $severity = 1, $filename = null, $lineno = null, $previous = null) { + // Since these are basically always PHP Parser Node line numbers, treat -1 as null. + if ($lineno === -1) { + $lineno = null; + } + $this->rawMessage = $message; $message = sprintf('PHP Fatal error: %s in %s on line %d', $message, $filename ?: "eval()'d code", $lineno); parent::__construct($message, $code, $severity, $filename, $lineno, $previous); diff --git a/vendor/psy/psysh/src/Psy/Input/CodeArgument.php b/vendor/psy/psysh/src/Psy/Input/CodeArgument.php new file mode 100644 index 000000000..4e50754e4 --- /dev/null +++ b/vendor/psy/psysh/src/Psy/Input/CodeArgument.php @@ -0,0 +1,50 @@ +validateInput($input); + + if (!$pattern = $input->getOption('grep')) { + $this->filter = false; + + return; + } + + if (!$this->stringIsRegex($pattern)) { + $pattern = '/' . preg_quote($pattern, '/') . '/'; + } + + if ($insensitive = $input->getOption('insensitive')) { + $pattern .= 'i'; + } + + $this->validateRegex($pattern); + + $this->filter = true; + $this->pattern = $pattern; + $this->insensitive = $insensitive; + $this->invert = $input->getOption('invert'); + } + + /** + * Check whether the bound input has filter options. + * + * @return bool + */ + public function hasFilter() + { + return $this->filter; + } + + /** + * Check whether a string matches the current filter options. + * + * @param string $string + * @param array $matches + * + * @return bool + */ + public function match($string, array &$matches = null) + { + return $this->filter === false || (preg_match($this->pattern, $string, $matches) xor $this->invert); + } + + /** + * Validate that grep, invert and insensitive input options are consistent. + * + * @param InputInterface $input + * + * @return bool + */ + private function validateInput(InputInterface $input) + { + if (!$input->getOption('grep')) { + foreach (array('invert', 'insensitive') as $option) { + if ($input->getOption($option)) { + throw new RuntimeException('--' . $option . ' does not make sense without --grep'); + } + } + } + } + + /** + * Check whether a string appears to be a regular expression. + * + * @param string $string + * + * @return bool + */ + private function stringIsRegex($string) + { + return substr($string, 0, 1) === '/' && substr($string, -1) === '/' && strlen($string) >= 3; + } + + /** + * Validate that $pattern is a valid regular expression. + * + * @param string $pattern + * + * @return bool + */ + private function validateRegex($pattern) + { + set_error_handler(array('Psy\Exception\ErrorException', 'throwException')); + try { + preg_match($pattern, ''); + } catch (ErrorException $e) { + throw new RuntimeException(str_replace('preg_match(): ', 'Invalid regular expression: ', $e->getRawMessage())); + } + restore_error_handler(); + } +} diff --git a/vendor/psy/psysh/src/Psy/Input/ShellInput.php b/vendor/psy/psysh/src/Psy/Input/ShellInput.php new file mode 100644 index 000000000..e25db4618 --- /dev/null +++ b/vendor/psy/psysh/src/Psy/Input/ShellInput.php @@ -0,0 +1,322 @@ +tokenPairs = $this->tokenize($input); + } + + /** + * {@inheritdoc} + * + * @throws \InvalidArgumentException if $definition has CodeArgument before the final argument position + */ + public function bind(InputDefinition $definition) + { + $hasCodeArgument = false; + + if ($definition->getArgumentCount() > 0) { + $args = $definition->getArguments(); + $lastArg = array_pop($args); + foreach ($args as $arg) { + if ($arg instanceof CodeArgument) { + $msg = sprintf('Unexpected CodeArgument before the final position: %s', $arg->getName()); + throw new \InvalidArgumentException($msg); + } + } + + if ($lastArg instanceof CodeArgument) { + $hasCodeArgument = true; + } + } + + $this->hasCodeArgument = $hasCodeArgument; + + return parent::bind($definition); + } + + /** + * Tokenizes a string. + * + * The version of this on StringInput is good, but doesn't handle code + * arguments if they're at all complicated. This does :) + * + * @param string $input The input to tokenize + * + * @return array An array of token/rest pairs + * + * @throws \InvalidArgumentException When unable to parse input (should never happen) + */ + private function tokenize($input) + { + $tokens = array(); + $length = strlen($input); + $cursor = 0; + while ($cursor < $length) { + if (preg_match('/\s+/A', $input, $match, null, $cursor)) { + } elseif (preg_match('/([^="\'\s]+?)(=?)(' . StringInput::REGEX_QUOTED_STRING . '+)/A', $input, $match, null, $cursor)) { + $tokens[] = array( + $match[1] . $match[2] . stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2))), + substr($input, $cursor), + ); + } elseif (preg_match('/' . StringInput::REGEX_QUOTED_STRING . '/A', $input, $match, null, $cursor)) { + $tokens[] = array( + stripcslashes(substr($match[0], 1, strlen($match[0]) - 2)), + substr($input, $cursor), + ); + } elseif (preg_match('/' . StringInput::REGEX_STRING . '/A', $input, $match, null, $cursor)) { + $tokens[] = array( + stripcslashes($match[1]), + substr($input, $cursor), + ); + } else { + // should never happen + throw new \InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10))); + } + + $cursor += strlen($match[0]); + } + + return $tokens; + } + + /** + * Same as parent, but with some bonus handling for code arguments. + */ + protected function parse() + { + $parseOptions = true; + $this->parsed = $this->tokenPairs; + while (null !== $tokenPair = array_shift($this->parsed)) { + // token is what you'd expect. rest is the remainder of the input + // string, including token, and will be used if this is a code arg. + list($token, $rest) = $tokenPair; + + if ($parseOptions && '' === $token) { + $this->parseShellArgument($token, $rest); + } elseif ($parseOptions && '--' === $token) { + $parseOptions = false; + } elseif ($parseOptions && 0 === strpos($token, '--')) { + $this->parseLongOption($token); + } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { + $this->parseShortOption($token); + } else { + $this->parseShellArgument($token, $rest); + } + } + } + + /** + * Parses an argument, with bonus handling for code arguments. + * + * @param string $token The current token + * @param string $rest The remaining unparsed input, including the current token + * + * @throws \RuntimeException When too many arguments are given + */ + private function parseShellArgument($token, $rest) + { + $c = count($this->arguments); + + // if input is expecting another argument, add it + if ($this->definition->hasArgument($c)) { + $arg = $this->definition->getArgument($c); + + if ($arg instanceof CodeArgument) { + // When we find a code argument, we're done parsing. Add the + // remaining input to the current argument and call it a day. + $this->parsed = array(); + $this->arguments[$arg->getName()] = $rest; + } else { + $this->arguments[$arg->getName()] = $arg->isArray() ? array($token) : $token; + } + + // if last argument isArray(), append token to last argument + } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) { + $arg = $this->definition->getArgument($c - 1); + $this->arguments[$arg->getName()][] = $token; + + // unexpected argument + } else { + $all = $this->definition->getArguments(); + if (count($all)) { + throw new \RuntimeException(sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all)))); + } + + throw new \RuntimeException(sprintf('No arguments expected, got "%s".', $token)); + } + } + + // Everything below this is copypasta from ArgvInput private methods + + /** + * Parses a short option. + * + * @param string $token The current token + */ + private function parseShortOption($token) + { + $name = substr($token, 1); + + if (strlen($name) > 1) { + if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) { + // an option with a value (with no space) + $this->addShortOption($name[0], substr($name, 1)); + } else { + $this->parseShortOptionSet($name); + } + } else { + $this->addShortOption($name, null); + } + } + + /** + * Parses a short option set. + * + * @param string $name The current token + * + * @throws \RuntimeException When option given doesn't exist + */ + private function parseShortOptionSet($name) + { + $len = strlen($name); + for ($i = 0; $i < $len; ++$i) { + if (!$this->definition->hasShortcut($name[$i])) { + throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i])); + } + + $option = $this->definition->getOptionForShortcut($name[$i]); + if ($option->acceptValue()) { + $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1)); + + break; + } else { + $this->addLongOption($option->getName(), null); + } + } + } + + /** + * Parses a long option. + * + * @param string $token The current token + */ + private function parseLongOption($token) + { + $name = substr($token, 2); + + if (false !== $pos = strpos($name, '=')) { + if (0 === strlen($value = substr($name, $pos + 1))) { + // if no value after "=" then substr() returns "" since php7 only, false before + // see http://php.net/manual/fr/migration70.incompatible.php#119151 + if (PHP_VERSION_ID < 70000 && false === $value) { + $value = ''; + } + array_unshift($this->parsed, array($value, null)); + } + $this->addLongOption(substr($name, 0, $pos), $value); + } else { + $this->addLongOption($name, null); + } + } + + /** + * Adds a short option value. + * + * @param string $shortcut The short option key + * @param mixed $value The value for the option + * + * @throws \RuntimeException When option given doesn't exist + */ + private function addShortOption($shortcut, $value) + { + if (!$this->definition->hasShortcut($shortcut)) { + throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut)); + } + + $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); + } + + /** + * Adds a long option value. + * + * @param string $name The long option key + * @param mixed $value The value for the option + * + * @throws \RuntimeException When option given doesn't exist + */ + private function addLongOption($name, $value) + { + if (!$this->definition->hasOption($name)) { + throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name)); + } + + $option = $this->definition->getOption($name); + + if (null !== $value && !$option->acceptValue()) { + throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name)); + } + + if (in_array($value, array('', null), true) && $option->acceptValue() && count($this->parsed)) { + // if option accepts an optional or mandatory argument + // let's see if there is one provided + $next = array_shift($this->parsed); + $nextToken = $next[0]; + if ((isset($nextToken[0]) && '-' !== $nextToken[0]) || in_array($nextToken, array('', null), true)) { + $value = $nextToken; + } else { + array_unshift($this->parsed, $next); + } + } + + if (null === $value) { + if ($option->isValueRequired()) { + throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name)); + } + + if (!$option->isArray() && !$option->isValueOptional()) { + $value = true; + } + } + + if ($option->isArray()) { + $this->options[$name][] = $value; + } else { + $this->options[$name] = $value; + } + } +} diff --git a/vendor/psy/psysh/src/Psy/Input/SilentInput.php b/vendor/psy/psysh/src/Psy/Input/SilentInput.php new file mode 100644 index 000000000..0da750d69 --- /dev/null +++ b/vendor/psy/psysh/src/Psy/Input/SilentInput.php @@ -0,0 +1,44 @@ +inputString = $inputString; + } + + /** + * To. String. + * + * @return string + */ + public function __toString() + { + return $this->inputString; + } +} diff --git a/vendor/psy/psysh/src/Psy/Shell.php b/vendor/psy/psysh/src/Psy/Shell.php index 3e5594c5a..b0eb43301 100644 --- a/vendor/psy/psysh/src/Psy/Shell.php +++ b/vendor/psy/psysh/src/Psy/Shell.php @@ -11,10 +11,13 @@ namespace Psy; +use Psy\CodeCleaner\NoReturnValue; use Psy\Exception\BreakException; use Psy\Exception\ErrorException; use Psy\Exception\Exception as PsyException; use Psy\Exception\ThrowUpException; +use Psy\Input\ShellInput; +use Psy\Input\SilentInput; use Psy\Output\ShellOutput; use Psy\TabCompletion\Matcher; use Psy\VarDumper\PresenterAware; @@ -41,7 +44,7 @@ use Symfony\Component\Console\Output\OutputInterface; */ class Shell extends Application { - const VERSION = 'v0.8.3'; + const VERSION = 'v0.8.7'; const PROMPT = '>>> '; const BUFF_PROMPT = '... '; @@ -76,6 +79,7 @@ class Shell extends Application $this->context = new Context(); $this->includes = array(); $this->readline = $this->config->getReadline(); + $this->inputBuffer = array(); parent::__construct('Psy Shell', self::VERSION); @@ -100,31 +104,8 @@ class Shell extends Application /** * Invoke a Psy Shell from the current context. * - * For example: - * - * foreach ($items as $item) { - * \Psy\Shell::debug(get_defined_vars()); - * } - * - * If you would like your shell interaction to affect the state of the - * current context, you can extract() the values returned from this call: - * - * foreach ($items as $item) { - * extract(\Psy\Shell::debug(get_defined_vars())); - * var_dump($item); // will be whatever you set $item to in Psy Shell - * } - * - * Optionally, supply an object as the `$boundObject` parameter. This - * determines the value `$this` will have in the shell, and sets up class - * scope so that private and protected members are accessible: - * - * class Foo { - * function bar() { - * \Psy\Shell::debug(get_defined_vars(), $this); - * } - * } - * - * This only really works in PHP 5.4+ and HHVM 3.5+, so upgrade already. + * @see Psy\debug + * @deprecated will be removed in 1.0. Use \Psy\debug instead * * @param array $vars Scope variables from the calling context (default: array()) * @param object $boundObject Bound object ($this) value for the shell @@ -133,18 +114,7 @@ class Shell extends Application */ public static function debug(array $vars = array(), $boundObject = null) { - echo PHP_EOL; - - $sh = new \Psy\Shell(); - $sh->setScopeVariables($vars); - - if ($boundObject !== null) { - $sh->setBoundObject($boundObject); - } - - $sh->run(); - - return $sh->getScopeVariables(false); + return \Psy\debug($vars, $boundObject); } /** @@ -191,6 +161,9 @@ class Shell extends Application */ protected function getDefaultCommands() { + $sudo = new Command\SudoCommand(); + $sudo->setReadline($this->readline); + $hist = new Command\HistoryCommand(); $hist->setReadline($this->readline); @@ -200,13 +173,14 @@ class Shell extends Application new Command\DumpCommand(), new Command\DocCommand(), new Command\ShowCommand($this->config->colorMode()), - new Command\WtfCommand(), + new Command\WtfCommand($this->config->colorMode()), new Command\WhereamiCommand($this->config->colorMode()), new Command\ThrowUpCommand(), new Command\TraceCommand(), new Command\BufferCommand(), new Command\ClearCommand(), // new Command\PsyVersionCommand(), + $sudo, $hist, new Command\ExitCommand(), ); @@ -549,7 +523,7 @@ class Shell extends Application $this->code = $this->cleaner->clean($this->codeBuffer, $this->config->requireSemicolons()); } catch (\Exception $e) { // Add failed code blocks to the readline history. - $this->readline->addHistory(implode("\n", $this->codeBuffer)); + $this->addCodeBufferToHistory(); throw $e; } } @@ -583,7 +557,7 @@ class Shell extends Application throw new \InvalidArgumentException('Command not found: ' . $input); } - $input = new StringInput(str_replace('\\', '\\\\', rtrim($input, " \t\n\r\0\x0B;"))); + $input = new ShellInput(str_replace('\\', '\\\\', rtrim($input, " \t\n\r\0\x0B;"))); if ($input->hasParameterOption(array('--help', '-h'))) { $helpCommand = $this->get('help'); @@ -613,11 +587,12 @@ class Shell extends Application * This is useful for commands which want to replay history. * * @param string|array $input + * @param bool $silent */ - public function addInput($input) + public function addInput($input, $silent = false) { foreach ((array) $input as $line) { - $this->inputBuffer[] = $line; + $this->inputBuffer[] = $silent ? new SilentInput($line) : $line; } } @@ -632,7 +607,7 @@ class Shell extends Application public function flushCode() { if ($this->hasValidCode()) { - $this->readline->addHistory(implode("\n", $this->codeBuffer)); + $this->addCodeBufferToHistory(); $code = $this->code; $this->resetCodeBuffer(); @@ -640,6 +615,22 @@ class Shell extends Application } } + /** + * Filter silent input from code buffer, write the rest to readline history. + */ + private function addCodeBufferToHistory() + { + $codeBuffer = array_filter($this->codeBuffer, function ($line) { + return !$line instanceof SilentInput; + }); + + $code = implode("\n", $codeBuffer); + + if (trim($code) !== '') { + $this->readline->addHistory($code); + } + } + /** * Get the current evaluation scope namespace. * @@ -694,6 +685,10 @@ class Shell extends Application */ public function writeReturnValue($ret) { + if ($ret instanceof NoReturnValue) { + return; + } + $this->context->setReturnValue($ret); $ret = $this->presentValue($ret); $indent = str_repeat(' ', strlen(static::RETVAL)); @@ -715,16 +710,29 @@ class Shell extends Application public function writeException(\Exception $e) { $this->context->setLastException($e); + $this->output->writeln($this->formatException($e)); + $this->resetCodeBuffer(); + } + /** + * Helper for formatting an exception for writeException(). + * + * @todo extract this to somewhere it makes more sense + * + * @param \Exception $e + * + * @return string + */ + public function formatException(\Exception $e) + { $message = $e->getMessage(); if (!$e instanceof PsyException) { $message = sprintf('%s with message \'%s\'', get_class($e), $message); } $severity = ($e instanceof \ErrorException) ? $this->getSeverity($e) : 'error'; - $this->output->writeln(sprintf('<%s>%s', $severity, OutputFormatter::escape($message), $severity)); - $this->resetCodeBuffer(); + return sprintf('<%s>%s', $severity, OutputFormatter::escape($message), $severity); } /** @@ -864,7 +872,9 @@ class Shell extends Application { if (!empty($this->inputBuffer)) { $line = array_shift($this->inputBuffer); - $this->output->writeln(sprintf('', static::REPLAY, OutputFormatter::escape($line))); + if (!$line instanceof SilentInput) { + $this->output->writeln(sprintf('', static::REPLAY, OutputFormatter::escape($line))); + } return $line; } diff --git a/vendor/psy/psysh/src/Psy/Sudo.php b/vendor/psy/psysh/src/Psy/Sudo.php new file mode 100644 index 000000000..2ba55728e --- /dev/null +++ b/vendor/psy/psysh/src/Psy/Sudo.php @@ -0,0 +1,150 @@ +property + */ + public static function fetchProperty($object, $property) + { + $refl = new \ReflectionObject($object); + $prop = $refl->getProperty($property); + $prop->setAccessible(true); + + return $prop->getValue($object); + } + + /** + * Assign the value of a property of an object, bypassing visibility restrictions. + * + * @param object $object + * @param string $property property name + * @param mixed $value + * + * @return mixed Value of $object->property + */ + public static function assignProperty($object, $property, $value) + { + $refl = new \ReflectionObject($object); + $prop = $refl->getProperty($property); + $prop->setAccessible(true); + $prop->setValue($object, $value); + + return $value; + } + + /** + * Call a method on an object, bypassing visibility restrictions. + * + * @param object $object + * @param string $method method name + * @param mixed $args... + * + * @return mixed + */ + public static function callMethod($object, $method, $args = null) + { + $args = func_get_args(); + $object = array_shift($args); + $method = array_shift($args); + + $refl = new \ReflectionObject($object); + $reflMethod = $refl->getMethod($method); + $reflMethod->setAccessible(true); + + return $reflMethod->invokeArgs($object, $args); + } + + /** + * Fetch a property of a class, bypassing visibility restrictions. + * + * @param string|object $class class name or instance + * @param string $property property name + * + * @return mixed Value of $class::$property + */ + public static function fetchStaticProperty($class, $property) + { + $refl = new \ReflectionClass($class); + $prop = $refl->getProperty($property); + $prop->setAccessible(true); + + return $prop->getValue(); + } + + /** + * Assign the value of a static property of a class, bypassing visibility restrictions. + * + * @param string|object $class class name or instance + * @param string $property property name + * @param mixed $value + * + * @return mixed Value of $class::$property + */ + public static function assignStaticProperty($class, $property, $value) + { + $refl = new \ReflectionClass($class); + $prop = $refl->getProperty($property); + $prop->setAccessible(true); + $prop->setValue($value); + + return $value; + } + + /** + * Call a static method on a class, bypassing visibility restrictions. + * + * @param string|object $class class name or instance + * @param string $method method name + * @param mixed $args... + * + * @return mixed + */ + public static function callStatic($class, $method, $args = null) + { + $args = func_get_args(); + $class = array_shift($args); + $method = array_shift($args); + + $refl = new \ReflectionClass($class); + $reflMethod = $refl->getMethod($method); + $reflMethod->setAccessible(true); + + return $reflMethod->invokeArgs(null, $args); + } + + /** + * Fetch a class constant, bypassing visibility restrictions. + * + * @param string|object $class class name or instance + * @param string $const constant name + * + * @return mixed + */ + public static function fetchClassConst($class, $const) + { + $refl = new \ReflectionClass($class); + + return $refl->getConstant($const); + } +} diff --git a/vendor/psy/psysh/src/Psy/Sudo/SudoVisitor.php b/vendor/psy/psysh/src/Psy/Sudo/SudoVisitor.php new file mode 100644 index 000000000..0bd77e9a4 --- /dev/null +++ b/vendor/psy/psysh/src/Psy/Sudo/SudoVisitor.php @@ -0,0 +1,115 @@ +var, + is_string($node->name) ? new String_($node->name) : $node->name, + ); + + return $this->prepareCall(self::PROPERTY_FETCH, $args); + } elseif ($node instanceof Assign && $node->var instanceof PropertyFetch) { + $target = $node->var; + $args = array( + $target->var, + is_string($target->name) ? new String_($target->name) : $target->name, + $node->expr, + ); + + return $this->prepareCall(self::PROPERTY_ASSIGN, $args); + } elseif ($node instanceof MethodCall) { + $args = $node->args; + array_unshift($args, new Arg(is_string($node->name) ? new String_($node->name) : $node->name)); + array_unshift($args, new Arg($node->var)); + + // not using prepareCall because the $node->args we started with are already Arg instances + return new StaticCall(new FullyQualifiedName(self::SUDO_CLASS), self::METHOD_CALL, $args); + } elseif ($node instanceof StaticPropertyFetch) { + $class = $node->class instanceof Name ? (string) $node->class : $node->class; + $args = array( + is_string($class) ? new String_($class) : $class, + is_string($node->name) ? new String_($node->name) : $node->name, + ); + + return $this->prepareCall(self::STATIC_PROPERTY_FETCH, $args); + } elseif ($node instanceof Assign && $node->var instanceof StaticPropertyFetch) { + $target = $node->var; + $class = $target->class instanceof Name ? (string) $target->class : $target->class; + $args = array( + is_string($class) ? new String_($class) : $class, + is_string($target->name) ? new String_($target->name) : $target->name, + $node->expr, + ); + + return $this->prepareCall(self::STATIC_PROPERTY_ASSIGN, $args); + } elseif ($node instanceof StaticCall) { + $args = $node->args; + $class = $node->class instanceof Name ? (string) $node->class : $node->class; + array_unshift($args, new Arg(is_string($node->name) ? new String_($node->name) : $node->name)); + array_unshift($args, new Arg(is_string($class) ? new String_($class) : $class)); + + // not using prepareCall because the $node->args we started with are already Arg instances + return new StaticCall(new FullyQualifiedName(self::SUDO_CLASS), self::STATIC_CALL, $args); + } elseif ($node instanceof ClassConstFetch) { + $class = $node->class instanceof Name ? (string) $node->class : $node->class; + $args = array( + is_string($class) ? new String_($class) : $class, + is_string($node->name) ? new String_($node->name) : $node->name, + ); + + return $this->prepareCall(self::CLASS_CONST_FETCH, $args); + } + } + + private function prepareCall($method, $args) + { + return new StaticCall(new FullyQualifiedName(self::SUDO_CLASS), $method, array_map(function ($arg) { + return new Arg($arg); + }, $args)); + } +} diff --git a/vendor/psy/psysh/src/Psy/TabCompletion/AutoCompleter.php b/vendor/psy/psysh/src/Psy/TabCompletion/AutoCompleter.php index a1fcd014a..86cd1663d 100644 --- a/vendor/psy/psysh/src/Psy/TabCompletion/AutoCompleter.php +++ b/vendor/psy/psysh/src/Psy/TabCompletion/AutoCompleter.php @@ -52,8 +52,18 @@ class AutoCompleter */ public function processCallback($input, $index, $info = array()) { - $line = substr($info['line_buffer'], 0, $info['end']); + // Some (Windows?) systems provide incomplete `readline_info`, so let's + // try to work around it. + $line = $info['line_buffer']; + if (isset($info['end'])) { + $line = substr($line, 0, $info['end']); + } + if ($line === '' && $input !== '') { + $line = $input; + } + $tokens = token_get_all('setScopeVariables($vars); + + // Show a couple of lines of call context for the debug session. + // + // @todo come up with a better way of doing this which doesn't involve injecting input :-P + if ($sh->has('whereami')) { + $sh->addInput('whereami -n2', true); + } + + if ($boundObject !== null) { + $sh->setBoundObject($boundObject); + } + + $sh->run(); + + return $sh->getScopeVariables(false); } } @@ -253,7 +312,7 @@ EOL; } catch (Exception $e) { echo $e->getMessage() . PHP_EOL; - // TODO: this triggers the "exited unexpectedly" logic in the + // @todo this triggers the "exited unexpectedly" logic in the // ForkingLoop, so we can't exit(1) after starting the shell... // fix this :) diff --git a/vendor/psy/psysh/test/Psy/Test/AutoloaderTest.php b/vendor/psy/psysh/test/Psy/Test/AutoloaderTest.php new file mode 100644 index 000000000..b906aaf29 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/AutoloaderTest.php @@ -0,0 +1,23 @@ +assertTrue(spl_autoload_unregister(array('Psy\Autoloader', 'autoload'))); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AbstractClassPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AbstractClassPassTest.php new file mode 100644 index 000000000..76f8c63c2 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AbstractClassPassTest.php @@ -0,0 +1,61 @@ +pass = new AbstractClassPass(); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor($this->pass); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + return array( + array('class A { abstract function a(); }'), + array('abstract class B { abstract function b() {} }'), + array('abstract class B { abstract function b() { echo "yep"; } }'), + ); + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + return array( + array('abstract class C { function c() {} }'), + array('abstract class D { abstract function d(); }'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AssignThisVariablePassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AssignThisVariablePassTest.php new file mode 100644 index 000000000..a8f7b835a --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AssignThisVariablePassTest.php @@ -0,0 +1,62 @@ +pass = new AssignThisVariablePass(); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor($this->pass); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + return array( + array('$this = 3'), + array('strtolower($this = "this")'), + ); + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + return array( + array('$this'), + array('$a = $this'), + array('$a = "this"; $$a = 3'), + array('$$this = "b"'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CallTimePassByReferencePassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CallTimePassByReferencePassTest.php new file mode 100644 index 000000000..e4e338f71 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CallTimePassByReferencePassTest.php @@ -0,0 +1,73 @@ +pass = new CallTimePassByReferencePass(); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor($this->pass); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + if (version_compare(PHP_VERSION, '5.4', '<')) { + $this->markTestSkipped(); + } + + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + return array( + array('f(&$arg)'), + array('$object->method($first, &$arg)'), + array('$closure($first, &$arg, $last)'), + array('A::b(&$arg)'), + ); + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + $data = array( + array('array(&$var)'), + array('$a = &$b'), + array('f(array(&$b))'), + ); + + if (version_compare(PHP_VERSION, '5.4', '<')) { + $data = array_merge($data, $this->invalidStatements()); + } + + return $data; + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CalledClassPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CalledClassPassTest.php new file mode 100644 index 000000000..dad8a05b7 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CalledClassPassTest.php @@ -0,0 +1,98 @@ +pass = new CalledClassPass(); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor($this->pass); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\ErrorException + */ + public function testProcessStatementFails($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + return array( + array('get_class()'), + array('get_class(null)'), + array('get_called_class()'), + array('get_called_class(null)'), + array('function foo() { return get_class(); }'), + array('function foo() { return get_class(null); }'), + array('function foo() { return get_called_class(); }'), + array('function foo() { return get_called_class(null); }'), + ); + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + return array( + array('get_class($foo)'), + array('get_class(bar())'), + array('get_called_class($foo)'), + array('get_called_class(bar())'), + array('function foo($bar) { return get_class($bar); }'), + array('function foo($bar) { return get_called_class($bar); }'), + array('class Foo { function bar() { return get_class(); } }'), + array('class Foo { function bar() { return get_class(null); } }'), + array('class Foo { function bar() { return get_called_class(); } }'), + array('class Foo { function bar() { return get_called_class(null); } }'), + array('$foo = function () {}; $foo()'), + ); + } + + /** + * @dataProvider validTraitStatements + */ + public function testProcessTraitStatementPasses($code) + { + if (version_compare(PHP_VERSION, '5.4', '<')) { + $this->markTestSkipped(); + } + + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validTraitStatements() + { + return array( + array('trait Foo { function bar() { return get_class(); } }'), + array('trait Foo { function bar() { return get_class(null); } }'), + array('trait Foo { function bar() { return get_called_class(); } }'), + array('trait Foo { function bar() { return get_called_class(null); } }'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CodeCleanerTestCase.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CodeCleanerTestCase.php new file mode 100644 index 000000000..b2f2fcdde --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CodeCleanerTestCase.php @@ -0,0 +1,97 @@ +pass = $pass; + if (!isset($this->traverser)) { + $this->traverser = new NodeTraverser(); + } + $this->traverser->addVisitor($this->pass); + } + + protected function parse($code, $prefix = 'getParser()->parse($code); + } catch (\PhpParser\Error $e) { + if (!$this->parseErrorIsEOF($e)) { + throw ParseErrorException::fromParseError($e); + } + + try { + // Unexpected EOF, try again with an implicit semicolon + return $this->getParser()->parse($code . ';'); + } catch (\PhpParser\Error $e) { + return false; + } + } + } + + protected function traverse(array $stmts) + { + return $this->traverser->traverse($stmts); + } + + protected function prettyPrint(array $stmts) + { + return $this->getPrinter()->prettyPrint($stmts); + } + + protected function assertProcessesAs($from, $to) + { + $stmts = $this->parse($from); + $stmts = $this->traverse($stmts); + $this->assertEquals($to, $this->prettyPrint($stmts)); + } + + private function getParser() + { + if (!isset($this->parser)) { + $parserFactory = new ParserFactory(); + $this->parser = $parserFactory->createParser(); + } + + return $this->parser; + } + + private function getPrinter() + { + if (!isset($this->printer)) { + $this->printer = new Printer(); + } + + return $this->printer; + } + + private function parseErrorIsEOF(\PhpParser\Error $e) + { + $msg = $e->getRawMessage(); + + return ($msg === 'Unexpected token EOF') || (strpos($msg, 'Syntax error, unexpected EOF') !== false); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ExitPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ExitPassTest.php new file mode 100644 index 000000000..43b55546b --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ExitPassTest.php @@ -0,0 +1,59 @@ +setPass(new ExitPass()); + } + + /** + * @dataProvider dataProviderExitStatement + */ + public function testExitStatement($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + /** + * Data provider for testExitStatement. + * + * @return array + */ + public function dataProviderExitStatement() + { + return array( + array('exit;', "{$this->expectedExceptionString};"), + array('exit();', "{$this->expectedExceptionString};"), + array('die;', "{$this->expectedExceptionString};"), + array('exit(die(die));', "{$this->expectedExceptionString};"), + array('if (true) { exit; }', "if (true) {\n {$this->expectedExceptionString};\n}"), + array('if (false) { exit; }', "if (false) {\n {$this->expectedExceptionString};\n}"), + array('1 and exit();', "1 and {$this->expectedExceptionString};"), + array('foo() or die', "foo() or {$this->expectedExceptionString};"), + array('exit and 1;', "{$this->expectedExceptionString} and 1;"), + array('if (exit) { echo $wat; }', "if ({$this->expectedExceptionString}) {\n echo \$wat;\n}"), + array('exit or die;', "{$this->expectedExceptionString} or {$this->expectedExceptionString};"), + array('switch (die) { }', "switch ({$this->expectedExceptionString}) {\n}"), + array('for ($i = 1; $i < 10; die) {}', "for (\$i = 1; \$i < 10; {$this->expectedExceptionString}) {\n}"), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/FinalClassPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/FinalClassPassTest.php new file mode 100644 index 000000000..e368fc9e2 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/FinalClassPassTest.php @@ -0,0 +1,69 @@ +pass = new FinalClassPass(); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor($this->pass); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + $stmts = array( + array('final class A {} class B extends A {}'), + array('class A {} final class B extends A {} class C extends B {}'), + // array('namespace A { final class B {} } namespace C { class D extends \\A\\B {} }'), + ); + + if (!defined('HHVM_VERSION')) { + // For some reason Closure isn't final in HHVM? + $stmts[] = array('class A extends \\Closure {}'); + } + + return $stmts; + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + return array( + array('class A extends \\stdClass {}'), + array('final class A extends \\stdClass {}'), + array('class A {} class B extends A {}'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/Fixtures/ClassWithCallStatic.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/Fixtures/ClassWithCallStatic.php new file mode 100644 index 000000000..f576ebf66 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/Fixtures/ClassWithCallStatic.php @@ -0,0 +1,20 @@ +pass = new FunctionReturnInWriteContextPass(); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor($this->pass); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + * @expectedExceptionMessage Can't use function return value in write context + */ + public function testProcessStatementFails($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + return array( + array('f(&g())'), + array('array(& $object->method())'), + array('$a->method(& $closure())'), + array('array(& A::b())'), + array('f() = 5'), + ); + } + + public function testIsset() + { + try { + $this->traverser->traverse($this->parse('isset(strtolower("A"))')); + $this->fail(); + } catch (FatalErrorException $e) { + if (version_compare(PHP_VERSION, '5.5', '>=')) { + $this->assertContains( + 'Cannot use isset() on the result of a function call (you can use "null !== func()" instead)', + $e->getMessage() + ); + } else { + $this->assertContains("Can't use function return value in write context", $e->getMessage()); + } + } + } + + /** + * @expectedException \Psy\Exception\FatalErrorException + * @expectedExceptionMessage Can't use function return value in write context + */ + public function testEmpty() + { + if (version_compare(PHP_VERSION, '5.5', '>=')) { + $this->markTestSkipped(); + } + + $this->traverser->traverse($this->parse('empty(strtolower("A"))')); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ImplicitReturnPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ImplicitReturnPassTest.php new file mode 100644 index 000000000..e6a1bdfe6 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ImplicitReturnPassTest.php @@ -0,0 +1,96 @@ +setPass(new ImplicitReturnPass()); + } + + /** + * @dataProvider implicitReturns + */ + public function testProcess($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function implicitReturns() + { + $values = array( + array('4', 'return 4;'), + array('foo()', 'return foo();'), + array('return 1', 'return 1;'), + ); + + $from = 'if (true) { 1; } elseif (true) { 2; } else { 3; }'; + $to = <<<'EOS' +if (true) { + return 1; +} elseif (true) { + return 2; +} else { + return 3; +} +return new \Psy\CodeCleaner\NoReturnValue(); +EOS; + $values[] = array($from, $to); + + $from = 'class A {}'; + $to = <<<'EOS' +class A +{ +} +return new \Psy\CodeCleaner\NoReturnValue(); +EOS; + $values[] = array($from, $to); + + $from = <<<'EOS' +switch (false) { + case 0: + 0; + case 1: + 1; + break; + case 2: + 2; + return; +} +EOS; + $to = <<<'EOS' +switch (false) { + case 0: + 0; + case 1: + return 1; + break; + case 2: + 2; + return; +} +return new \Psy\CodeCleaner\NoReturnValue(); +EOS; + $values[] = array($from, $to); + + if (version_compare(PHP_VERSION, '5.4', '<')) { + $values[] = array('exit()', 'die;'); + } else { + $values[] = array('exit()', 'exit;'); + } + + return $values; + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/InstanceOfPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/InstanceOfPassTest.php new file mode 100644 index 000000000..7fea4e725 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/InstanceOfPassTest.php @@ -0,0 +1,73 @@ +setPass(new InstanceOfPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessInvalidStatement($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + return array( + array('null instanceof stdClass'), + array('true instanceof stdClass'), + array('9 instanceof stdClass'), + array('1.0 instanceof stdClass'), + array('"foo" instanceof stdClass'), + array('__DIR__ instanceof stdClass'), + array('PHP_SAPI instanceof stdClass'), + array('1+1 instanceof stdClass'), + array('true && false instanceof stdClass'), + array('"a"."b" instanceof stdClass'), + array('!5 instanceof stdClass'), + ); + } + + /** + * @dataProvider validStatements + */ + public function testProcessValidStatement($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + $data = array( + array('$a instanceof stdClass'), + array('strtolower("foo") instanceof stdClass'), + array('array(1) instanceof stdClass'), + array('(string) "foo" instanceof stdClass'), + array('(1+1) instanceof stdClass'), + array('"foo ${foo} $bar" instanceof stdClass'), + array('DateTime::ISO8601 instanceof stdClass'), + ); + + return $data; + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LeavePsyshAlonePassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LeavePsyshAlonePassTest.php new file mode 100644 index 000000000..3311e4117 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LeavePsyshAlonePassTest.php @@ -0,0 +1,69 @@ +setPass(new LeavePsyshAlonePass()); + } + + public function testPassesInlineHtmlThroughJustFine() + { + $inline = $this->parse('not php at all!', ''); + $this->traverse($inline); + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $stmts = $this->parse($code); + $this->traverse($stmts); + } + + public function validStatements() + { + return array( + array('array_merge()'), + array('__psysh__()'), + array('$this'), + array('$psysh'), + array('$__psysh'), + array('$banana'), + ); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\RuntimeException + */ + public function testProcessStatementFails($code) + { + $stmts = $this->parse($code); + $this->traverse($stmts); + } + + public function invalidStatements() + { + return array( + array('$__psysh__'), + array('var_dump($__psysh__)'), + array('$__psysh__ = "your mom"'), + array('$__psysh__->fakeFunctionCall()'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LegacyEmptyPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LegacyEmptyPassTest.php new file mode 100644 index 000000000..8853a9119 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LegacyEmptyPassTest.php @@ -0,0 +1,77 @@ +setPass(new LegacyEmptyPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\ParseErrorException + */ + public function testProcessInvalidStatement($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + if (version_compare(PHP_VERSION, '5.5', '>=')) { + return array( + array('empty()'), + ); + } + + return array( + array('empty()'), + array('empty(null)'), + array('empty(PHP_EOL)'), + array('empty("wat")'), + array('empty(1.1)'), + array('empty(Foo::$bar)'), + ); + } + + /** + * @dataProvider validStatements + */ + public function testProcessValidStatement($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + if (version_compare(PHP_VERSION, '5.5', '<')) { + return array( + array('empty($foo)'), + ); + } + + return array( + array('empty($foo)'), + array('empty(null)'), + array('empty(PHP_EOL)'), + array('empty("wat")'), + array('empty(1.1)'), + array('empty(Foo::$bar)'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LoopContextPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LoopContextPassTest.php new file mode 100644 index 000000000..9d1c8d99f --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LoopContextPassTest.php @@ -0,0 +1,134 @@ +pass = new LoopContextPass(); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor($this->pass); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + return array( + array('continue'), + array('break'), + array('if (true) { continue; }'), + array('if (true) { break; }'), + array('if (false) { continue; }'), + array('if (false) { break; }'), + array('function foo() { break; }'), + array('function foo() { continue; }'), + + // actually enforce break/continue depth argument + array('do { break 2; } while (true)'), + array('do { continue 2; } while (true)'), + array('for ($a; $b; $c) { break 2; }'), + array('for ($a; $b; $c) { continue 2; }'), + array('foreach ($a as $b) { break 2; }'), + array('foreach ($a as $b) { continue 2; }'), + array('switch (true) { default: break 2; }'), + array('switch (true) { default: continue 2; }'), + array('while (true) { break 2; }'), + array('while (true) { continue 2; }'), + + // invalid in 5.4+ because they're floats + // ... in 5.3 because the number is too big + array('while (true) { break 2.0; }'), + array('while (true) { continue 2.0; }'), + + // and once with nested loops, just for good measure + array('while (true) { while (true) { break 3; } }'), + array('while (true) { while (true) { continue 3; } }'), + ); + } + + /** + * @dataProvider invalidPHP54Statements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testPHP54ProcessStatementFails($code) + { + if (version_compare(PHP_VERSION, '5.4.0', '<')) { + $this->markTestSkipped(); + } + + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidPHP54Statements() + { + return array( + // In PHP 5.4+, only positive literal integers are allowed + array('while (true) { break $n; }'), + array('while (true) { continue $n; }'), + array('while (true) { break N; }'), + array('while (true) { continue N; }'), + array('while (true) { break 0; }'), + array('while (true) { continue 0; }'), + array('while (true) { break -1; }'), + array('while (true) { continue -1; }'), + array('while (true) { break 1.0; }'), + array('while (true) { continue 1.0; }'), + ); + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + return array( + array('do { break; } while (true)'), + array('do { continue; } while (true)'), + array('for ($a; $b; $c) { break; }'), + array('for ($a; $b; $c) { continue; }'), + array('foreach ($a as $b) { break; }'), + array('foreach ($a as $b) { continue; }'), + array('switch (true) { default: break; }'), + array('switch (true) { default: continue; }'), + array('while (true) { break; }'), + array('while (true) { continue; }'), + + // `break 1` is redundant, but not invalid + array('while (true) { break 1; }'), + array('while (true) { continue 1; }'), + + // and once with nested loops just for good measure + array('while (true) { while (true) { break 2; } }'), + array('while (true) { while (true) { continue 2; } }'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/MagicConstantsPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/MagicConstantsPassTest.php new file mode 100644 index 000000000..1f78e12d2 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/MagicConstantsPassTest.php @@ -0,0 +1,39 @@ +setPass(new MagicConstantsPass()); + } + + /** + * @dataProvider magicConstants + */ + public function testProcess($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function magicConstants() + { + return array( + array('__DIR__;', 'getcwd();'), + array('__FILE__;', "'';"), + array('___FILE___;', '___FILE___;'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/NamespacePassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/NamespacePassTest.php new file mode 100644 index 000000000..553a699a7 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/NamespacePassTest.php @@ -0,0 +1,56 @@ +cleaner = new CodeCleaner(); + $this->setPass(new NamespacePass($this->cleaner)); + } + + public function testProcess() + { + $this->process('array_merge()'); + $this->assertNull($this->cleaner->getNamespace()); + + // A non-block namespace statement should set the current namespace. + $this->process('namespace Alpha'); + $this->assertEquals(array('Alpha'), $this->cleaner->getNamespace()); + + // A new non-block namespace statement should override the current namespace. + $this->process('namespace Beta; class B {}'); + $this->assertEquals(array('Beta'), $this->cleaner->getNamespace()); + + // @todo Figure out if we can detect when the last namespace block is + // bracketed or unbracketed, because this should really clear the + // namespace at the end... + $this->process('namespace Gamma { array_merge(); }'); + $this->assertEquals(array('Gamma'), $this->cleaner->getNamespace()); + + // A null namespace clears out the current namespace. + $this->process('namespace { array_merge(); }'); + $this->assertNull($this->cleaner->getNamespace()); + } + + private function process($code) + { + $stmts = $this->parse($code); + $this->traverse($stmts); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/PassableByReferencePassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/PassableByReferencePassTest.php new file mode 100644 index 000000000..96a6b6665 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/PassableByReferencePassTest.php @@ -0,0 +1,109 @@ +pass = new PassableByReferencePass(); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor($this->pass); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + return array( + array('array_pop(array())'), + array('array_pop(array($foo))'), + array('array_shift(array())'), + ); + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + return array( + array('array_pop(json_decode("[]"))'), + array('array_pop($foo)'), + array('array_pop($foo->bar)'), + array('array_pop($foo::baz)'), + array('array_pop(Foo::qux)'), + ); + } + + /** + * @dataProvider validArrayMultisort + */ + public function testArrayMultisort($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validArrayMultisort() + { + return array( + array('array_multisort($a)'), + array('array_multisort($a, $b)'), + array('array_multisort($a, SORT_NATURAL, $b)'), + array('array_multisort($a, SORT_NATURAL | SORT_FLAG_CASE, $b)'), + array('array_multisort($a, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE, $b)'), + array('array_multisort($a, SORT_NATURAL | SORT_FLAG_CASE, SORT_ASC, $b)'), + array('array_multisort($a, $b, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE)'), + array('array_multisort($a, SORT_NATURAL | SORT_FLAG_CASE, $b, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE)'), + array('array_multisort($a, 1, $b)'), + array('array_multisort($a, 1 + 2, $b)'), + array('array_multisort($a, getMultisortFlags(), $b)'), + ); + } + + /** + * @dataProvider invalidArrayMultisort + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testInvalidArrayMultisort($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidArrayMultisort() + { + return array( + array('array_multisort(1)'), + array('array_multisort(array(1, 2, 3))'), + array('array_multisort($a, SORT_NATURAL, SORT_ASC, SORT_NATURAL, $b)'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/RequirePassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/RequirePassTest.php new file mode 100644 index 000000000..bf1763287 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/RequirePassTest.php @@ -0,0 +1,95 @@ +setPass(new RequirePass()); + } + + /** + * @dataProvider exitStatements + */ + public function testExitStatement($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function exitStatements() + { + $resolve = '\\Psy\\CodeCleaner\\RequirePass::resolve'; + + if (version_compare(PHP_VERSION, '5.4', '<')) { + return array( + array('require $foo', "$resolve(\$foo, 1);"), + array('$bar = require $baz', "\$bar = $resolve(\$baz, 1);"), + ); + } + + return array( + // The basics + array('require "a"', "$resolve(\"a\", 1);"), + array('require "b.php"', "$resolve(\"b.php\", 1);"), + array('require_once "c"', "$resolve(\"c\", 1);"), + array('require_once "d.php"', "$resolve(\"d.php\", 1);"), + + // Ensure that line numbers work correctly + array("null;\nrequire \"e.php\"", "null;\n$resolve(\"e.php\", 2);"), + array("null;\nrequire_once \"f.php\"", "null;\n$resolve(\"f.php\", 2);"), + + // Things with expressions + array('require $foo', "$resolve(\$foo, 1);"), + array('require_once $foo', "$resolve(\$foo, 1);"), + array('require ($bar = "g.php")', "$resolve(\$bar = \"g.php\", 1);"), + array('require_once ($bar = "h.php")', "$resolve(\$bar = \"h.php\", 1);"), + array('$bar = require ($baz = "i.php")', "\$bar = $resolve(\$baz = \"i.php\", 1);"), + array('$bar = require_once ($baz = "j.php")', "\$bar = $resolve(\$baz = \"j.php\", 1);"), + ); + } + + /** + * @expectedException \Psy\Exception\FatalErrorException + * @expectedExceptionMessage Failed opening required 'not a file name' in eval()'d code on line 2 + */ + public function testResolve() + { + RequirePass::resolve('not a file name', 2); + } + + /** + * @dataProvider emptyWarnings + * + * @expectedException \Psy\Exception\ErrorException + * @expectedExceptionMessage Filename cannot be empty on line 1 + */ + public function testResolveEmptyWarnings($file) + { + if (!E_WARNING & error_reporting()) { + $this->markTestSkipped(); + } + + RequirePass::resolve($file, 1); + } + + public function emptyWarnings() + { + return array( + array(null), + array(false), + array(''), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StaticConstructorPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StaticConstructorPassTest.php new file mode 100644 index 000000000..611fa30a7 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StaticConstructorPassTest.php @@ -0,0 +1,91 @@ +setPass(new StaticConstructorPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessInvalidStatement($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + /** + * @dataProvider invalidParserStatements + * @expectedException \Psy\Exception\ParseErrorException + */ + public function testProcessInvalidStatementCatchedByParser($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + $statements = array( + array('class A { public static function A() {}}'), + array('class A { private static function A() {}}'), + ); + + if (version_compare(PHP_VERSION, '5.3.3', '<')) { + $statements[] = array('namespace B; class A { private static function A() {}}'); + } + + return $statements; + } + + public function invalidParserStatements() + { + $statements = array( + array('class A { public static function __construct() {}}'), + array('class A { private static function __construct() {}}'), + array('class A { private static function __construct() {} public function A() {}}'), + array('namespace B; class A { private static function __construct() {}}'), + ); + + return $statements; + } + + /** + * @dataProvider validStatements + */ + public function testProcessValidStatement($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function validStatements() + { + $statements = array( + array('class A { public static function A() {} public function __construct() {}}'), + array('class A { private function __construct() {} public static function A() {}}'), + ); + + if (version_compare(PHP_VERSION, '5.3.3', '>=')) { + $statements[] = array('namespace B; class A { private static function A() {}}'); + } + + return $statements; + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StrictTypesPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StrictTypesPassTest.php new file mode 100644 index 000000000..8458fc01b --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StrictTypesPassTest.php @@ -0,0 +1,53 @@ +markTestSkipped(); + } + + $this->setPass(new StrictTypesPass()); + } + + public function testProcess() + { + $this->assertProcessesAs('declare(strict_types=1)', 'declare (strict_types=1);'); + $this->assertProcessesAs('null', "declare (strict_types=1);\nnull;"); + $this->assertProcessesAs('declare(strict_types=0)', 'declare (strict_types=0);'); + $this->assertProcessesAs('null', 'null;'); + } + + /** + * @dataProvider invalidDeclarations + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testInvalidDeclarations($declaration) + { + $stmts = $this->parse($declaration); + $this->traverser->traverse($stmts); + } + + public function invalidDeclarations() + { + return array( + array('declare(strict_types=-1)'), + array('declare(strict_types=2)'), + array('declare(strict_types="foo")'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/UseStatementPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/UseStatementPassTest.php new file mode 100644 index 000000000..9c525efef --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/UseStatementPassTest.php @@ -0,0 +1,52 @@ +setPass(new UseStatementPass()); + } + + /** + * @dataProvider useStatements + */ + public function testProcess($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function useStatements() + { + return array( + array( + "use StdClass as NotSoStd;\n\$std = new NotSoStd();", + '$std = new \\StdClass();', + ), + array( + "namespace Foo;\n\nuse StdClass as S;\n\$std = new S();", + "namespace Foo;\n\n\$std = new \\StdClass();", + ), + array( + "namespace Foo;\n\nuse \\StdClass as S;\n\$std = new S();", + "namespace Foo;\n\n\$std = new \\StdClass();", + ), + array( + "use Foo\\Bar as fb;\n\$baz = new fb\\Baz();", + '$baz = new \\Foo\\Bar\\Baz();', + ), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidClassNamePassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidClassNamePassTest.php new file mode 100644 index 000000000..06ad4e224 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidClassNamePassTest.php @@ -0,0 +1,333 @@ +setPass(new ValidClassNamePass()); + } + + /** + * @dataProvider getInvalid + */ + public function testProcessInvalid($code, $php54 = false) + { + try { + $stmts = $this->parse($code); + $this->traverse($stmts); + $this->fail(); + } catch (Exception $e) { + if ($php54 && version_compare(PHP_VERSION, '5.4', '<')) { + $this->assertInstanceOf('Psy\Exception\ParseErrorException', $e); + } else { + $this->assertInstanceOf('Psy\Exception\FatalErrorException', $e); + } + } + } + + public function getInvalid() + { + // class declarations + return array( + // core class + array('class stdClass {}'), + // capitalization + array('class stdClass {}'), + + // collisions with interfaces and traits + array('interface stdClass {}'), + array('trait stdClass {}', true), + + // collisions inside the same code snippet + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + ', true), + array(' + trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + ', true), + array(' + trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + ', true), + array(' + interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + ', true), + array(' + interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} + '), + + // namespaced collisions + array(' + namespace Psy\\Test\\CodeCleaner { + class ValidClassNamePassTest {} + } + '), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { + class Beta {} + } + namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { + class Beta {} + } + '), + + // extends and implements + array('class ValidClassNamePassTest extends NotAClass {}'), + array('class ValidClassNamePassTest extends ArrayAccess {}'), + array('class ValidClassNamePassTest implements stdClass {}'), + array('class ValidClassNamePassTest implements ArrayAccess, stdClass {}'), + array('interface ValidClassNamePassTest extends stdClass {}'), + array('interface ValidClassNamePassTest extends ArrayAccess, stdClass {}'), + + // class instantiations + array('new Psy_Test_CodeCleaner_ValidClassNamePass_Gamma();'), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { + new Psy_Test_CodeCleaner_ValidClassNamePass_Delta(); + } + '), + + // class constant fetch + array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::FOO'), + + // static call + array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::foo()'), + array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::$foo()'), + ); + } + + /** + * @dataProvider getValid + */ + public function testProcessValid($code) + { + $stmts = $this->parse($code); + $this->traverse($stmts); + } + + public function getValid() + { + $valid = array( + // class declarations + array('class Psy_Test_CodeCleaner_ValidClassNamePass_Epsilon {}'), + array('namespace Psy\Test\CodeCleaner\ValidClassNamePass; class Zeta {}'), + array(' + namespace { class Psy_Test_CodeCleaner_ValidClassNamePass_Eta {}; } + namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { + class Psy_Test_CodeCleaner_ValidClassNamePass_Eta {} + } + '), + array('namespace Psy\Test\CodeCleaner\ValidClassNamePass { class stdClass {} }'), + + // class instantiations + array('new stdClass();'), + array('new stdClass();'), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { + class Theta {} + } + namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { + new Theta(); + } + '), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { + class Iota {} + new Iota(); + } + '), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { + class Kappa {} + } + namespace { + new \\Psy\\Test\\CodeCleaner\\ValidClassNamePass\\Kappa(); + } + '), + + // Class constant fetch (ValidConstantPassTest validates the actual constant) + array('class A {} A::FOO'), + array('$a = new DateTime; $a::ATOM'), + array('interface A { const B = 1; } A::B'), + + // static call + array('DateTime::createFromFormat()'), + array('DateTime::$someMethod()'), + array('Psy\Test\CodeCleaner\Fixtures\ClassWithStatic::doStuff()'), + array('Psy\Test\CodeCleaner\Fixtures\ClassWithCallStatic::doStuff()'), + + // Allow `self` and `static` as class names. + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { + public static function getInstance() { + return new self(); + } + } + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { + public static function getInstance() { + return new SELF(); + } + } + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { + public static function getInstance() { + return new self; + } + } + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { + public static function getInstance() { + return new static(); + } + } + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { + public static function getInstance() { + return new Static(); + } + } + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { + public static function getInstance() { + return new static; + } + } + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { + public static function foo() { + return parent::bar(); + } + } + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { + public static function foo() { + return self::bar(); + } + } + '), + array(' + class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { + public static function foo() { + return static::bar(); + } + } + '), + + array('class A { static function b() { return new A; } }'), + array(' + class A { + const B = 123; + function c() { + return A::B; + } + } + '), + array('class A {} class B { function c() { return new A; } }'), + + // recursion + array('class A { function a() { A::a(); } }'), + + // conditionally defined classes + array(' + class A {} + if (false) { + class A {} + } + '), + array(' + class A {} + if (true) { + class A {} + } else if (false) { + class A {} + } else { + class A {} + } + '), + // ewww + array(' + class A {} + if (true): + class A {} + elseif (false): + class A {} + else: + class A {} + endif; + '), + array(' + class A {} + while (false) { class A {} } + '), + array(' + class A {} + do { class A {} } while (false); + '), + array(' + class A {} + switch (1) { + case 0: + class A {} + break; + case 1: + class A {} + break; + case 2: + class A {} + break; + } + '), + ); + + // Ugh. There's gotta be a better way to test for this. + if (class_exists('PhpParser\ParserFactory')) { + // PHP 7.0 anonymous classes, only supported by PHP Parser v2.x + $valid[] = array('$obj = new class() {}'); + } + + if (version_compare(PHP_VERSION, '5.5', '>=')) { + $valid[] = array('interface A {} A::class'); + $valid[] = array('interface A {} A::CLASS'); + $valid[] = array('class A {} A::class'); + $valid[] = array('class A {} A::CLASS'); + $valid[] = array('A::class'); + $valid[] = array('A::CLASS'); + } + + return $valid; + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidConstantPassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidConstantPassTest.php new file mode 100644 index 000000000..2d77c8935 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidConstantPassTest.php @@ -0,0 +1,66 @@ +setPass(new ValidConstantPass()); + } + + /** + * @dataProvider getInvalidReferences + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessInvalidConstantReferences($code) + { + $stmts = $this->parse($code); + $this->traverse($stmts); + } + + public function getInvalidReferences() + { + return array( + array('Foo\BAR'), + + // class constant fetch + array('Psy\Test\CodeCleaner\ValidConstantPassTest::FOO'), + array('DateTime::BACON'), + ); + } + + /** + * @dataProvider getValidReferences + */ + public function testProcessValidConstantReferences($code) + { + $stmts = $this->parse($code); + $this->traverse($stmts); + } + + public function getValidReferences() + { + return array( + array('PHP_EOL'), + + // class constant fetch + array('NotAClass::FOO'), + array('DateTime::ATOM'), + array('$a = new DateTime; $a::ATOM'), + array('DateTime::class'), + array('$a = new DateTime; $a::class'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidFunctionNamePassTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidFunctionNamePassTest.php new file mode 100644 index 000000000..1f2b8fbf5 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidFunctionNamePassTest.php @@ -0,0 +1,181 @@ +setPass(new ValidFunctionNamePass()); + } + + /** + * @dataProvider getInvalidFunctions + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessInvalidFunctionCallsAndDeclarations($code) + { + $stmts = $this->parse($code); + $this->traverse($stmts); + } + + public function getInvalidFunctions() + { + return array( + // function declarations + array('function array_merge() {}'), + array('function Array_Merge() {}'), + array(' + function psy_test_codecleaner_validfunctionnamepass_alpha() {} + function psy_test_codecleaner_validfunctionnamepass_alpha() {} + '), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + function beta() {} + } + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + function beta() {} + } + '), + + // function calls + array('psy_test_codecleaner_validfunctionnamepass_gamma()'), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + delta(); + } + '), + + // recursion + array('function a() { a(); } function a() {}'), + ); + } + + /** + * @dataProvider getValidFunctions + */ + public function testProcessValidFunctionCallsAndDeclarations($code) + { + $stmts = $this->parse($code); + $this->traverse($stmts); + } + + public function getValidFunctions() + { + return array( + array('function psy_test_codecleaner_validfunctionnamepass_epsilon() {}'), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + function zeta() {} + } + '), + array(' + namespace { + function psy_test_codecleaner_validfunctionnamepass_eta() {} + } + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + function psy_test_codecleaner_validfunctionnamepass_eta() {} + } + '), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + function psy_test_codecleaner_validfunctionnamepass_eta() {} + } + namespace { + function psy_test_codecleaner_validfunctionnamepass_eta() {} + } + '), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + function array_merge() {} + } + '), + + // function calls + array('array_merge();'), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + function theta() {} + } + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + theta(); + } + '), + // closures + array('$test = function(){};$test()'), + array(' + namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { + function theta() {} + } + namespace { + Psy\\Test\\CodeCleaner\\ValidFunctionNamePass\\theta(); + } + '), + + // recursion + array('function a() { a(); }'), + + // conditionally defined functions + array(' + function a() {} + if (false) { + function a() {} + } + '), + array(' + function a() {} + if (true) { + function a() {} + } else if (false) { + function a() {} + } else { + function a() {} + } + '), + // ewww + array(' + function a() {} + if (true): + function a() {} + elseif (false): + function a() {} + else: + function a() {} + endif; + '), + array(' + function a() {} + while (false) { function a() {} } + '), + array(' + function a() {} + do { function a() {} } while (false); + '), + array(' + function a() {} + switch (1) { + case 0: + function a() {} + break; + case 1: + function a() {} + break; + case 2: + function a() {} + break; + } + '), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/CodeCleanerTest.php b/vendor/psy/psysh/test/Psy/Test/CodeCleanerTest.php new file mode 100644 index 000000000..3200ac0cf --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/CodeCleanerTest.php @@ -0,0 +1,128 @@ +assertEquals($expected, $cc->clean($lines, $requireSemicolons)); + } + + public function semicolonCodeProvider() + { + $values = array( + array(array('true'), false, 'return true;'), + array(array('true;'), false, 'return true;'), + array(array('true;'), true, 'return true;'), + array(array('true'), true, false), + + array(array('echo "foo";', 'true'), true, false), + ); + + if (version_compare(PHP_VERSION, '5.4', '<')) { + $values[] = array(array('echo "foo";', 'true'), false, "echo 'foo';\nreturn true;"); + } else { + $values[] = array(array('echo "foo";', 'true'), false, "echo \"foo\";\nreturn true;"); + } + + return $values; + } + + /** + * @dataProvider unclosedStatementsProvider + */ + public function testUnclosedStatements(array $lines, $isUnclosed) + { + $cc = new CodeCleaner(); + $res = $cc->clean($lines); + + if ($isUnclosed) { + $this->assertFalse($res); + } else { + $this->assertNotFalse($res); + } + } + + public function unclosedStatementsProvider() + { + return array( + array(array('echo "'), true), + array(array('echo \''), true), + array(array('if (1) {'), true), + + array(array('echo ""'), false), + array(array("echo ''"), false), + array(array('if (1) {}'), false), + + array(array('// closed comment'), false), + array(array('function foo() { /**'), true), + ); + } + + /** + * @dataProvider moreUnclosedStatementsProvider + */ + public function testMoreUnclosedStatements(array $lines) + { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM not supported.'); + } + + $cc = new CodeCleaner(); + $res = $cc->clean($lines); + + $this->assertFalse($res); + } + + public function moreUnclosedStatementsProvider() + { + return array( + array(array("\$content = <<clean(array($code)); + } + + public function invalidStatementsProvider() + { + return array( + array('function "what'), + array("function 'what"), + array('echo }'), + array('echo {'), + array('if (1) }'), + array('echo """'), + array("echo '''"), + array('$foo "bar'), + array('$foo \'bar'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/ConfigurationTest.php b/vendor/psy/psysh/test/Psy/Test/ConfigurationTest.php new file mode 100644 index 000000000..99604a6dd --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/ConfigurationTest.php @@ -0,0 +1,262 @@ + $configFile ?: __DIR__ . '/../../fixtures/empty.php', + )); + } + + public function testDefaults() + { + $config = $this->getConfig(); + + $this->assertEquals(function_exists('readline'), $config->hasReadline()); + $this->assertEquals(function_exists('readline'), $config->useReadline()); + $this->assertEquals(function_exists('pcntl_signal'), $config->hasPcntl()); + $this->assertEquals(function_exists('pcntl_signal'), $config->usePcntl()); + $this->assertFalse($config->requireSemicolons()); + $this->assertSame(Configuration::COLOR_MODE_AUTO, $config->colorMode()); + $this->assertNull($config->getStartupMessage()); + } + + public function testGettersAndSetters() + { + $config = $this->getConfig(); + + $this->assertNull($config->getDataDir()); + $config->setDataDir('wheee'); + $this->assertEquals('wheee', $config->getDataDir()); + + $this->assertNull($config->getConfigDir()); + $config->setConfigDir('wheee'); + $this->assertEquals('wheee', $config->getConfigDir()); + } + + /** + * @dataProvider directories + */ + public function testFilesAndDirectories($home, $configFile, $historyFile, $manualDbFile) + { + $oldHome = getenv('HOME'); + putenv("HOME=$home"); + + $config = new Configuration(); + $this->assertEquals(realpath($configFile), realpath($config->getConfigFile())); + $this->assertEquals(realpath($historyFile), realpath($config->getHistoryFile())); + $this->assertEquals(realpath($manualDbFile), realpath($config->getManualDbFile())); + + putenv("HOME=$oldHome"); + } + + public function directories() + { + $base = realpath(__DIR__ . '/../../fixtures'); + + return array( + array( + $base . '/default', + $base . '/default/.config/psysh/config.php', + $base . '/default/.config/psysh/psysh_history', + $base . '/default/.local/share/psysh/php_manual.sqlite', + ), + array( + $base . '/legacy', + $base . '/legacy/.psysh/rc.php', + $base . '/legacy/.psysh/history', + $base . '/legacy/.psysh/php_manual.sqlite', + ), + array( + $base . '/mixed', + $base . '/mixed/.psysh/config.php', + $base . '/mixed/.psysh/psysh_history', + null, + ), + ); + } + + public function testLoadConfig() + { + $config = $this->getConfig(); + $cleaner = new CodeCleaner(); + $pager = new PassthruPager(new ConsoleOutput()); + $loop = new Loop($config); + + $config->loadConfig(array( + 'useReadline' => false, + 'usePcntl' => false, + 'codeCleaner' => $cleaner, + 'pager' => $pager, + 'loop' => $loop, + 'requireSemicolons' => true, + 'errorLoggingLevel' => E_ERROR | E_WARNING, + 'colorMode' => Configuration::COLOR_MODE_FORCED, + 'startupMessage' => 'Psysh is awesome!', + )); + + $this->assertFalse($config->useReadline()); + $this->assertFalse($config->usePcntl()); + $this->assertSame($cleaner, $config->getCodeCleaner()); + $this->assertSame($pager, $config->getPager()); + $this->assertSame($loop, $config->getLoop()); + $this->assertTrue($config->requireSemicolons()); + $this->assertEquals(E_ERROR | E_WARNING, $config->errorLoggingLevel()); + $this->assertSame(Configuration::COLOR_MODE_FORCED, $config->colorMode()); + $this->assertSame('Psysh is awesome!', $config->getStartupMessage()); + } + + public function testLoadConfigFile() + { + $config = $this->getConfig(__DIR__ . '/../../fixtures/config.php'); + + $runtimeDir = $this->joinPath(realpath(sys_get_temp_dir()), 'psysh_test', 'withconfig', 'temp'); + + $this->assertStringStartsWith($runtimeDir, realpath($config->getTempFile('foo', 123))); + $this->assertStringStartsWith($runtimeDir, realpath(dirname($config->getPipe('pipe', 123)))); + $this->assertStringStartsWith($runtimeDir, realpath($config->getRuntimeDir())); + + $this->assertEquals(function_exists('readline'), $config->useReadline()); + $this->assertFalse($config->usePcntl()); + $this->assertEquals(E_ALL & ~E_NOTICE, $config->errorLoggingLevel()); + } + + public function testLoadLocalConfigFile() + { + $oldPwd = getenv('PWD'); + putenv('PWD=' . realpath(__DIR__ . '/../../fixtures/project/')); + + $config = new Configuration(); + + // When no configuration file is specified local project config is merged + $this->assertFalse($config->useReadline()); + $this->assertTrue($config->usePcntl()); + + $config = new Configuration(array('configFile' => __DIR__ . '/../../fixtures/config.php')); + + // Defining a configuration file skips loading local project config + $this->assertTrue($config->useReadline()); + $this->assertFalse($config->usePcntl()); + + putenv("PWD=$oldPwd"); + } + + /** + * @expectedException \Psy\Exception\DeprecatedException + */ + public function testBaseDirConfigIsDeprecated() + { + $config = new Configuration(array('baseDir' => 'fake')); + } + + private function joinPath() + { + return implode(DIRECTORY_SEPARATOR, func_get_args()); + } + + public function testConfigIncludes() + { + $config = new Configuration(array( + 'defaultIncludes' => array('/file.php'), + 'configFile' => __DIR__ . '/../../fixtures/empty.php', + )); + + $includes = $config->getDefaultIncludes(); + $this->assertCount(1, $includes); + $this->assertEquals('/file.php', $includes[0]); + } + + public function testGetOutput() + { + $config = $this->getConfig(); + $output = $config->getOutput(); + + $this->assertInstanceOf('\Psy\Output\ShellOutput', $output); + } + + public function getOutputDecoratedProvider() + { + return array( + 'auto' => array( + null, + Configuration::COLOR_MODE_AUTO, + ), + 'forced' => array( + true, + Configuration::COLOR_MODE_FORCED, + ), + 'disabled' => array( + false, + Configuration::COLOR_MODE_DISABLED, + ), + ); + } + + /** @dataProvider getOutputDecoratedProvider */ + public function testGetOutputDecorated($expectation, $colorMode) + { + $config = $this->getConfig(); + $config->setColorMode($colorMode); + + $this->assertSame($expectation, $config->getOutputDecorated()); + } + + public function setColorModeValidProvider() + { + return array( + 'auto' => array(Configuration::COLOR_MODE_AUTO), + 'forced' => array(Configuration::COLOR_MODE_FORCED), + 'disabled' => array(Configuration::COLOR_MODE_DISABLED), + ); + } + + /** @dataProvider setColorModeValidProvider */ + public function testSetColorModeValid($colorMode) + { + $config = $this->getConfig(); + $config->setColorMode($colorMode); + + $this->assertEquals($colorMode, $config->colorMode()); + } + + public function testSetColorModeInvalid() + { + $config = $this->getConfig(); + $colorMode = 'some invalid mode'; + + $this->setExpectedException( + '\InvalidArgumentException', + 'invalid color mode: some invalid mode' + ); + $config->setColorMode($colorMode); + } + + public function testSetCheckerValid() + { + $config = $this->getConfig(); + $checker = new GitHubChecker(); + + $config->setChecker($checker); + + $this->assertSame($checker, $config->getChecker()); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/ConsoleColorFactoryTest.php b/vendor/psy/psysh/test/Psy/Test/ConsoleColorFactoryTest.php new file mode 100644 index 000000000..9e9ced7e5 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/ConsoleColorFactoryTest.php @@ -0,0 +1,51 @@ +getConsoleColor(); + $themes = $colors->getThemes(); + + $this->assertFalse($colors->isStyleForced()); + $this->assertEquals(array('blue'), $themes['line_number']); + } + + public function testGetConsoleColorForced() + { + $colorMode = Configuration::COLOR_MODE_FORCED; + $factory = new ConsoleColorFactory($colorMode); + $colors = $factory->getConsoleColor(); + $themes = $colors->getThemes(); + + $this->assertTrue($colors->isStyleForced()); + $this->assertEquals(array('blue'), $themes['line_number']); + } + + public function testGetConsoleColorDisabled() + { + $colorMode = Configuration::COLOR_MODE_DISABLED; + $factory = new ConsoleColorFactory($colorMode); + $colors = $factory->getConsoleColor(); + $themes = $colors->getThemes(); + + $this->assertFalse($colors->isStyleForced()); + $this->assertEquals(array('none'), $themes['line_number']); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Exception/BreakExceptionTest.php b/vendor/psy/psysh/test/Psy/Test/Exception/BreakExceptionTest.php new file mode 100644 index 000000000..75f5e5d86 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Exception/BreakExceptionTest.php @@ -0,0 +1,34 @@ +assertTrue($e instanceof Exception); + $this->assertTrue($e instanceof BreakException); + } + + public function testMessage() + { + $e = new BreakException('foo'); + + $this->assertContains('foo', $e->getMessage()); + $this->assertEquals('foo', $e->getRawMessage()); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Exception/ErrorExceptionTest.php b/vendor/psy/psysh/test/Psy/Test/Exception/ErrorExceptionTest.php new file mode 100644 index 000000000..f4ca54f2e --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Exception/ErrorExceptionTest.php @@ -0,0 +1,108 @@ +assertTrue($e instanceof Exception); + $this->assertTrue($e instanceof \ErrorException); + $this->assertTrue($e instanceof ErrorException); + } + + public function testMessage() + { + $e = new ErrorException('foo'); + + $this->assertContains('foo', $e->getMessage()); + $this->assertEquals('foo', $e->getRawMessage()); + } + + /** + * @dataProvider getLevels + */ + public function testErrorLevels($level, $type) + { + $e = new ErrorException('foo', 0, $level); + $this->assertContains('PHP ' . $type, $e->getMessage()); + } + + /** + * @dataProvider getLevels + */ + public function testThrowException($level, $type) + { + try { + ErrorException::throwException($level, '{whot}', '{file}', '13'); + } catch (ErrorException $e) { + $this->assertContains('PHP ' . $type, $e->getMessage()); + $this->assertContains('{whot}', $e->getMessage()); + $this->assertContains('in {file}', $e->getMessage()); + $this->assertContains('on line 13', $e->getMessage()); + } + } + + public function getLevels() + { + return array( + array(E_WARNING, 'warning'), + array(E_CORE_WARNING, 'warning'), + array(E_COMPILE_WARNING, 'warning'), + array(E_USER_WARNING, 'warning'), + array(E_STRICT, 'Strict error'), + array(0, 'error'), + ); + } + + /** + * @dataProvider getUserLevels + */ + public function testThrowExceptionAsErrorHandler($level, $type) + { + set_error_handler(array('Psy\Exception\ErrorException', 'throwException')); + try { + trigger_error('{whot}', $level); + } catch (ErrorException $e) { + $this->assertContains('PHP ' . $type, $e->getMessage()); + $this->assertContains('{whot}', $e->getMessage()); + } + restore_error_handler(); + } + + public function getUserLevels() + { + return array( + array(E_USER_ERROR, 'error'), + array(E_USER_WARNING, 'warning'), + array(E_USER_NOTICE, 'error'), + array(E_USER_DEPRECATED, 'error'), + ); + } + + public function testIgnoreExecutionLoopFilename() + { + $e = new ErrorException('{{message}}', 0, 1, '/fake/path/to/Psy/ExecutionLoop/Loop.php'); + $this->assertEmpty($e->getFile()); + + $e = new ErrorException('{{message}}', 0, 1, 'c:\fake\path\to\Psy\ExecutionLoop\Loop.php'); + $this->assertEmpty($e->getFile()); + + $e = new ErrorException('{{message}}', 0, 1, '/fake/path/to/Psy/File.php'); + $this->assertNotEmpty($e->getFile()); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Exception/FatalErrorExceptionTest.php b/vendor/psy/psysh/test/Psy/Test/Exception/FatalErrorExceptionTest.php new file mode 100644 index 000000000..2a443ca49 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Exception/FatalErrorExceptionTest.php @@ -0,0 +1,46 @@ +assertTrue($e instanceof Exception); + $this->assertTrue($e instanceof \ErrorException); + $this->assertTrue($e instanceof FatalErrorException); + } + + public function testMessage() + { + $e = new FatalErrorException('{msg}', 0, 0, '{filename}', 13); + + $this->assertEquals('{msg}', $e->getRawMessage()); + $this->assertContains('{msg}', $e->getMessage()); + $this->assertContains('{filename}', $e->getMessage()); + $this->assertContains('line 13', $e->getMessage()); + } + + public function testMessageWithNoFilename() + { + $e = new FatalErrorException('{msg}'); + + $this->assertEquals('{msg}', $e->getRawMessage()); + $this->assertContains('{msg}', $e->getMessage()); + $this->assertContains('eval()\'d code', $e->getMessage()); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Exception/ParseErrorExceptionTest.php b/vendor/psy/psysh/test/Psy/Test/Exception/ParseErrorExceptionTest.php new file mode 100644 index 000000000..c68100259 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Exception/ParseErrorExceptionTest.php @@ -0,0 +1,43 @@ +assertTrue($e instanceof Exception); + $this->assertTrue($e instanceof \PhpParser\Error); + $this->assertTrue($e instanceof ParseErrorException); + } + + public function testMessage() + { + $e = new ParseErrorException('{msg}', 1); + + $this->assertContains('{msg}', $e->getMessage()); + $this->assertContains('PHP Parse error:', $e->getMessage()); + } + + public function testConstructFromParseError() + { + $e = ParseErrorException::fromParseError(new \PhpParser\Error('{msg}')); + + $this->assertContains('{msg}', $e->getRawMessage()); + $this->assertContains('PHP Parse error:', $e->getMessage()); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Exception/RuntimeExceptionTest.php b/vendor/psy/psysh/test/Psy/Test/Exception/RuntimeExceptionTest.php new file mode 100644 index 000000000..c1eb5e19b --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Exception/RuntimeExceptionTest.php @@ -0,0 +1,31 @@ +assertTrue($e instanceof Exception); + $this->assertTrue($e instanceof \RuntimeException); + $this->assertTrue($e instanceof RuntimeException); + + $this->assertEquals($msg, $e->getMessage()); + $this->assertEquals($msg, $e->getRawMessage()); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Formatter/CodeFormatterTest.php b/vendor/psy/psysh/test/Psy/Test/Formatter/CodeFormatterTest.php new file mode 100644 index 000000000..aa028715f --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Formatter/CodeFormatterTest.php @@ -0,0 +1,61 @@ + 18| private function ignoreThisMethod($arg) + 19| { + 20| echo 'whot!'; + 21| } +EOS; + + $formatted = CodeFormatter::format(new \ReflectionMethod($this, 'ignoreThisMethod')); + $formattedWithoutColors = preg_replace('#' . chr(27) . '\[\d\d?m#', '', $formatted); + + $this->assertEquals($expected, rtrim($formattedWithoutColors)); + $this->assertNotEquals($expected, rtrim($formatted)); + } + + /** + * @dataProvider filenames + * @expectedException \Psy\Exception\RuntimeException + */ + public function testCodeFormatterThrowsException($filename) + { + $reflector = $this->getMockBuilder('ReflectionClass') + ->disableOriginalConstructor() + ->getMock(); + + $reflector + ->expects($this->once()) + ->method('getFileName') + ->will($this->returnValue($filename)); + + CodeFormatter::format($reflector); + } + + public function filenames() + { + return array(array(null), array('not a file')); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Formatter/DocblockFormatterTest.php b/vendor/psy/psysh/test/Psy/Test/Formatter/DocblockFormatterTest.php new file mode 100644 index 000000000..3a736d7c6 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Formatter/DocblockFormatterTest.php @@ -0,0 +1,63 @@ + + * + * @throws InvalidArgumentException if $foo is empty + * + * @param mixed $foo It's a foo thing + * @param int $bar This is definitely bar + * + * @return string A string of no consequence + */ + private function methodWithDocblock($foo, $bar = 1) + { + if (empty($foo)) { + throw new \InvalidArgumentException(); + } + + return 'method called'; + } + + public function testFormat() + { + $expected = <<Description: + This is a docblock! + +Throws: + InvalidArgumentException if \$foo is empty + +Param: + mixed \$foo It's a foo thing + int \$bar This is definitely bar + +Return: + string A string of no consequence + +Author: Justin Hileman \ +EOS; + + $this->assertEquals( + $expected, + DocblockFormatter::format(new \ReflectionMethod($this, 'methodWithDocblock')) + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Formatter/SignatureFormatterTest.php b/vendor/psy/psysh/test/Psy/Test/Formatter/SignatureFormatterTest.php new file mode 100644 index 000000000..0ceb5b477 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Formatter/SignatureFormatterTest.php @@ -0,0 +1,77 @@ +assertEquals($expected, strip_tags(SignatureFormatter::format($reflector))); + } + + public function signatureReflectors() + { + return array( + array( + new \ReflectionClass($this), + "class Psy\Test\Formatter\SignatureFormatterTest " + . 'extends PHPUnit_Framework_TestCase implements ' + . 'Countable, PHPUnit_Framework_SelfDescribing, ' + . 'PHPUnit_Framework_Test', + ), + array( + new \ReflectionFunction('implode'), + defined('HHVM_VERSION') ? 'function implode($arg1, $arg2 = null)' : 'function implode($glue, $pieces)', + ), + array( + new ReflectionConstant($this, 'FOO'), + 'const FOO = "foo value"', + ), + array( + new \ReflectionMethod($this, 'someFakeMethod'), + 'private function someFakeMethod(array $one, $two = \'TWO\', Reflector $three = null)', + ), + array( + new \ReflectionProperty($this, 'bar'), + 'private static $bar', + ), + array( + new \ReflectionClass('Psy\CodeCleaner\CodeCleanerPass'), + 'abstract class Psy\CodeCleaner\CodeCleanerPass ' + . 'extends PhpParser\NodeVisitorAbstract ' + . 'implements PhpParser\NodeVisitor', + ), + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSignatureFormatterThrowsUnknownReflectorExpeption() + { + $refl = $this->getMockBuilder('Reflector')->getMock(); + SignatureFormatter::format($refl); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Input/CodeArgumentTest.php b/vendor/psy/psysh/test/Psy/Test/Input/CodeArgumentTest.php new file mode 100644 index 000000000..a87357e8f --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Input/CodeArgumentTest.php @@ -0,0 +1,52 @@ +assertInstanceOf('Psy\Input\CodeArgument', new CodeArgument('yeah', $mode)); + } + + public function getValidModes() + { + return array( + array(InputArgument::REQUIRED), + array(InputArgument::OPTIONAL), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Input/ShellInputTest.php b/vendor/psy/psysh/test/Psy/Test/Input/ShellInputTest.php new file mode 100644 index 000000000..5b15bccf3 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Input/ShellInputTest.php @@ -0,0 +1,204 @@ +getProperty('tokenPairs'); + $p->setAccessible(true); + $this->assertEquals($tokens, $p->getValue($input), $message); + } + + public function testInputOptionWithGivenString() + { + $definition = new InputDefinition(array( + new InputOption('foo', null, InputOption::VALUE_REQUIRED), + new CodeArgument('code', null, InputOption::VALUE_REQUIRED), + )); + + $input = new ShellInput('--foo=bar echo "baz\n";'); + $input->bind($definition); + $this->assertEquals('bar', $input->getOption('foo')); + $this->assertEquals('echo "baz\n";', $input->getArgument('code')); + } + + public function testInputOptionWithoutCodeArguments() + { + $definition = new InputDefinition(array( + new InputOption('foo', null, InputOption::VALUE_REQUIRED), + new InputArgument('bar', null, InputOption::VALUE_REQUIRED), + new InputArgument('baz', null, InputOption::VALUE_REQUIRED), + )); + + $input = new ShellInput('--foo=foo bar "baz\n"'); + $input->bind($definition); + $this->assertEquals('foo', $input->getOption('foo')); + $this->assertEquals('bar', $input->getArgument('bar')); + $this->assertEquals("baz\n", $input->getArgument('baz')); + } + + public function getTokenizeData() + { + // Test all the cases from StringInput test, ensuring they have an appropriate $rest token. + return array( + array( + '', + array(), + '->tokenize() parses an empty string', + ), + array( + 'foo', + array(array('foo', 'foo')), + '->tokenize() parses arguments', + ), + array( + ' foo bar ', + array(array('foo', 'foo bar '), array('bar', 'bar ')), + '->tokenize() ignores whitespaces between arguments', + ), + array( + '"quoted"', + array(array('quoted', '"quoted"')), + '->tokenize() parses quoted arguments', + ), + array( + "'quoted'", + array(array('quoted', "'quoted'")), + '->tokenize() parses quoted arguments', + ), + array( + "'a\rb\nc\td'", + array(array("a\rb\nc\td", "'a\rb\nc\td'")), + '->tokenize() parses whitespace chars in strings', + ), + array( + "'a'\r'b'\n'c'\t'd'", + array( + array('a', "'a'\r'b'\n'c'\t'd'"), + array('b', "'b'\n'c'\t'd'"), + array('c', "'c'\t'd'"), + array('d', "'d'"), + ), + '->tokenize() parses whitespace chars between args as spaces', + ), + array( + '\"quoted\"', + array(array('"quoted"', '\"quoted\"')), + '->tokenize() parses escaped-quoted arguments', + ), + array( + "\'quoted\'", + array(array('\'quoted\'', "\'quoted\'")), + '->tokenize() parses escaped-quoted arguments', + ), + array( + '-a', + array(array('-a', '-a')), + '->tokenize() parses short options', + ), + array( + '-azc', + array(array('-azc', '-azc')), + '->tokenize() parses aggregated short options', + ), + array( + '-awithavalue', + array(array('-awithavalue', '-awithavalue')), + '->tokenize() parses short options with a value', + ), + array( + '-a"foo bar"', + array(array('-afoo bar', '-a"foo bar"')), + '->tokenize() parses short options with a value', + ), + array( + '-a"foo bar""foo bar"', + array(array('-afoo barfoo bar', '-a"foo bar""foo bar"')), + '->tokenize() parses short options with a value', + ), + array( + '-a\'foo bar\'', + array(array('-afoo bar', '-a\'foo bar\'')), + '->tokenize() parses short options with a value', + ), + array( + '-a\'foo bar\'\'foo bar\'', + array(array('-afoo barfoo bar', '-a\'foo bar\'\'foo bar\'')), + '->tokenize() parses short options with a value', + ), + array( + '-a\'foo bar\'"foo bar"', + array(array('-afoo barfoo bar', '-a\'foo bar\'"foo bar"')), + '->tokenize() parses short options with a value', + ), + array( + '--long-option', + array(array('--long-option', '--long-option')), + '->tokenize() parses long options', + ), + array( + '--long-option=foo', + array(array('--long-option=foo', '--long-option=foo')), + '->tokenize() parses long options with a value', + ), + array( + '--long-option="foo bar"', + array(array('--long-option=foo bar', '--long-option="foo bar"')), + '->tokenize() parses long options with a value', + ), + array( + '--long-option="foo bar""another"', + array(array('--long-option=foo baranother', '--long-option="foo bar""another"')), + '->tokenize() parses long options with a value', + ), + array( + '--long-option=\'foo bar\'', + array(array('--long-option=foo bar', '--long-option=\'foo bar\'')), + '->tokenize() parses long options with a value', + ), + array( + "--long-option='foo bar''another'", + array(array('--long-option=foo baranother', "--long-option='foo bar''another'")), + '->tokenize() parses long options with a value', + ), + array( + "--long-option='foo bar'\"another\"", + array(array('--long-option=foo baranother', "--long-option='foo bar'\"another\"")), + '->tokenize() parses long options with a value', + ), + array( + 'foo -a -ffoo --long bar', + array( + array('foo', 'foo -a -ffoo --long bar'), + array('-a', '-a -ffoo --long bar'), + array('-ffoo', '-ffoo --long bar'), + array('--long', '--long bar'), + array('bar', 'bar'), + ), + '->tokenize() parses when several arguments and options', + ), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Readline/GNUReadlineTest.php b/vendor/psy/psysh/test/Psy/Test/Readline/GNUReadlineTest.php new file mode 100644 index 000000000..45fbb9b58 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Readline/GNUReadlineTest.php @@ -0,0 +1,80 @@ +markTestSkipped('GNUReadline not enabled'); + } + + $this->historyFile = tempnam(sys_get_temp_dir(), 'psysh_test_history'); + file_put_contents($this->historyFile, "_HiStOrY_V2_\n"); + } + + public function testHistory() + { + $readline = new GNUReadline($this->historyFile); + $this->assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $this->assertEquals(array('foo'), $readline->listHistory()); + $readline->addHistory('bar'); + $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $readline->addHistory('baz'); + $this->assertEquals(array('foo', 'bar', 'baz'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } + + /** + * @depends testHistory + */ + public function testHistorySize() + { + $readline = new GNUReadline($this->historyFile, 2); + $this->assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $readline->addHistory('bar'); + $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $readline->addHistory('baz'); + $this->assertEquals(array('bar', 'baz'), $readline->listHistory()); + $readline->addHistory('w00t'); + $this->assertEquals(array('baz', 'w00t'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } + + /** + * @depends testHistory + */ + public function testHistoryEraseDups() + { + $readline = new GNUReadline($this->historyFile, 0, true); + $this->assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $readline->addHistory('bar'); + $readline->addHistory('foo'); + $this->assertEquals(array('bar', 'foo'), $readline->listHistory()); + $readline->addHistory('baz'); + $readline->addHistory('w00t'); + $readline->addHistory('baz'); + $this->assertEquals(array('bar', 'foo', 'w00t', 'baz'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Readline/HoaConsoleTest.php b/vendor/psy/psysh/test/Psy/Test/Readline/HoaConsoleTest.php new file mode 100644 index 000000000..2ddbbc982 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Readline/HoaConsoleTest.php @@ -0,0 +1,31 @@ +assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $this->assertEquals(array('foo'), $readline->listHistory()); + $readline->addHistory('bar'); + $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $readline->addHistory('baz'); + $this->assertEquals(array('foo', 'bar', 'baz'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Readline/LibeditTest.php b/vendor/psy/psysh/test/Psy/Test/Readline/LibeditTest.php new file mode 100644 index 000000000..c87d22c2e --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Readline/LibeditTest.php @@ -0,0 +1,128 @@ +markTestSkipped('Libedit not enabled'); + } + + $this->historyFile = tempnam(sys_get_temp_dir(), 'psysh_test_history'); + if (false === file_put_contents($this->historyFile, "_HiStOrY_V2_\n")) { + $this->fail('Unable to write history file: ' . $this->historyFile); + } + // Calling readline_read_history before readline_clear_history + // avoids segfault with PHP 5.5.7 & libedit v3.1 + readline_read_history($this->historyFile); + readline_clear_history(); + } + + public function tearDown() + { + if (is_file($this->historyFile)) { + unlink($this->historyFile); + } + } + + public function testHistory() + { + $readline = new Libedit($this->historyFile); + $this->assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $this->assertEquals(array('foo'), $readline->listHistory()); + $readline->addHistory('bar'); + $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $readline->addHistory('baz'); + $this->assertEquals(array('foo', 'bar', 'baz'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } + + /** + * @depends testHistory + */ + public function testHistorySize() + { + $readline = new Libedit($this->historyFile, 2); + $this->assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $readline->addHistory('bar'); + $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $readline->addHistory('baz'); + $this->assertEquals(array('bar', 'baz'), $readline->listHistory()); + $readline->addHistory('w00t'); + $this->assertEquals(array('baz', 'w00t'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } + + /** + * @depends testHistory + */ + public function testHistoryEraseDups() + { + $readline = new Libedit($this->historyFile, 0, true); + $this->assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $readline->addHistory('bar'); + $readline->addHistory('foo'); + $this->assertEquals(array('bar', 'foo'), $readline->listHistory()); + $readline->addHistory('baz'); + $readline->addHistory('w00t'); + $readline->addHistory('baz'); + $this->assertEquals(array('bar', 'foo', 'w00t', 'baz'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } + + public function testListHistory() + { + $readline = new Libedit($this->historyFile); + file_put_contents( + $this->historyFile, + "This is an entry\n\0This is a comment\nThis is an entry\0With a comment\n", + FILE_APPEND + ); + $this->assertEquals(array( + 'This is an entry', + 'This is an entry', + ), $readline->listHistory()); + $readline->clearHistory(); + } + + /** + * Libedit being a BSD library, + * it doesn't support non-unix line separators. + */ + public function testLinebreaksSupport() + { + $readline = new Libedit($this->historyFile); + file_put_contents( + $this->historyFile, + "foo\rbar\nbaz\r\nw00t", + FILE_APPEND + ); + $this->assertEquals(array( + "foo\rbar", + "baz\r", + 'w00t', + ), $readline->listHistory()); + $readline->clearHistory(); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Readline/TransientTest.php b/vendor/psy/psysh/test/Psy/Test/Readline/TransientTest.php new file mode 100644 index 000000000..133f5779a --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Readline/TransientTest.php @@ -0,0 +1,76 @@ +assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $this->assertEquals(array('foo'), $readline->listHistory()); + $readline->addHistory('bar'); + $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $readline->addHistory('baz'); + $this->assertEquals(array('foo', 'bar', 'baz'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } + + /** + * @depends testHistory + */ + public function testHistorySize() + { + $readline = new Transient(null, 2); + $this->assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $readline->addHistory('bar'); + $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $readline->addHistory('baz'); + $this->assertEquals(array('bar', 'baz'), $readline->listHistory()); + $readline->addHistory('w00t'); + $this->assertEquals(array('baz', 'w00t'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } + + /** + * @depends testHistory + */ + public function testHistoryEraseDups() + { + $readline = new Transient(null, 0, true); + $this->assertEmpty($readline->listHistory()); + $readline->addHistory('foo'); + $readline->addHistory('bar'); + $readline->addHistory('foo'); + $this->assertEquals(array('bar', 'foo'), $readline->listHistory()); + $readline->addHistory('baz'); + $readline->addHistory('w00t'); + $readline->addHistory('baz'); + $this->assertEquals(array('bar', 'foo', 'w00t', 'baz'), $readline->listHistory()); + $readline->clearHistory(); + $this->assertEmpty($readline->listHistory()); + } + + public function testSomeThingsAreAlwaysTrue() + { + $readline = new Transient(); + $this->assertTrue(Transient::isSupported()); + $this->assertTrue($readline->readHistory()); + $this->assertTrue($readline->writeHistory()); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Reflection/ReflectionConstantTest.php b/vendor/psy/psysh/test/Psy/Test/Reflection/ReflectionConstantTest.php new file mode 100644 index 000000000..a3c6464b0 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Reflection/ReflectionConstantTest.php @@ -0,0 +1,60 @@ +getDeclaringClass(); + + $this->assertTrue($class instanceof \ReflectionClass); + $this->assertEquals('Psy\Test\Reflection\ReflectionConstantTest', $class->getName()); + $this->assertEquals('CONSTANT_ONE', $refl->getName()); + $this->assertEquals('CONSTANT_ONE', (string) $refl); + $this->assertEquals('one', $refl->getValue()); + $this->assertEquals(null, $refl->getFileName()); + $this->assertFalse($refl->getDocComment()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testUnknownConstantThrowsException() + { + new ReflectionConstant($this, 'UNKNOWN_CONSTANT'); + } + + /** + * @expectedException \RuntimeException + * @dataProvider notYetImplemented + */ + public function testNotYetImplemented($method) + { + $refl = new ReflectionConstant($this, 'CONSTANT_ONE'); + $refl->$method(); + } + + public function notYetImplemented() + { + return array( + array('getStartLine'), + array('getEndLine'), + array('export'), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/ShellTest.php b/vendor/psy/psysh/test/Psy/Test/ShellTest.php new file mode 100644 index 000000000..ade798d1e --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/ShellTest.php @@ -0,0 +1,346 @@ +streams as $stream) { + fclose($stream); + } + } + + public function testScopeVariables() + { + $one = 'banana'; + $two = 123; + $three = new \StdClass(); + $__psysh__ = 'ignore this'; + $_ = 'ignore this'; + $_e = 'ignore this'; + + $shell = new Shell($this->getConfig()); + $shell->setScopeVariables(compact('one', 'two', 'three', '__psysh__', '_', '_e', 'this')); + + $this->assertNotContains('__psysh__', $shell->getScopeVariableNames()); + $this->assertEquals(array('one', 'two', 'three', '_'), $shell->getScopeVariableNames()); + $this->assertEquals('banana', $shell->getScopeVariable('one')); + $this->assertEquals(123, $shell->getScopeVariable('two')); + $this->assertSame($three, $shell->getScopeVariable('three')); + $this->assertNull($shell->getScopeVariable('_')); + + $shell->setScopeVariables(array()); + $this->assertEquals(array('_'), $shell->getScopeVariableNames()); + + $shell->setBoundObject($this); + $this->assertEquals(array('_', 'this'), $shell->getScopeVariableNames()); + $this->assertSame($this, $shell->getScopeVariable('this')); + $this->assertEquals(array('_' => null), $shell->getScopeVariables(false)); + $this->assertEquals(array('_' => null, 'this' => $this), $shell->getScopeVariables()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testUnknownScopeVariablesThrowExceptions() + { + $shell = new Shell($this->getConfig()); + $shell->setScopeVariables(array('foo' => 'FOO', 'bar' => 1)); + $shell->getScopeVariable('baz'); + } + + public function testIncludes() + { + $config = $this->getConfig(array('configFile' => __DIR__ . '/../../fixtures/empty.php')); + + $shell = new Shell($config); + $this->assertEmpty($shell->getIncludes()); + $shell->setIncludes(array('foo', 'bar', 'baz')); + $this->assertEquals(array('foo', 'bar', 'baz'), $shell->getIncludes()); + } + + public function testIncludesConfig() + { + $config = $this->getConfig(array( + 'defaultIncludes' => array('/file.php'), + 'configFile' => __DIR__ . '/../../fixtures/empty.php', + )); + + $shell = new Shell($config); + + $includes = $shell->getIncludes(); + $this->assertEquals('/file.php', $includes[0]); + } + + public function testAddMatchersViaConfig() + { + $config = $this->getConfig(array( + 'tabCompletionMatchers' => array( + new ClassMethodsMatcher(), + ), + )); + + $matchers = $config->getTabCompletionMatchers(); + + $this->assertTrue(array_pop($matchers) instanceof ClassMethodsMatcher); + } + + public function testRenderingExceptions() + { + $shell = new Shell($this->getConfig()); + $output = $this->getOutput(); + $stream = $output->getStream(); + $e = new ParseErrorException('message', 13); + + $shell->setOutput($output); + $shell->addCode('code'); + $this->assertTrue($shell->hasCode()); + $this->assertNotEmpty($shell->getCodeBuffer()); + + $shell->writeException($e); + + $this->assertSame($e, $shell->getScopeVariable('_e')); + $this->assertFalse($shell->hasCode()); + $this->assertEmpty($shell->getCodeBuffer()); + + rewind($stream); + $streamContents = stream_get_contents($stream); + + $this->assertContains('PHP Parse error', $streamContents); + $this->assertContains('message', $streamContents); + $this->assertContains('line 13', $streamContents); + } + + public function testHandlingErrors() + { + $shell = new Shell($this->getConfig()); + $output = $this->getOutput(); + $stream = $output->getStream(); + $shell->setOutput($output); + + $oldLevel = error_reporting(); + error_reporting($oldLevel & ~E_USER_NOTICE); + + try { + $shell->handleError(E_USER_NOTICE, 'wheee', null, 13); + } catch (ErrorException $e) { + error_reporting($oldLevel); + $this->fail('Unexpected error exception'); + } + error_reporting($oldLevel); + + rewind($stream); + $streamContents = stream_get_contents($stream); + + $this->assertContains('PHP error:', $streamContents); + $this->assertContains('wheee', $streamContents); + $this->assertContains('line 13', $streamContents); + } + + /** + * @expectedException \Psy\Exception\ErrorException + */ + public function testNotHandlingErrors() + { + $shell = new Shell($this->getConfig()); + $oldLevel = error_reporting(); + error_reporting($oldLevel | E_USER_NOTICE); + + try { + $shell->handleError(E_USER_NOTICE, 'wheee', null, 13); + } catch (ErrorException $e) { + error_reporting($oldLevel); + throw $e; + } + } + + public function testVersion() + { + $shell = new Shell($this->getConfig()); + + $this->assertInstanceOf('Symfony\Component\Console\Application', $shell); + $this->assertContains(Shell::VERSION, $shell->getVersion()); + $this->assertContains(phpversion(), $shell->getVersion()); + $this->assertContains(php_sapi_name(), $shell->getVersion()); + } + + public function testCodeBuffer() + { + $shell = new Shell($this->getConfig()); + + $shell->addCode('class'); + $this->assertNull($shell->flushCode()); + $this->assertTrue($shell->hasCode()); + + $shell->addCode('a'); + $this->assertNull($shell->flushCode()); + $this->assertTrue($shell->hasCode()); + + $shell->addCode('{}'); + $code = $shell->flushCode(); + $this->assertFalse($shell->hasCode()); + $code = preg_replace('/\s+/', ' ', $code); + $this->assertNotNull($code); + $this->assertEquals('class a { } return new \\Psy\\CodeCleaner\\NoReturnValue();', $code); + } + + public function testKeepCodeBufferOpen() + { + $shell = new Shell($this->getConfig()); + + $shell->addCode('1 \\'); + $this->assertNull($shell->flushCode()); + $this->assertTrue($shell->hasCode()); + + $shell->addCode('+ 1 \\'); + $this->assertNull($shell->flushCode()); + $this->assertTrue($shell->hasCode()); + + $shell->addCode('+ 1'); + $code = $shell->flushCode(); + $this->assertFalse($shell->hasCode()); + $code = preg_replace('/\s+/', ' ', $code); + $this->assertNotNull($code); + $this->assertEquals('return 1 + 1 + 1;', $code); + } + + /** + * @expectedException \Psy\Exception\ParseErrorException + */ + public function testCodeBufferThrowsParseExceptions() + { + $shell = new Shell($this->getConfig()); + $shell->addCode('this is not valid'); + $shell->flushCode(); + } + + public function testClosuresSupport() + { + $shell = new Shell($this->getConfig()); + $code = '$test = function () {}'; + $shell->addCode($code); + $shell->flushCode(); + $code = '$test()'; + $shell->addCode($code); + $shell->flushCode(); + } + + public function testWriteStdout() + { + $output = $this->getOutput(); + $stream = $output->getStream(); + $shell = new Shell($this->getConfig()); + $shell->setOutput($output); + + $shell->writeStdout("{{stdout}}\n"); + + rewind($stream); + $streamContents = stream_get_contents($stream); + + $this->assertEquals('{{stdout}}' . PHP_EOL, $streamContents); + } + + public function testWriteStdoutWithoutNewline() + { + $output = $this->getOutput(); + $stream = $output->getStream(); + $shell = new Shell($this->getConfig()); + $shell->setOutput($output); + + $shell->writeStdout('{{stdout}}'); + + rewind($stream); + $streamContents = stream_get_contents($stream); + + $this->assertEquals('{{stdout}}' . PHP_EOL, $streamContents); + } + + /** + * @dataProvider getReturnValues + */ + public function testWriteReturnValue($input, $expected) + { + $output = $this->getOutput(); + $stream = $output->getStream(); + $shell = new Shell($this->getConfig()); + $shell->setOutput($output); + + $shell->writeReturnValue($input); + rewind($stream); + $this->assertEquals($expected, stream_get_contents($stream)); + } + + public function getReturnValues() + { + return array( + array('{{return value}}', "=> \"\033[32m{{return value}}\033[39m\"" . PHP_EOL), + array(1, "=> \033[35m1\033[39m" . PHP_EOL), + ); + } + + /** + * @dataProvider getRenderedExceptions + */ + public function testWriteException($exception, $expected) + { + $output = $this->getOutput(); + $stream = $output->getStream(); + $shell = new Shell($this->getConfig()); + $shell->setOutput($output); + + $shell->writeException($exception); + rewind($stream); + $this->assertEquals($expected, stream_get_contents($stream)); + } + + public function getRenderedExceptions() + { + return array( + array(new \Exception('{{message}}'), "Exception with message '{{message}}'" . PHP_EOL), + ); + } + + private function getOutput() + { + $stream = fopen('php://memory', 'w+'); + $this->streams[] = $stream; + + $output = new StreamOutput($stream, StreamOutput::VERBOSITY_NORMAL, false); + + return $output; + } + + private function getConfig(array $config = array()) + { + // Mebbe there's a better way than this? + $dir = tempnam(sys_get_temp_dir(), 'psysh_shell_test_'); + unlink($dir); + + $defaults = array( + 'configDir' => $dir, + 'dataDir' => $dir, + 'runtimeDir' => $dir, + ); + + return new Configuration(array_merge($defaults, $config)); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/TabCompletion/AutoCompleterTest.php b/vendor/psy/psysh/test/Psy/Test/TabCompletion/AutoCompleterTest.php new file mode 100644 index 000000000..c05048d43 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/TabCompletion/AutoCompleterTest.php @@ -0,0 +1,145 @@ +getAutoCompleter(); + foreach ($matchers as $matcher) { + if ($matcher instanceof ContextAware) { + $matcher->setContext($context); + } + $tabCompletion->addMatcher($matcher); + } + + $context->setAll(array('foo' => 12, 'bar' => new \DOMDocument())); + + $code = $tabCompletion->processCallback('', 0, array( + 'line_buffer' => $line, + 'point' => 0, + 'end' => strlen($line), + )); + + foreach ($mustContain as $mc) { + $this->assertContains($mc, $code); + } + + foreach ($mustNotContain as $mnc) { + $this->assertNotContains($mnc, $code); + } + } + + /** + * TODO + * ==== + * draft, open to modifications + * - [ ] if the variable is an array, return the square bracket for completion + * - [ ] if the variable is a constructor or method, reflect to complete as a function call + * - [ ] if the preceding token is a variable, call operators or keywords compatible for completion + * - [X] a command always should be the second token after php_open_tag + * - [X] keywords are never consecutive + * - [X] namespacing completion should work just fine + * - [X] after a new keyword, should always be a class constructor, never a function call or keyword, constant, + * or variable that does not contain a existing class name. + * - [X] on a namespaced constructor the completion must show the classes related, not constants. + * + * @return array + */ + public function classesInput() + { + return array( + // input, must had, must not had + array('T_OPE', array('T_OPEN_TAG'), array()), + array('st', array('stdClass'), array()), + array('stdCla', array('stdClass'), array()), + array('new s', array('stdClass'), array()), + array( + 'new ', + array('stdClass', 'Psy\\Context', 'Psy\\Configuration'), + array('require', 'array_search', 'T_OPEN_TAG', '$foo'), + ), + array('new Psy\\C', array('Context'), array('CASE_LOWER')), + array('\s', array('stdClass'), array()), + array('array_', array('array_search', 'array_map', 'array_merge'), array()), + array('$bar->', array('load'), array()), + array('$b', array('bar'), array()), + array('6 + $b', array('bar'), array()), + array('$f', array('foo'), array()), + array('l', array('ls'), array()), + array('ls ', array(), array('ls')), + array('sho', array('show'), array()), + array('12 + clone $', array('foo'), array()), + // array( + // '$foo ', + // array('+', 'clone'), + // array('$foo', 'DOMDocument', 'array_map') + // ), requires a operator matcher? + array('$', array('foo', 'bar'), array('require', 'array_search', 'T_OPEN_TAG', 'Psy')), + array( + 'Psy\\', + array('Context', 'TabCompletion\\Matcher\\AbstractMatcher'), + array('require', 'array_search'), + ), + array( + 'Psy\Test\TabCompletion\StaticSample::CO', + array('Psy\Test\TabCompletion\StaticSample::CONSTANT_VALUE'), + array(), + ), + array( + 'Psy\Test\TabCompletion\StaticSample::', + array('Psy\Test\TabCompletion\StaticSample::$staticVariable'), + array(), + ), + array( + 'Psy\Test\TabCompletion\StaticSample::', + array('Psy\Test\TabCompletion\StaticSample::staticFunction'), + array(), + ), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/TabCompletion/StaticSample.php b/vendor/psy/psysh/test/Psy/Test/TabCompletion/StaticSample.php new file mode 100644 index 000000000..aea0031c3 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/TabCompletion/StaticSample.php @@ -0,0 +1,27 @@ +getMockBuilder('ReflectionClass') + ->disableOriginalConstructor() + ->getMock(); + + $reflector->expects($this->once()) + ->method('getDocComment') + ->will($this->returnValue($comment)); + + $docblock = new Docblock($reflector); + + $this->assertEquals($body, $docblock->desc); + + foreach ($tags as $tag => $value) { + $this->assertTrue($docblock->hasTag($tag)); + $this->assertEquals($value, $docblock->tag($tag)); + } + } + + public function comments() + { + return array( + array('', '', array()), + array( + '/** + * This is a docblock + * + * @throws \Exception with a description + */', + 'This is a docblock', + array( + 'throws' => array(array('type' => '\Exception', 'desc' => 'with a description')), + ), + ), + array( + '/** + * This is a slightly longer docblock + * + * @param int $foo Is a Foo + * @param string $bar With some sort of description + * @param \ClassName $baz is cool too + * + * @return int At least it isn\'t a string + */', + 'This is a slightly longer docblock', + array( + 'param' => array( + array('type' => 'int', 'desc' => 'Is a Foo', 'var' => '$foo'), + array('type' => 'string', 'desc' => 'With some sort of description', 'var' => '$bar'), + array('type' => '\ClassName', 'desc' => 'is cool too', 'var' => '$baz'), + ), + 'return' => array( + array('type' => 'int', 'desc' => 'At least it isn\'t a string'), + ), + ), + ), + array( + '/** + * This is a docblock! + * + * It spans lines, too! + * + * @tagname plus a description + * + * @return + */', + "This is a docblock!\n\nIt spans lines, too!", + array( + 'tagname' => array('plus a description'), + ), + ), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Util/MirrorTest.php b/vendor/psy/psysh/test/Psy/Test/Util/MirrorTest.php new file mode 100644 index 000000000..7d6a43257 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Util/MirrorTest.php @@ -0,0 +1,80 @@ +assertTrue($refl instanceof \ReflectionFunction); + + $refl = Mirror::get('Psy\Test\Util\MirrorTest'); + $this->assertTrue($refl instanceof \ReflectionClass); + + $refl = Mirror::get($this); + $this->assertTrue($refl instanceof \ReflectionObject); + + $refl = Mirror::get($this, 'FOO'); + $this->assertTrue($refl instanceof ReflectionConstant); + + $refl = Mirror::get($this, 'bar'); + $this->assertTrue($refl instanceof \ReflectionProperty); + + $refl = Mirror::get($this, 'baz'); + $this->assertTrue($refl instanceof \ReflectionProperty); + + $refl = Mirror::get($this, 'aPublicMethod'); + $this->assertTrue($refl instanceof \ReflectionMethod); + + $refl = Mirror::get($this, 'baz', Mirror::STATIC_PROPERTY); + $this->assertTrue($refl instanceof \ReflectionProperty); + } + + /** + * @expectedException \RuntimeException + */ + public function testMirrorThrowsExceptions() + { + Mirror::get($this, 'notAMethod'); + } + + /** + * @expectedException \InvalidArgumentException + * @dataProvider invalidArguments + */ + public function testMirrorThrowsInvalidArgumentExceptions($value) + { + Mirror::get($value); + } + + public function invalidArguments() + { + return array( + array('not_a_function_or_class'), + array(array()), + array(1), + ); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/Util/StrTest.php b/vendor/psy/psysh/test/Psy/Test/Util/StrTest.php new file mode 100644 index 000000000..25602f919 --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/Util/StrTest.php @@ -0,0 +1,31 @@ +assertEquals($expected, Str::unvis($input)); + } + + public function testUnvisProvider() + { + //return require_once(__DIR__.'/../../../fixtures/unvis_fixtures.php'); + return json_decode(file_get_contents(__DIR__ . '/../../../fixtures/unvis_fixtures.json')); + } +} diff --git a/vendor/psy/psysh/test/Psy/Test/VersionUpdater/GitHubCheckerTest.php b/vendor/psy/psysh/test/Psy/Test/VersionUpdater/GitHubCheckerTest.php new file mode 100644 index 000000000..32a7e534f --- /dev/null +++ b/vendor/psy/psysh/test/Psy/Test/VersionUpdater/GitHubCheckerTest.php @@ -0,0 +1,82 @@ +getMockBuilder('Psy\\VersionUpdater\\GitHubChecker') + ->setMethods(array('fetchLatestRelease')) + ->getMock(); + $checker->expects($this->once())->method('fetchLatestRelease')->willReturn($input); + $checker->isLatest(); + } + + /** + * @dataProvider jsonResults + * + * @param $assertion + * @param $input + */ + public function testDataSetResults($assertion, $input) + { + $checker = $this->getMockBuilder('Psy\\VersionUpdater\\GitHubChecker') + ->setMethods(array('fetchLatestRelease')) + ->getMock(); + $checker->expects($this->once())->method('fetchLatestRelease')->willReturn($input); + $this->assertSame($assertion, $checker->isLatest()); + } + + /** + * @return array + */ + public function jsonResults() + { + return array( + array(false, json_decode('{"tag_name":"v9.0.0"}')), + array(true, json_decode('{"tag_name":"v' . Shell::VERSION . '"}')), + array(true, json_decode('{"tag_name":"v0.0.1"}')), + array(true, json_decode('{"tag_name":"v0.4.1-alpha"}')), + array(true, json_decode('{"tag_name":"v0.4.2-beta3"}')), + array(true, json_decode('{"tag_name":"v0.0.1"}')), + array(true, json_decode('{"tag_name":""}')), + ); + } + + /** + * @return array + */ + public function malformedResults() + { + return array( + array(null), + array(false), + array(true), + array(json_decode('{"foo":"bar"}')), + array(json_decode('{}')), + array(json_decode('[]')), + array(array()), + array(json_decode('{"tag_name":false"}')), + array(json_decode('{"tag_name":true"}')), + ); + } +} diff --git a/vendor/psy/psysh/test/fixtures/config.php b/vendor/psy/psysh/test/fixtures/config.php new file mode 100644 index 000000000..31a4ef54d --- /dev/null +++ b/vendor/psy/psysh/test/fixtures/config.php @@ -0,0 +1,18 @@ +setRuntimeDir(sys_get_temp_dir() . '/psysh_test/withconfig/temp'); + +return array( + 'useReadline' => true, + 'usePcntl' => false, + 'errorLoggingLevel' => E_ALL & ~E_NOTICE, +); diff --git a/vendor/psy/psysh/test/fixtures/default/.config/psysh/config.php b/vendor/psy/psysh/test/fixtures/default/.config/psysh/config.php new file mode 100644 index 000000000..b3d9bbc7f --- /dev/null +++ b/vendor/psy/psysh/test/fixtures/default/.config/psysh/config.php @@ -0,0 +1 @@ + false, + 'usePcntl' => true, +); diff --git a/vendor/psy/psysh/test/fixtures/unvis_fixtures.json b/vendor/psy/psysh/test/fixtures/unvis_fixtures.json new file mode 100644 index 000000000..960fb02a1 --- /dev/null +++ b/vendor/psy/psysh/test/fixtures/unvis_fixtures.json @@ -0,0 +1 @@ +[["", ""], ["\\^A", "\u0001"], ["\\^B", "\u0002"], ["\\^C", "\u0003"], ["\\^D", "\u0004"], ["\\^E", "\u0005"], ["\\^F", "\u0006"], ["\\^G", "\u0007"], ["\\^H", "\b"], ["\\^I", "\t"], ["\\^J", "\n"], ["\\^K", "\u000b"], ["\\^L", "\f"], ["\\^M", "\r"], ["\\^N", "\u000e"], ["\\^O", "\u000f"], ["\\^P", "\u0010"], ["\\^Q", "\u0011"], ["\\^R", "\u0012"], ["\\^S", "\u0013"], ["\\^T", "\u0014"], ["\\^U", "\u0015"], ["\\^V", "\u0016"], ["\\^W", "\u0017"], ["\\^X", "\u0018"], ["\\^Y", "\u0019"], ["\\^Z", "\u001a"], ["\\^[", "\u001b"], ["\\^\\", "\u001c"], ["\\^]", "\u001d"], ["\\^^", "\u001e"], ["\\^_", "\u001f"], ["\\040", " "], ["!", "!"], ["\"", "\""], ["#", "#"], ["$", "$"], ["%", "%"], ["&", "&"], ["'", "'"], ["(", "("], [")", ")"], ["*", "*"], ["+", "+"], [",", ","], ["-", "-"], [".", "."], ["/", "/"], ["0", "0"], ["1", "1"], ["2", "2"], ["3", "3"], ["4", "4"], ["5", "5"], ["6", "6"], ["7", "7"], ["8", "8"], ["9", "9"], [":", ":"], [";", ";"], ["<", "<"], ["=", "="], [">", ">"], ["?", "?"], ["@", "@"], ["A", "A"], ["B", "B"], ["C", "C"], ["D", "D"], ["E", "E"], ["F", "F"], ["G", "G"], ["H", "H"], ["I", "I"], ["J", "J"], ["K", "K"], ["L", "L"], ["M", "M"], ["N", "N"], ["O", "O"], ["P", "P"], ["Q", "Q"], ["R", "R"], ["S", "S"], ["T", "T"], ["U", "U"], ["V", "V"], ["W", "W"], ["X", "X"], ["Y", "Y"], ["Z", "Z"], ["[", "["], ["\\\\", "\\"], ["]", "]"], ["^", "^"], ["_", "_"], ["`", "`"], ["a", "a"], ["b", "b"], ["c", "c"], ["d", "d"], ["e", "e"], ["f", "f"], ["g", "g"], ["h", "h"], ["i", "i"], ["j", "j"], ["k", "k"], ["l", "l"], ["m", "m"], ["n", "n"], ["o", "o"], ["p", "p"], ["q", "q"], ["r", "r"], ["s", "s"], ["t", "t"], ["u", "u"], ["v", "v"], ["w", "w"], ["x", "x"], ["y", "y"], ["z", "z"], ["{", "{"], ["|", "|"], ["}", "}"], ["~", "~"], ["\\^?", "\u007f"], ["\\M-B\\M^@", "\u0080"], ["\\M-B\\M^A", "\u0081"], ["\\M-B\\M^B", "\u0082"], ["\\M-B\\M^C", "\u0083"], ["\\M-B\\M^D", "\u0084"], ["\\M-B\\M^E", "\u0085"], ["\\M-B\\M^F", "\u0086"], ["\\M-B\\M^G", "\u0087"], ["\\M-B\\M^H", "\u0088"], ["\\M-B\\M^I", "\u0089"], ["\\M-B\\M^J", "\u008a"], ["\\M-B\\M^K", "\u008b"], ["\\M-B\\M^L", "\u008c"], ["\\M-B\\M^M", "\u008d"], ["\\M-B\\M^N", "\u008e"], ["\\M-B\\M^O", "\u008f"], ["\\M-B\\M^P", "\u0090"], ["\\M-B\\M^Q", "\u0091"], ["\\M-B\\M^R", "\u0092"], ["\\M-B\\M^S", "\u0093"], ["\\M-B\\M^T", "\u0094"], ["\\M-B\\M^U", "\u0095"], ["\\M-B\\M^V", "\u0096"], ["\\M-B\\M^W", "\u0097"], ["\\M-B\\M^X", "\u0098"], ["\\M-B\\M^Y", "\u0099"], ["\\M-B\\M^Z", "\u009a"], ["\\M-B\\M^[", "\u009b"], ["\\M-B\\M^\\", "\u009c"], ["\\M-B\\M^]", "\u009d"], ["\\M-B\\M^^", "\u009e"], ["\\M-B\\M^_", "\u009f"], ["\\M-B\\240", "\u00a0"], ["\\M-B\\M-!", "\u00a1"], ["\\M-B\\M-\"", "\u00a2"], ["\\M-B\\M-#", "\u00a3"], ["\\M-B\\M-$", "\u00a4"], ["\\M-B\\M-%", "\u00a5"], ["\\M-B\\M-&", "\u00a6"], ["\\M-B\\M-'", "\u00a7"], ["\\M-B\\M-(", "\u00a8"], ["\\M-B\\M-)", "\u00a9"], ["\\M-B\\M-*", "\u00aa"], ["\\M-B\\M-+", "\u00ab"], ["\\M-B\\M-,", "\u00ac"], ["\\M-B\\M--", "\u00ad"], ["\\M-B\\M-.", "\u00ae"], ["\\M-B\\M-/", "\u00af"], ["\\M-B\\M-0", "\u00b0"], ["\\M-B\\M-1", "\u00b1"], ["\\M-B\\M-2", "\u00b2"], ["\\M-B\\M-3", "\u00b3"], ["\\M-B\\M-4", "\u00b4"], ["\\M-B\\M-5", "\u00b5"], ["\\M-B\\M-6", "\u00b6"], ["\\M-B\\M-7", "\u00b7"], ["\\M-B\\M-8", "\u00b8"], ["\\M-B\\M-9", "\u00b9"], ["\\M-B\\M-:", "\u00ba"], ["\\M-B\\M-;", "\u00bb"], ["\\M-B\\M-<", "\u00bc"], ["\\M-B\\M-=", "\u00bd"], ["\\M-B\\M->", "\u00be"], ["\\M-B\\M-?", "\u00bf"], ["\\M-C\\M^@", "\u00c0"], ["\\M-C\\M^A", "\u00c1"], ["\\M-C\\M^B", "\u00c2"], ["\\M-C\\M^C", "\u00c3"], ["\\M-C\\M^D", "\u00c4"], ["\\M-C\\M^E", "\u00c5"], ["\\M-C\\M^F", "\u00c6"], ["\\M-C\\M^G", "\u00c7"], ["\\M-C\\M^H", "\u00c8"], ["\\M-C\\M^I", "\u00c9"], ["\\M-C\\M^J", "\u00ca"], ["\\M-C\\M^K", "\u00cb"], ["\\M-C\\M^L", "\u00cc"], ["\\M-C\\M^M", "\u00cd"], ["\\M-C\\M^N", "\u00ce"], ["\\M-C\\M^O", "\u00cf"], ["\\M-C\\M^P", "\u00d0"], ["\\M-C\\M^Q", "\u00d1"], ["\\M-C\\M^R", "\u00d2"], ["\\M-C\\M^S", "\u00d3"], ["\\M-C\\M^T", "\u00d4"], ["\\M-C\\M^U", "\u00d5"], ["\\M-C\\M^V", "\u00d6"], ["\\M-C\\M^W", "\u00d7"], ["\\M-C\\M^X", "\u00d8"], ["\\M-C\\M^Y", "\u00d9"], ["\\M-C\\M^Z", "\u00da"], ["\\M-C\\M^[", "\u00db"], ["\\M-C\\M^\\", "\u00dc"], ["\\M-C\\M^]", "\u00dd"], ["\\M-C\\M^^", "\u00de"], ["\\M-C\\M^_", "\u00df"], ["\\M-C\\240", "\u00e0"], ["\\M-C\\M-!", "\u00e1"], ["\\M-C\\M-\"", "\u00e2"], ["\\M-C\\M-#", "\u00e3"], ["\\M-C\\M-$", "\u00e4"], ["\\M-C\\M-%", "\u00e5"], ["\\M-C\\M-&", "\u00e6"], ["\\M-C\\M-'", "\u00e7"], ["\\M-C\\M-(", "\u00e8"], ["\\M-C\\M-)", "\u00e9"], ["\\M-C\\M-*", "\u00ea"], ["\\M-C\\M-+", "\u00eb"], ["\\M-C\\M-,", "\u00ec"], ["\\M-C\\M--", "\u00ed"], ["\\M-C\\M-.", "\u00ee"], ["\\M-C\\M-/", "\u00ef"], ["\\M-C\\M-0", "\u00f0"], ["\\M-C\\M-1", "\u00f1"], ["\\M-C\\M-2", "\u00f2"], ["\\M-C\\M-3", "\u00f3"], ["\\M-C\\M-4", "\u00f4"], ["\\M-C\\M-5", "\u00f5"], ["\\M-C\\M-6", "\u00f6"], ["\\M-C\\M-7", "\u00f7"], ["\\M-C\\M-8", "\u00f8"], ["\\M-C\\M-9", "\u00f9"], ["\\M-C\\M-:", "\u00fa"], ["\\M-C\\M-;", "\u00fb"], ["\\M-C\\M-<", "\u00fc"], ["\\M-C\\M-=", "\u00fd"], ["\\M-C\\M->", "\u00fe"], ["\\M-C\\M-?", "\u00ff"], ["\\M-D\\M^@", "\u0100"], ["\\M-D\\M^A", "\u0101"], ["\\M-D\\M^B", "\u0102"], ["\\M-D\\M^C", "\u0103"], ["\\M-D\\M^D", "\u0104"], ["\\M-D\\M^E", "\u0105"], ["\\M-D\\M^F", "\u0106"], ["\\M-D\\M^G", "\u0107"], ["\\M-D\\M^H", "\u0108"], ["\\M-D\\M^I", "\u0109"], ["\\M-D\\M^J", "\u010a"], ["\\M-D\\M^K", "\u010b"], ["\\M-D\\M^L", "\u010c"], ["\\M-D\\M^M", "\u010d"], ["\\M-D\\M^N", "\u010e"], ["\\M-D\\M^O", "\u010f"], ["\\M-D\\M^P", "\u0110"], ["\\M-D\\M^Q", "\u0111"], ["\\M-D\\M^R", "\u0112"], ["\\M-D\\M^S", "\u0113"], ["\\M-D\\M^T", "\u0114"], ["\\M-D\\M^U", "\u0115"], ["\\M-D\\M^V", "\u0116"], ["\\M-D\\M^W", "\u0117"], ["\\M-D\\M^X", "\u0118"], ["\\M-D\\M^Y", "\u0119"], ["\\M-D\\M^Z", "\u011a"], ["\\M-D\\M^[", "\u011b"], ["\\M-D\\M^\\", "\u011c"], ["\\M-D\\M^]", "\u011d"], ["\\M-D\\M^^", "\u011e"], ["\\M-D\\M^_", "\u011f"], ["\\M-D\\240", "\u0120"], ["\\M-D\\M-!", "\u0121"], ["\\M-D\\M-\"", "\u0122"], ["\\M-D\\M-#", "\u0123"], ["\\M-D\\M-$", "\u0124"], ["\\M-D\\M-%", "\u0125"], ["\\M-D\\M-&", "\u0126"], ["\\M-D\\M-'", "\u0127"], ["\\M-D\\M-(", "\u0128"], ["\\M-D\\M-)", "\u0129"], ["\\M-D\\M-*", "\u012a"], ["\\M-D\\M-+", "\u012b"], ["\\M-D\\M-,", "\u012c"], ["\\M-D\\M--", "\u012d"], ["\\M-D\\M-.", "\u012e"], ["\\M-D\\M-/", "\u012f"], ["\\M-D\\M-0", "\u0130"], ["\\M-D\\M-1", "\u0131"], ["\\M-D\\M-2", "\u0132"], ["\\M-D\\M-3", "\u0133"], ["\\M-D\\M-4", "\u0134"], ["\\M-D\\M-5", "\u0135"], ["\\M-D\\M-6", "\u0136"], ["\\M-D\\M-7", "\u0137"], ["\\M-D\\M-8", "\u0138"], ["\\M-D\\M-9", "\u0139"], ["\\M-D\\M-:", "\u013a"], ["\\M-D\\M-;", "\u013b"], ["\\M-D\\M-<", "\u013c"], ["\\M-D\\M-=", "\u013d"], ["\\M-D\\M->", "\u013e"], ["\\M-D\\M-?", "\u013f"], ["\\M-E\\M^@", "\u0140"], ["\\M-E\\M^A", "\u0141"], ["\\M-E\\M^B", "\u0142"], ["\\M-E\\M^C", "\u0143"], ["\\M-E\\M^D", "\u0144"], ["\\M-E\\M^E", "\u0145"], ["\\M-E\\M^F", "\u0146"], ["\\M-E\\M^G", "\u0147"], ["\\M-E\\M^H", "\u0148"], ["\\M-E\\M^I", "\u0149"], ["\\M-E\\M^J", "\u014a"], ["\\M-E\\M^K", "\u014b"], ["\\M-E\\M^L", "\u014c"], ["\\M-E\\M^M", "\u014d"], ["\\M-E\\M^N", "\u014e"], ["\\M-E\\M^O", "\u014f"], ["\\M-E\\M^P", "\u0150"], ["\\M-E\\M^Q", "\u0151"], ["\\M-E\\M^R", "\u0152"], ["\\M-E\\M^S", "\u0153"], ["\\M-E\\M^T", "\u0154"], ["\\M-E\\M^U", "\u0155"], ["\\M-E\\M^V", "\u0156"], ["\\M-E\\M^W", "\u0157"], ["\\M-E\\M^X", "\u0158"], ["\\M-E\\M^Y", "\u0159"], ["\\M-E\\M^Z", "\u015a"], ["\\M-E\\M^[", "\u015b"], ["\\M-E\\M^\\", "\u015c"], ["\\M-E\\M^]", "\u015d"], ["\\M-E\\M^^", "\u015e"], ["\\M-E\\M^_", "\u015f"], ["\\M-E\\240", "\u0160"], ["\\M-E\\M-!", "\u0161"], ["\\M-E\\M-\"", "\u0162"], ["\\M-E\\M-#", "\u0163"], ["\\M-E\\M-$", "\u0164"], ["\\M-E\\M-%", "\u0165"], ["\\M-E\\M-&", "\u0166"], ["\\M-E\\M-'", "\u0167"], ["\\M-E\\M-(", "\u0168"], ["\\M-E\\M-)", "\u0169"], ["\\M-E\\M-*", "\u016a"], ["\\M-E\\M-+", "\u016b"], ["\\M-E\\M-,", "\u016c"], ["\\M-E\\M--", "\u016d"], ["\\M-E\\M-.", "\u016e"], ["\\M-E\\M-/", "\u016f"], ["\\M-E\\M-0", "\u0170"], ["\\M-E\\M-1", "\u0171"], ["\\M-E\\M-2", "\u0172"], ["\\M-E\\M-3", "\u0173"], ["\\M-E\\M-4", "\u0174"], ["\\M-E\\M-5", "\u0175"], ["\\M-E\\M-6", "\u0176"], ["\\M-E\\M-7", "\u0177"], ["\\M-E\\M-8", "\u0178"], ["\\M-E\\M-9", "\u0179"], ["\\M-E\\M-:", "\u017a"], ["\\M-E\\M-;", "\u017b"], ["\\M-E\\M-<", "\u017c"], ["\\M-E\\M-=", "\u017d"], ["\\M-E\\M->", "\u017e"], ["\\M-E\\M-?", "\u017f"], ["\\M-F\\M^@", "\u0180"], ["\\M-F\\M^A", "\u0181"], ["\\M-F\\M^B", "\u0182"], ["\\M-F\\M^C", "\u0183"], ["\\M-F\\M^D", "\u0184"], ["\\M-F\\M^E", "\u0185"], ["\\M-F\\M^F", "\u0186"], ["\\M-F\\M^G", "\u0187"], ["\\M-F\\M^H", "\u0188"], ["\\M-F\\M^I", "\u0189"], ["\\M-F\\M^J", "\u018a"], ["\\M-F\\M^K", "\u018b"], ["\\M-F\\M^L", "\u018c"], ["\\M-F\\M^M", "\u018d"], ["\\M-F\\M^N", "\u018e"], ["\\M-F\\M^O", "\u018f"], ["\\M-F\\M^P", "\u0190"], ["\\M-F\\M^Q", "\u0191"], ["\\M-F\\M^R", "\u0192"], ["\\M-F\\M^S", "\u0193"], ["\\M-F\\M^T", "\u0194"], ["\\M-F\\M^U", "\u0195"], ["\\M-F\\M^V", "\u0196"], ["\\M-F\\M^W", "\u0197"], ["\\M-F\\M^X", "\u0198"], ["\\M-F\\M^Y", "\u0199"], ["\\M-F\\M^Z", "\u019a"], ["\\M-F\\M^[", "\u019b"], ["\\M-F\\M^\\", "\u019c"], ["\\M-F\\M^]", "\u019d"], ["\\M-F\\M^^", "\u019e"], ["\\M-F\\M^_", "\u019f"], ["\\M-F\\240", "\u01a0"], ["\\M-F\\M-!", "\u01a1"], ["\\M-F\\M-\"", "\u01a2"], ["\\M-F\\M-#", "\u01a3"], ["\\M-F\\M-$", "\u01a4"], ["\\M-F\\M-%", "\u01a5"], ["\\M-F\\M-&", "\u01a6"], ["\\M-F\\M-'", "\u01a7"], ["\\M-F\\M-(", "\u01a8"], ["\\M-F\\M-)", "\u01a9"], ["\\M-F\\M-*", "\u01aa"], ["\\M-F\\M-+", "\u01ab"], ["\\M-F\\M-,", "\u01ac"], ["\\M-F\\M--", "\u01ad"], ["\\M-F\\M-.", "\u01ae"], ["\\M-F\\M-/", "\u01af"], ["\\M-F\\M-0", "\u01b0"], ["\\M-F\\M-1", "\u01b1"], ["\\M-F\\M-2", "\u01b2"], ["\\M-F\\M-3", "\u01b3"], ["\\M-F\\M-4", "\u01b4"], ["\\M-F\\M-5", "\u01b5"], ["\\M-F\\M-6", "\u01b6"], ["\\M-F\\M-7", "\u01b7"], ["\\M-F\\M-8", "\u01b8"], ["\\M-F\\M-9", "\u01b9"], ["\\M-F\\M-:", "\u01ba"], ["\\M-F\\M-;", "\u01bb"], ["\\M-F\\M-<", "\u01bc"], ["\\M-F\\M-=", "\u01bd"], ["\\M-F\\M->", "\u01be"], ["\\M-F\\M-?", "\u01bf"], ["\\M-G\\M^@", "\u01c0"], ["\\M-G\\M^A", "\u01c1"], ["\\M-G\\M^B", "\u01c2"], ["\\M-G\\M^C", "\u01c3"], ["\\M-G\\M^D", "\u01c4"], ["\\M-G\\M^E", "\u01c5"], ["\\M-G\\M^F", "\u01c6"], ["\\M-G\\M^G", "\u01c7"], ["\\M-G\\M^H", "\u01c8"], ["\\M-G\\M^I", "\u01c9"], ["\\M-G\\M^J", "\u01ca"], ["\\M-G\\M^K", "\u01cb"], ["\\M-G\\M^L", "\u01cc"], ["\\M-G\\M^M", "\u01cd"], ["\\M-G\\M^N", "\u01ce"], ["\\M-G\\M^O", "\u01cf"], ["\\M-G\\M^P", "\u01d0"], ["\\M-G\\M^Q", "\u01d1"], ["\\M-G\\M^R", "\u01d2"], ["\\M-G\\M^S", "\u01d3"], ["\\M-G\\M^T", "\u01d4"], ["\\M-G\\M^U", "\u01d5"], ["\\M-G\\M^V", "\u01d6"], ["\\M-G\\M^W", "\u01d7"], ["\\M-G\\M^X", "\u01d8"], ["\\M-G\\M^Y", "\u01d9"], ["\\M-G\\M^Z", "\u01da"], ["\\M-G\\M^[", "\u01db"], ["\\M-G\\M^\\", "\u01dc"], ["\\M-G\\M^]", "\u01dd"], ["\\M-G\\M^^", "\u01de"], ["\\M-G\\M^_", "\u01df"], ["\\M-G\\240", "\u01e0"], ["\\M-G\\M-!", "\u01e1"], ["\\M-G\\M-\"", "\u01e2"], ["\\M-G\\M-#", "\u01e3"], ["\\M-G\\M-$", "\u01e4"], ["\\M-G\\M-%", "\u01e5"], ["\\M-G\\M-&", "\u01e6"], ["\\M-G\\M-'", "\u01e7"], ["\\M-G\\M-(", "\u01e8"], ["\\M-G\\M-)", "\u01e9"], ["\\M-G\\M-*", "\u01ea"], ["\\M-G\\M-+", "\u01eb"], ["\\M-G\\M-,", "\u01ec"], ["\\M-G\\M--", "\u01ed"], ["\\M-G\\M-.", "\u01ee"], ["\\M-G\\M-/", "\u01ef"], ["\\M-G\\M-0", "\u01f0"], ["\\M-G\\M-1", "\u01f1"], ["\\M-G\\M-2", "\u01f2"], ["\\M-G\\M-3", "\u01f3"], ["\\M-G\\M-4", "\u01f4"], ["\\M-G\\M-5", "\u01f5"], ["\\M-G\\M-6", "\u01f6"], ["\\M-G\\M-7", "\u01f7"], ["\\M-G\\M-8", "\u01f8"], ["\\M-G\\M-9", "\u01f9"], ["\\M-G\\M-:", "\u01fa"], ["\\M-G\\M-;", "\u01fb"], ["\\M-G\\M-<", "\u01fc"], ["\\M-G\\M-=", "\u01fd"], ["\\M-G\\M->", "\u01fe"], ["\\M-G\\M-?", "\u01ff"], ["\\M-H\\M^@", "\u0200"], ["\\M-H\\M^A", "\u0201"], ["\\M-H\\M^B", "\u0202"], ["\\M-H\\M^C", "\u0203"], ["\\M-H\\M^D", "\u0204"], ["\\M-H\\M^E", "\u0205"], ["\\M-H\\M^F", "\u0206"], ["\\M-H\\M^G", "\u0207"], ["\\M-H\\M^H", "\u0208"], ["\\M-H\\M^I", "\u0209"], ["\\M-H\\M^J", "\u020a"], ["\\M-H\\M^K", "\u020b"], ["\\M-H\\M^L", "\u020c"], ["\\M-H\\M^M", "\u020d"], ["\\M-H\\M^N", "\u020e"], ["\\M-H\\M^O", "\u020f"], ["\\M-H\\M^P", "\u0210"], ["\\M-H\\M^Q", "\u0211"], ["\\M-H\\M^R", "\u0212"], ["\\M-H\\M^S", "\u0213"], ["\\M-H\\M^T", "\u0214"], ["\\M-H\\M^U", "\u0215"], ["\\M-H\\M^V", "\u0216"], ["\\M-H\\M^W", "\u0217"], ["\\M-H\\M^X", "\u0218"], ["\\M-H\\M^Y", "\u0219"], ["\\M-H\\M^Z", "\u021a"], ["\\M-H\\M^[", "\u021b"], ["\\M-H\\M^\\", "\u021c"], ["\\M-H\\M^]", "\u021d"], ["\\M-H\\M^^", "\u021e"], ["\\M-H\\M^_", "\u021f"], ["\\M-H\\240", "\u0220"], ["\\M-H\\M-!", "\u0221"], ["\\M-H\\M-\"", "\u0222"], ["\\M-H\\M-#", "\u0223"], ["\\M-H\\M-$", "\u0224"], ["\\M-H\\M-%", "\u0225"], ["\\M-H\\M-&", "\u0226"], ["\\M-H\\M-'", "\u0227"], ["\\M-H\\M-(", "\u0228"], ["\\M-H\\M-)", "\u0229"], ["\\M-H\\M-*", "\u022a"], ["\\M-H\\M-+", "\u022b"], ["\\M-H\\M-,", "\u022c"], ["\\M-H\\M--", "\u022d"], ["\\M-H\\M-.", "\u022e"], ["\\M-H\\M-/", "\u022f"], ["\\M-H\\M-0", "\u0230"], ["\\M-H\\M-1", "\u0231"], ["\\M-H\\M-2", "\u0232"], ["\\M-H\\M-3", "\u0233"], ["\\M-H\\M-4", "\u0234"], ["\\M-H\\M-5", "\u0235"], ["\\M-H\\M-6", "\u0236"], ["\\M-H\\M-7", "\u0237"], ["\\M-H\\M-8", "\u0238"], ["\\M-H\\M-9", "\u0239"], ["\\M-H\\M-:", "\u023a"], ["\\M-H\\M-;", "\u023b"], ["\\M-H\\M-<", "\u023c"], ["\\M-H\\M-=", "\u023d"], ["\\M-H\\M->", "\u023e"], ["\\M-H\\M-?", "\u023f"], ["\\M-I\\M^@", "\u0240"], ["\\M-I\\M^A", "\u0241"], ["\\M-I\\M^B", "\u0242"], ["\\M-I\\M^C", "\u0243"], ["\\M-I\\M^D", "\u0244"], ["\\M-I\\M^E", "\u0245"], ["\\M-I\\M^F", "\u0246"], ["\\M-I\\M^G", "\u0247"], ["\\M-I\\M^H", "\u0248"], ["\\M-I\\M^I", "\u0249"], ["\\M-I\\M^J", "\u024a"], ["\\M-I\\M^K", "\u024b"], ["\\M-I\\M^L", "\u024c"], ["\\M-I\\M^M", "\u024d"], ["\\M-I\\M^N", "\u024e"], ["\\M-I\\M^O", "\u024f"], ["\\M-M\\M-0", "\u0370"], ["\\M-M\\M-1", "\u0371"], ["\\M-M\\M-2", "\u0372"], ["\\M-M\\M-3", "\u0373"], ["\\M-M\\M-4", "\u0374"], ["\\M-M\\M-5", "\u0375"], ["\\M-M\\M-6", "\u0376"], ["\\M-M\\M-7", "\u0377"], ["\\M-M\\M-8", "\u0378"], ["\\M-M\\M-9", "\u0379"], ["\\M-M\\M-:", "\u037a"], ["\\M-M\\M-;", "\u037b"], ["\\M-M\\M-<", "\u037c"], ["\\M-M\\M-=", "\u037d"], ["\\M-M\\M->", "\u037e"], ["\\M-M\\M-?", "\u037f"], ["\\M-N\\M^@", "\u0380"], ["\\M-N\\M^A", "\u0381"], ["\\M-N\\M^B", "\u0382"], ["\\M-N\\M^C", "\u0383"], ["\\M-N\\M^D", "\u0384"], ["\\M-N\\M^E", "\u0385"], ["\\M-N\\M^F", "\u0386"], ["\\M-N\\M^G", "\u0387"], ["\\M-N\\M^H", "\u0388"], ["\\M-N\\M^I", "\u0389"], ["\\M-N\\M^J", "\u038a"], ["\\M-N\\M^K", "\u038b"], ["\\M-N\\M^L", "\u038c"], ["\\M-N\\M^M", "\u038d"], ["\\M-N\\M^N", "\u038e"], ["\\M-N\\M^O", "\u038f"], ["\\M-N\\M^P", "\u0390"], ["\\M-N\\M^Q", "\u0391"], ["\\M-N\\M^R", "\u0392"], ["\\M-N\\M^S", "\u0393"], ["\\M-N\\M^T", "\u0394"], ["\\M-N\\M^U", "\u0395"], ["\\M-N\\M^V", "\u0396"], ["\\M-N\\M^W", "\u0397"], ["\\M-N\\M^X", "\u0398"], ["\\M-N\\M^Y", "\u0399"], ["\\M-N\\M^Z", "\u039a"], ["\\M-N\\M^[", "\u039b"], ["\\M-N\\M^\\", "\u039c"], ["\\M-N\\M^]", "\u039d"], ["\\M-N\\M^^", "\u039e"], ["\\M-N\\M^_", "\u039f"], ["\\M-N\\240", "\u03a0"], ["\\M-N\\M-!", "\u03a1"], ["\\M-N\\M-\"", "\u03a2"], ["\\M-N\\M-#", "\u03a3"], ["\\M-N\\M-$", "\u03a4"], ["\\M-N\\M-%", "\u03a5"], ["\\M-N\\M-&", "\u03a6"], ["\\M-N\\M-'", "\u03a7"], ["\\M-N\\M-(", "\u03a8"], ["\\M-N\\M-)", "\u03a9"], ["\\M-N\\M-*", "\u03aa"], ["\\M-N\\M-+", "\u03ab"], ["\\M-N\\M-,", "\u03ac"], ["\\M-N\\M--", "\u03ad"], ["\\M-N\\M-.", "\u03ae"], ["\\M-N\\M-/", "\u03af"], ["\\M-N\\M-0", "\u03b0"], ["\\M-N\\M-1", "\u03b1"], ["\\M-N\\M-2", "\u03b2"], ["\\M-N\\M-3", "\u03b3"], ["\\M-N\\M-4", "\u03b4"], ["\\M-N\\M-5", "\u03b5"], ["\\M-N\\M-6", "\u03b6"], ["\\M-N\\M-7", "\u03b7"], ["\\M-N\\M-8", "\u03b8"], ["\\M-N\\M-9", "\u03b9"], ["\\M-N\\M-:", "\u03ba"], ["\\M-N\\M-;", "\u03bb"], ["\\M-N\\M-<", "\u03bc"], ["\\M-N\\M-=", "\u03bd"], ["\\M-N\\M->", "\u03be"], ["\\M-N\\M-?", "\u03bf"], ["\\M-O\\M^@", "\u03c0"], ["\\M-O\\M^A", "\u03c1"], ["\\M-O\\M^B", "\u03c2"], ["\\M-O\\M^C", "\u03c3"], ["\\M-O\\M^D", "\u03c4"], ["\\M-O\\M^E", "\u03c5"], ["\\M-O\\M^F", "\u03c6"], ["\\M-O\\M^G", "\u03c7"], ["\\M-O\\M^H", "\u03c8"], ["\\M-O\\M^I", "\u03c9"], ["\\M-O\\M^J", "\u03ca"], ["\\M-O\\M^K", "\u03cb"], ["\\M-O\\M^L", "\u03cc"], ["\\M-O\\M^M", "\u03cd"], ["\\M-O\\M^N", "\u03ce"], ["\\M-O\\M^O", "\u03cf"], ["\\M-O\\M^P", "\u03d0"], ["\\M-O\\M^Q", "\u03d1"], ["\\M-O\\M^R", "\u03d2"], ["\\M-O\\M^S", "\u03d3"], ["\\M-O\\M^T", "\u03d4"], ["\\M-O\\M^U", "\u03d5"], ["\\M-O\\M^V", "\u03d6"], ["\\M-O\\M^W", "\u03d7"], ["\\M-O\\M^X", "\u03d8"], ["\\M-O\\M^Y", "\u03d9"], ["\\M-O\\M^Z", "\u03da"], ["\\M-O\\M^[", "\u03db"], ["\\M-O\\M^\\", "\u03dc"], ["\\M-O\\M^]", "\u03dd"], ["\\M-O\\M^^", "\u03de"], ["\\M-O\\M^_", "\u03df"], ["\\M-O\\240", "\u03e0"], ["\\M-O\\M-!", "\u03e1"], ["\\M-O\\M-\"", "\u03e2"], ["\\M-O\\M-#", "\u03e3"], ["\\M-O\\M-$", "\u03e4"], ["\\M-O\\M-%", "\u03e5"], ["\\M-O\\M-&", "\u03e6"], ["\\M-O\\M-'", "\u03e7"], ["\\M-O\\M-(", "\u03e8"], ["\\M-O\\M-)", "\u03e9"], ["\\M-O\\M-*", "\u03ea"], ["\\M-O\\M-+", "\u03eb"], ["\\M-O\\M-,", "\u03ec"], ["\\M-O\\M--", "\u03ed"], ["\\M-O\\M-.", "\u03ee"], ["\\M-O\\M-/", "\u03ef"], ["\\M-O\\M-0", "\u03f0"], ["\\M-O\\M-1", "\u03f1"], ["\\M-O\\M-2", "\u03f2"], ["\\M-O\\M-3", "\u03f3"], ["\\M-O\\M-4", "\u03f4"], ["\\M-O\\M-5", "\u03f5"], ["\\M-O\\M-6", "\u03f6"], ["\\M-O\\M-7", "\u03f7"], ["\\M-O\\M-8", "\u03f8"], ["\\M-O\\M-9", "\u03f9"], ["\\M-O\\M-:", "\u03fa"], ["\\M-O\\M-;", "\u03fb"], ["\\M-O\\M-<", "\u03fc"], ["\\M-O\\M-=", "\u03fd"], ["\\M-O\\M->", "\u03fe"], ["\\M-O\\M-?", "\u03ff"], ["\\M-P\\M^@", "\u0400"], ["\\M-P\\M^A", "\u0401"], ["\\M-P\\M^B", "\u0402"], ["\\M-P\\M^C", "\u0403"], ["\\M-P\\M^D", "\u0404"], ["\\M-P\\M^E", "\u0405"], ["\\M-P\\M^F", "\u0406"], ["\\M-P\\M^G", "\u0407"], ["\\M-P\\M^H", "\u0408"], ["\\M-P\\M^I", "\u0409"], ["\\M-P\\M^J", "\u040a"], ["\\M-P\\M^K", "\u040b"], ["\\M-P\\M^L", "\u040c"], ["\\M-P\\M^M", "\u040d"], ["\\M-P\\M^N", "\u040e"], ["\\M-P\\M^O", "\u040f"], ["\\M-P\\M^P", "\u0410"], ["\\M-P\\M^Q", "\u0411"], ["\\M-P\\M^R", "\u0412"], ["\\M-P\\M^S", "\u0413"], ["\\M-P\\M^T", "\u0414"], ["\\M-P\\M^U", "\u0415"], ["\\M-P\\M^V", "\u0416"], ["\\M-P\\M^W", "\u0417"], ["\\M-P\\M^X", "\u0418"], ["\\M-P\\M^Y", "\u0419"], ["\\M-P\\M^Z", "\u041a"], ["\\M-P\\M^[", "\u041b"], ["\\M-P\\M^\\", "\u041c"], ["\\M-P\\M^]", "\u041d"], ["\\M-P\\M^^", "\u041e"], ["\\M-P\\M^_", "\u041f"], ["\\M-P\\240", "\u0420"], ["\\M-P\\M-!", "\u0421"], ["\\M-P\\M-\"", "\u0422"], ["\\M-P\\M-#", "\u0423"], ["\\M-P\\M-$", "\u0424"], ["\\M-P\\M-%", "\u0425"], ["\\M-P\\M-&", "\u0426"], ["\\M-P\\M-'", "\u0427"], ["\\M-P\\M-(", "\u0428"], ["\\M-P\\M-)", "\u0429"], ["\\M-P\\M-*", "\u042a"], ["\\M-P\\M-+", "\u042b"], ["\\M-P\\M-,", "\u042c"], ["\\M-P\\M--", "\u042d"], ["\\M-P\\M-.", "\u042e"], ["\\M-P\\M-/", "\u042f"], ["\\M-P\\M-0", "\u0430"], ["\\M-P\\M-1", "\u0431"], ["\\M-P\\M-2", "\u0432"], ["\\M-P\\M-3", "\u0433"], ["\\M-P\\M-4", "\u0434"], ["\\M-P\\M-5", "\u0435"], ["\\M-P\\M-6", "\u0436"], ["\\M-P\\M-7", "\u0437"], ["\\M-P\\M-8", "\u0438"], ["\\M-P\\M-9", "\u0439"], ["\\M-P\\M-:", "\u043a"], ["\\M-P\\M-;", "\u043b"], ["\\M-P\\M-<", "\u043c"], ["\\M-P\\M-=", "\u043d"], ["\\M-P\\M->", "\u043e"], ["\\M-P\\M-?", "\u043f"], ["\\M-Q\\M^@", "\u0440"], ["\\M-Q\\M^A", "\u0441"], ["\\M-Q\\M^B", "\u0442"], ["\\M-Q\\M^C", "\u0443"], ["\\M-Q\\M^D", "\u0444"], ["\\M-Q\\M^E", "\u0445"], ["\\M-Q\\M^F", "\u0446"], ["\\M-Q\\M^G", "\u0447"], ["\\M-Q\\M^H", "\u0448"], ["\\M-Q\\M^I", "\u0449"], ["\\M-Q\\M^J", "\u044a"], ["\\M-Q\\M^K", "\u044b"], ["\\M-Q\\M^L", "\u044c"], ["\\M-Q\\M^M", "\u044d"], ["\\M-Q\\M^N", "\u044e"], ["\\M-Q\\M^O", "\u044f"], ["\\M-Q\\M^P", "\u0450"], ["\\M-Q\\M^Q", "\u0451"], ["\\M-Q\\M^R", "\u0452"], ["\\M-Q\\M^S", "\u0453"], ["\\M-Q\\M^T", "\u0454"], ["\\M-Q\\M^U", "\u0455"], ["\\M-Q\\M^V", "\u0456"], ["\\M-Q\\M^W", "\u0457"], ["\\M-Q\\M^X", "\u0458"], ["\\M-Q\\M^Y", "\u0459"], ["\\M-Q\\M^Z", "\u045a"], ["\\M-Q\\M^[", "\u045b"], ["\\M-Q\\M^\\", "\u045c"], ["\\M-Q\\M^]", "\u045d"], ["\\M-Q\\M^^", "\u045e"], ["\\M-Q\\M^_", "\u045f"], ["\\M-Q\\240", "\u0460"], ["\\M-Q\\M-!", "\u0461"], ["\\M-Q\\M-\"", "\u0462"], ["\\M-Q\\M-#", "\u0463"], ["\\M-Q\\M-$", "\u0464"], ["\\M-Q\\M-%", "\u0465"], ["\\M-Q\\M-&", "\u0466"], ["\\M-Q\\M-'", "\u0467"], ["\\M-Q\\M-(", "\u0468"], ["\\M-Q\\M-)", "\u0469"], ["\\M-Q\\M-*", "\u046a"], ["\\M-Q\\M-+", "\u046b"], ["\\M-Q\\M-,", "\u046c"], ["\\M-Q\\M--", "\u046d"], ["\\M-Q\\M-.", "\u046e"], ["\\M-Q\\M-/", "\u046f"], ["\\M-Q\\M-0", "\u0470"], ["\\M-Q\\M-1", "\u0471"], ["\\M-Q\\M-2", "\u0472"], ["\\M-Q\\M-3", "\u0473"], ["\\M-Q\\M-4", "\u0474"], ["\\M-Q\\M-5", "\u0475"], ["\\M-Q\\M-6", "\u0476"], ["\\M-Q\\M-7", "\u0477"], ["\\M-Q\\M-8", "\u0478"], ["\\M-Q\\M-9", "\u0479"], ["\\M-Q\\M-:", "\u047a"], ["\\M-Q\\M-;", "\u047b"], ["\\M-Q\\M-<", "\u047c"], ["\\M-Q\\M-=", "\u047d"], ["\\M-Q\\M->", "\u047e"], ["\\M-Q\\M-?", "\u047f"], ["\\M-R\\M^@", "\u0480"], ["\\M-R\\M^A", "\u0481"], ["\\M-R\\M^B", "\u0482"], ["\\M-R\\M^C", "\u0483"], ["\\M-R\\M^D", "\u0484"], ["\\M-R\\M^E", "\u0485"], ["\\M-R\\M^F", "\u0486"], ["\\M-R\\M^G", "\u0487"], ["\\M-R\\M^H", "\u0488"], ["\\M-R\\M^I", "\u0489"], ["\\M-R\\M^J", "\u048a"], ["\\M-R\\M^K", "\u048b"], ["\\M-R\\M^L", "\u048c"], ["\\M-R\\M^M", "\u048d"], ["\\M-R\\M^N", "\u048e"], ["\\M-R\\M^O", "\u048f"], ["\\M-R\\M^P", "\u0490"], ["\\M-R\\M^Q", "\u0491"], ["\\M-R\\M^R", "\u0492"], ["\\M-R\\M^S", "\u0493"], ["\\M-R\\M^T", "\u0494"], ["\\M-R\\M^U", "\u0495"], ["\\M-R\\M^V", "\u0496"], ["\\M-R\\M^W", "\u0497"], ["\\M-R\\M^X", "\u0498"], ["\\M-R\\M^Y", "\u0499"], ["\\M-R\\M^Z", "\u049a"], ["\\M-R\\M^[", "\u049b"], ["\\M-R\\M^\\", "\u049c"], ["\\M-R\\M^]", "\u049d"], ["\\M-R\\M^^", "\u049e"], ["\\M-R\\M^_", "\u049f"], ["\\M-R\\240", "\u04a0"], ["\\M-R\\M-!", "\u04a1"], ["\\M-R\\M-\"", "\u04a2"], ["\\M-R\\M-#", "\u04a3"], ["\\M-R\\M-$", "\u04a4"], ["\\M-R\\M-%", "\u04a5"], ["\\M-R\\M-&", "\u04a6"], ["\\M-R\\M-'", "\u04a7"], ["\\M-R\\M-(", "\u04a8"], ["\\M-R\\M-)", "\u04a9"], ["\\M-R\\M-*", "\u04aa"], ["\\M-R\\M-+", "\u04ab"], ["\\M-R\\M-,", "\u04ac"], ["\\M-R\\M--", "\u04ad"], ["\\M-R\\M-.", "\u04ae"], ["\\M-R\\M-/", "\u04af"], ["\\M-R\\M-0", "\u04b0"], ["\\M-R\\M-1", "\u04b1"], ["\\M-R\\M-2", "\u04b2"], ["\\M-R\\M-3", "\u04b3"], ["\\M-R\\M-4", "\u04b4"], ["\\M-R\\M-5", "\u04b5"], ["\\M-R\\M-6", "\u04b6"], ["\\M-R\\M-7", "\u04b7"], ["\\M-R\\M-8", "\u04b8"], ["\\M-R\\M-9", "\u04b9"], ["\\M-R\\M-:", "\u04ba"], ["\\M-R\\M-;", "\u04bb"], ["\\M-R\\M-<", "\u04bc"], ["\\M-R\\M-=", "\u04bd"], ["\\M-R\\M->", "\u04be"], ["\\M-R\\M-?", "\u04bf"], ["\\M-S\\M^@", "\u04c0"], ["\\M-S\\M^A", "\u04c1"], ["\\M-S\\M^B", "\u04c2"], ["\\M-S\\M^C", "\u04c3"], ["\\M-S\\M^D", "\u04c4"], ["\\M-S\\M^E", "\u04c5"], ["\\M-S\\M^F", "\u04c6"], ["\\M-S\\M^G", "\u04c7"], ["\\M-S\\M^H", "\u04c8"], ["\\M-S\\M^I", "\u04c9"], ["\\M-S\\M^J", "\u04ca"], ["\\M-S\\M^K", "\u04cb"], ["\\M-S\\M^L", "\u04cc"], ["\\M-S\\M^M", "\u04cd"], ["\\M-S\\M^N", "\u04ce"], ["\\M-S\\M^O", "\u04cf"], ["\\M-S\\M^P", "\u04d0"], ["\\M-S\\M^Q", "\u04d1"], ["\\M-S\\M^R", "\u04d2"], ["\\M-S\\M^S", "\u04d3"], ["\\M-S\\M^T", "\u04d4"], ["\\M-S\\M^U", "\u04d5"], ["\\M-S\\M^V", "\u04d6"], ["\\M-S\\M^W", "\u04d7"], ["\\M-S\\M^X", "\u04d8"], ["\\M-S\\M^Y", "\u04d9"], ["\\M-S\\M^Z", "\u04da"], ["\\M-S\\M^[", "\u04db"], ["\\M-S\\M^\\", "\u04dc"], ["\\M-S\\M^]", "\u04dd"], ["\\M-S\\M^^", "\u04de"], ["\\M-S\\M^_", "\u04df"], ["\\M-S\\240", "\u04e0"], ["\\M-S\\M-!", "\u04e1"], ["\\M-S\\M-\"", "\u04e2"], ["\\M-S\\M-#", "\u04e3"], ["\\M-S\\M-$", "\u04e4"], ["\\M-S\\M-%", "\u04e5"], ["\\M-S\\M-&", "\u04e6"], ["\\M-S\\M-'", "\u04e7"], ["\\M-S\\M-(", "\u04e8"], ["\\M-S\\M-)", "\u04e9"], ["\\M-S\\M-*", "\u04ea"], ["\\M-S\\M-+", "\u04eb"], ["\\M-S\\M-,", "\u04ec"], ["\\M-S\\M--", "\u04ed"], ["\\M-S\\M-.", "\u04ee"], ["\\M-S\\M-/", "\u04ef"], ["\\M-S\\M-0", "\u04f0"], ["\\M-S\\M-1", "\u04f1"], ["\\M-S\\M-2", "\u04f2"], ["\\M-S\\M-3", "\u04f3"], ["\\M-S\\M-4", "\u04f4"], ["\\M-S\\M-5", "\u04f5"], ["\\M-S\\M-6", "\u04f6"], ["\\M-S\\M-7", "\u04f7"], ["\\M-S\\M-8", "\u04f8"], ["\\M-S\\M-9", "\u04f9"], ["\\M-S\\M-:", "\u04fa"], ["\\M-S\\M-;", "\u04fb"], ["\\M-S\\M-<", "\u04fc"], ["\\M-S\\M-=", "\u04fd"], ["\\M-S\\M->", "\u04fe"], ["\\M-S\\M-?", "\u04ff"], ["\\M-T\\M^@", "\u0500"], ["\\M-T\\M^A", "\u0501"], ["\\M-T\\M^B", "\u0502"], ["\\M-T\\M^C", "\u0503"], ["\\M-T\\M^D", "\u0504"], ["\\M-T\\M^E", "\u0505"], ["\\M-T\\M^F", "\u0506"], ["\\M-T\\M^G", "\u0507"], ["\\M-T\\M^H", "\u0508"], ["\\M-T\\M^I", "\u0509"], ["\\M-T\\M^J", "\u050a"], ["\\M-T\\M^K", "\u050b"], ["\\M-T\\M^L", "\u050c"], ["\\M-T\\M^M", "\u050d"], ["\\M-T\\M^N", "\u050e"], ["\\M-T\\M^O", "\u050f"], ["\\M-T\\M^P", "\u0510"], ["\\M-T\\M^Q", "\u0511"], ["\\M-T\\M^R", "\u0512"], ["\\M-T\\M^S", "\u0513"], ["\\M-T\\M^T", "\u0514"], ["\\M-T\\M^U", "\u0515"], ["\\M-T\\M^V", "\u0516"], ["\\M-T\\M^W", "\u0517"], ["\\M-T\\M^X", "\u0518"], ["\\M-T\\M^Y", "\u0519"], ["\\M-T\\M^Z", "\u051a"], ["\\M-T\\M^[", "\u051b"], ["\\M-T\\M^\\", "\u051c"], ["\\M-T\\M^]", "\u051d"], ["\\M-T\\M^^", "\u051e"], ["\\M-T\\M^_", "\u051f"], ["\\M-T\\240", "\u0520"], ["\\M-T\\M-!", "\u0521"], ["\\M-T\\M-\"", "\u0522"], ["\\M-T\\M-#", "\u0523"], ["\\M-T\\M-$", "\u0524"], ["\\M-T\\M-%", "\u0525"], ["\\M-T\\M-&", "\u0526"], ["\\M-T\\M-'", "\u0527"], ["\\M-T\\M-(", "\u0528"], ["\\M-T\\M-)", "\u0529"], ["\\M-T\\M-*", "\u052a"], ["\\M-T\\M-+", "\u052b"], ["\\M-T\\M-,", "\u052c"], ["\\M-T\\M--", "\u052d"], ["\\M-T\\M-.", "\u052e"], ["\\M-T\\M-/", "\u052f"], ["\\M-V\\M^P", "\u0590"], ["\\M-V\\M^Q", "\u0591"], ["\\M-V\\M^R", "\u0592"], ["\\M-V\\M^S", "\u0593"], ["\\M-V\\M^T", "\u0594"], ["\\M-V\\M^U", "\u0595"], ["\\M-V\\M^V", "\u0596"], ["\\M-V\\M^W", "\u0597"], ["\\M-V\\M^X", "\u0598"], ["\\M-V\\M^Y", "\u0599"], ["\\M-V\\M^Z", "\u059a"], ["\\M-V\\M^[", "\u059b"], ["\\M-V\\M^\\", "\u059c"], ["\\M-V\\M^]", "\u059d"], ["\\M-V\\M^^", "\u059e"], ["\\M-V\\M^_", "\u059f"], ["\\M-V\\240", "\u05a0"], ["\\M-V\\M-!", "\u05a1"], ["\\M-V\\M-\"", "\u05a2"], ["\\M-V\\M-#", "\u05a3"], ["\\M-V\\M-$", "\u05a4"], ["\\M-V\\M-%", "\u05a5"], ["\\M-V\\M-&", "\u05a6"], ["\\M-V\\M-'", "\u05a7"], ["\\M-V\\M-(", "\u05a8"], ["\\M-V\\M-)", "\u05a9"], ["\\M-V\\M-*", "\u05aa"], ["\\M-V\\M-+", "\u05ab"], ["\\M-V\\M-,", "\u05ac"], ["\\M-V\\M--", "\u05ad"], ["\\M-V\\M-.", "\u05ae"], ["\\M-V\\M-/", "\u05af"], ["\\M-V\\M-0", "\u05b0"], ["\\M-V\\M-1", "\u05b1"], ["\\M-V\\M-2", "\u05b2"], ["\\M-V\\M-3", "\u05b3"], ["\\M-V\\M-4", "\u05b4"], ["\\M-V\\M-5", "\u05b5"], ["\\M-V\\M-6", "\u05b6"], ["\\M-V\\M-7", "\u05b7"], ["\\M-V\\M-8", "\u05b8"], ["\\M-V\\M-9", "\u05b9"], ["\\M-V\\M-:", "\u05ba"], ["\\M-V\\M-;", "\u05bb"], ["\\M-V\\M-<", "\u05bc"], ["\\M-V\\M-=", "\u05bd"], ["\\M-V\\M->", "\u05be"], ["\\M-V\\M-?", "\u05bf"], ["\\M-W\\M^@", "\u05c0"], ["\\M-W\\M^A", "\u05c1"], ["\\M-W\\M^B", "\u05c2"], ["\\M-W\\M^C", "\u05c3"], ["\\M-W\\M^D", "\u05c4"], ["\\M-W\\M^E", "\u05c5"], ["\\M-W\\M^F", "\u05c6"], ["\\M-W\\M^G", "\u05c7"], ["\\M-W\\M^H", "\u05c8"], ["\\M-W\\M^I", "\u05c9"], ["\\M-W\\M^J", "\u05ca"], ["\\M-W\\M^K", "\u05cb"], ["\\M-W\\M^L", "\u05cc"], ["\\M-W\\M^M", "\u05cd"], ["\\M-W\\M^N", "\u05ce"], ["\\M-W\\M^O", "\u05cf"], ["\\M-W\\M^P", "\u05d0"], ["\\M-W\\M^Q", "\u05d1"], ["\\M-W\\M^R", "\u05d2"], ["\\M-W\\M^S", "\u05d3"], ["\\M-W\\M^T", "\u05d4"], ["\\M-W\\M^U", "\u05d5"], ["\\M-W\\M^V", "\u05d6"], ["\\M-W\\M^W", "\u05d7"], ["\\M-W\\M^X", "\u05d8"], ["\\M-W\\M^Y", "\u05d9"], ["\\M-W\\M^Z", "\u05da"], ["\\M-W\\M^[", "\u05db"], ["\\M-W\\M^\\", "\u05dc"], ["\\M-W\\M^]", "\u05dd"], ["\\M-W\\M^^", "\u05de"], ["\\M-W\\M^_", "\u05df"], ["\\M-W\\240", "\u05e0"], ["\\M-W\\M-!", "\u05e1"], ["\\M-W\\M-\"", "\u05e2"], ["\\M-W\\M-#", "\u05e3"], ["\\M-W\\M-$", "\u05e4"], ["\\M-W\\M-%", "\u05e5"], ["\\M-W\\M-&", "\u05e6"], ["\\M-W\\M-'", "\u05e7"], ["\\M-W\\M-(", "\u05e8"], ["\\M-W\\M-)", "\u05e9"], ["\\M-W\\M-*", "\u05ea"], ["\\M-W\\M-+", "\u05eb"], ["\\M-W\\M-,", "\u05ec"], ["\\M-W\\M--", "\u05ed"], ["\\M-W\\M-.", "\u05ee"], ["\\M-W\\M-/", "\u05ef"], ["\\M-W\\M-0", "\u05f0"], ["\\M-W\\M-1", "\u05f1"], ["\\M-W\\M-2", "\u05f2"], ["\\M-W\\M-3", "\u05f3"], ["\\M-W\\M-4", "\u05f4"], ["\\M-W\\M-5", "\u05f5"], ["\\M-W\\M-6", "\u05f6"], ["\\M-W\\M-7", "\u05f7"], ["\\M-W\\M-8", "\u05f8"], ["\\M-W\\M-9", "\u05f9"], ["\\M-W\\M-:", "\u05fa"], ["\\M-W\\M-;", "\u05fb"], ["\\M-W\\M-<", "\u05fc"], ["\\M-W\\M-=", "\u05fd"], ["\\M-W\\M->", "\u05fe"], ["\\M-W\\M-?", "\u05ff"], ["\\M-X\\M^@", "\u0600"], ["\\M-X\\M^A", "\u0601"], ["\\M-X\\M^B", "\u0602"], ["\\M-X\\M^C", "\u0603"], ["\\M-X\\M^D", "\u0604"], ["\\M-X\\M^E", "\u0605"], ["\\M-X\\M^F", "\u0606"], ["\\M-X\\M^G", "\u0607"], ["\\M-X\\M^H", "\u0608"], ["\\M-X\\M^I", "\u0609"], ["\\M-X\\M^J", "\u060a"], ["\\M-X\\M^K", "\u060b"], ["\\M-X\\M^L", "\u060c"], ["\\M-X\\M^M", "\u060d"], ["\\M-X\\M^N", "\u060e"], ["\\M-X\\M^O", "\u060f"], ["\\M-X\\M^P", "\u0610"], ["\\M-X\\M^Q", "\u0611"], ["\\M-X\\M^R", "\u0612"], ["\\M-X\\M^S", "\u0613"], ["\\M-X\\M^T", "\u0614"], ["\\M-X\\M^U", "\u0615"], ["\\M-X\\M^V", "\u0616"], ["\\M-X\\M^W", "\u0617"], ["\\M-X\\M^X", "\u0618"], ["\\M-X\\M^Y", "\u0619"], ["\\M-X\\M^Z", "\u061a"], ["\\M-X\\M^[", "\u061b"], ["\\M-X\\M^\\", "\u061c"], ["\\M-X\\M^]", "\u061d"], ["\\M-X\\M^^", "\u061e"], ["\\M-X\\M^_", "\u061f"], ["\\M-X\\240", "\u0620"], ["\\M-X\\M-!", "\u0621"], ["\\M-X\\M-\"", "\u0622"], ["\\M-X\\M-#", "\u0623"], ["\\M-X\\M-$", "\u0624"], ["\\M-X\\M-%", "\u0625"], ["\\M-X\\M-&", "\u0626"], ["\\M-X\\M-'", "\u0627"], ["\\M-X\\M-(", "\u0628"], ["\\M-X\\M-)", "\u0629"], ["\\M-X\\M-*", "\u062a"], ["\\M-X\\M-+", "\u062b"], ["\\M-X\\M-,", "\u062c"], ["\\M-X\\M--", "\u062d"], ["\\M-X\\M-.", "\u062e"], ["\\M-X\\M-/", "\u062f"], ["\\M-X\\M-0", "\u0630"], ["\\M-X\\M-1", "\u0631"], ["\\M-X\\M-2", "\u0632"], ["\\M-X\\M-3", "\u0633"], ["\\M-X\\M-4", "\u0634"], ["\\M-X\\M-5", "\u0635"], ["\\M-X\\M-6", "\u0636"], ["\\M-X\\M-7", "\u0637"], ["\\M-X\\M-8", "\u0638"], ["\\M-X\\M-9", "\u0639"], ["\\M-X\\M-:", "\u063a"], ["\\M-X\\M-;", "\u063b"], ["\\M-X\\M-<", "\u063c"], ["\\M-X\\M-=", "\u063d"], ["\\M-X\\M->", "\u063e"], ["\\M-X\\M-?", "\u063f"], ["\\M-Y\\M^@", "\u0640"], ["\\M-Y\\M^A", "\u0641"], ["\\M-Y\\M^B", "\u0642"], ["\\M-Y\\M^C", "\u0643"], ["\\M-Y\\M^D", "\u0644"], ["\\M-Y\\M^E", "\u0645"], ["\\M-Y\\M^F", "\u0646"], ["\\M-Y\\M^G", "\u0647"], ["\\M-Y\\M^H", "\u0648"], ["\\M-Y\\M^I", "\u0649"], ["\\M-Y\\M^J", "\u064a"], ["\\M-Y\\M^K", "\u064b"], ["\\M-Y\\M^L", "\u064c"], ["\\M-Y\\M^M", "\u064d"], ["\\M-Y\\M^N", "\u064e"], ["\\M-Y\\M^O", "\u064f"], ["\\M-Y\\M^P", "\u0650"], ["\\M-Y\\M^Q", "\u0651"], ["\\M-Y\\M^R", "\u0652"], ["\\M-Y\\M^S", "\u0653"], ["\\M-Y\\M^T", "\u0654"], ["\\M-Y\\M^U", "\u0655"], ["\\M-Y\\M^V", "\u0656"], ["\\M-Y\\M^W", "\u0657"], ["\\M-Y\\M^X", "\u0658"], ["\\M-Y\\M^Y", "\u0659"], ["\\M-Y\\M^Z", "\u065a"], ["\\M-Y\\M^[", "\u065b"], ["\\M-Y\\M^\\", "\u065c"], ["\\M-Y\\M^]", "\u065d"], ["\\M-Y\\M^^", "\u065e"], ["\\M-Y\\M^_", "\u065f"], ["\\M-Y\\240", "\u0660"], ["\\M-Y\\M-!", "\u0661"], ["\\M-Y\\M-\"", "\u0662"], ["\\M-Y\\M-#", "\u0663"], ["\\M-Y\\M-$", "\u0664"], ["\\M-Y\\M-%", "\u0665"], ["\\M-Y\\M-&", "\u0666"], ["\\M-Y\\M-'", "\u0667"], ["\\M-Y\\M-(", "\u0668"], ["\\M-Y\\M-)", "\u0669"], ["\\M-Y\\M-*", "\u066a"], ["\\M-Y\\M-+", "\u066b"], ["\\M-Y\\M-,", "\u066c"], ["\\M-Y\\M--", "\u066d"], ["\\M-Y\\M-.", "\u066e"], ["\\M-Y\\M-/", "\u066f"], ["\\M-Y\\M-0", "\u0670"], ["\\M-Y\\M-1", "\u0671"], ["\\M-Y\\M-2", "\u0672"], ["\\M-Y\\M-3", "\u0673"], ["\\M-Y\\M-4", "\u0674"], ["\\M-Y\\M-5", "\u0675"], ["\\M-Y\\M-6", "\u0676"], ["\\M-Y\\M-7", "\u0677"], ["\\M-Y\\M-8", "\u0678"], ["\\M-Y\\M-9", "\u0679"], ["\\M-Y\\M-:", "\u067a"], ["\\M-Y\\M-;", "\u067b"], ["\\M-Y\\M-<", "\u067c"], ["\\M-Y\\M-=", "\u067d"], ["\\M-Y\\M->", "\u067e"], ["\\M-Y\\M-?", "\u067f"], ["\\M-Z\\M^@", "\u0680"], ["\\M-Z\\M^A", "\u0681"], ["\\M-Z\\M^B", "\u0682"], ["\\M-Z\\M^C", "\u0683"], ["\\M-Z\\M^D", "\u0684"], ["\\M-Z\\M^E", "\u0685"], ["\\M-Z\\M^F", "\u0686"], ["\\M-Z\\M^G", "\u0687"], ["\\M-Z\\M^H", "\u0688"], ["\\M-Z\\M^I", "\u0689"], ["\\M-Z\\M^J", "\u068a"], ["\\M-Z\\M^K", "\u068b"], ["\\M-Z\\M^L", "\u068c"], ["\\M-Z\\M^M", "\u068d"], ["\\M-Z\\M^N", "\u068e"], ["\\M-Z\\M^O", "\u068f"], ["\\M-Z\\M^P", "\u0690"], ["\\M-Z\\M^Q", "\u0691"], ["\\M-Z\\M^R", "\u0692"], ["\\M-Z\\M^S", "\u0693"], ["\\M-Z\\M^T", "\u0694"], ["\\M-Z\\M^U", "\u0695"], ["\\M-Z\\M^V", "\u0696"], ["\\M-Z\\M^W", "\u0697"], ["\\M-Z\\M^X", "\u0698"], ["\\M-Z\\M^Y", "\u0699"], ["\\M-Z\\M^Z", "\u069a"], ["\\M-Z\\M^[", "\u069b"], ["\\M-Z\\M^\\", "\u069c"], ["\\M-Z\\M^]", "\u069d"], ["\\M-Z\\M^^", "\u069e"], ["\\M-Z\\M^_", "\u069f"], ["\\M-Z\\240", "\u06a0"], ["\\M-Z\\M-!", "\u06a1"], ["\\M-Z\\M-\"", "\u06a2"], ["\\M-Z\\M-#", "\u06a3"], ["\\M-Z\\M-$", "\u06a4"], ["\\M-Z\\M-%", "\u06a5"], ["\\M-Z\\M-&", "\u06a6"], ["\\M-Z\\M-'", "\u06a7"], ["\\M-Z\\M-(", "\u06a8"], ["\\M-Z\\M-)", "\u06a9"], ["\\M-Z\\M-*", "\u06aa"], ["\\M-Z\\M-+", "\u06ab"], ["\\M-Z\\M-,", "\u06ac"], ["\\M-Z\\M--", "\u06ad"], ["\\M-Z\\M-.", "\u06ae"], ["\\M-Z\\M-/", "\u06af"], ["\\M-Z\\M-0", "\u06b0"], ["\\M-Z\\M-1", "\u06b1"], ["\\M-Z\\M-2", "\u06b2"], ["\\M-Z\\M-3", "\u06b3"], ["\\M-Z\\M-4", "\u06b4"], ["\\M-Z\\M-5", "\u06b5"], ["\\M-Z\\M-6", "\u06b6"], ["\\M-Z\\M-7", "\u06b7"], ["\\M-Z\\M-8", "\u06b8"], ["\\M-Z\\M-9", "\u06b9"], ["\\M-Z\\M-:", "\u06ba"], ["\\M-Z\\M-;", "\u06bb"], ["\\M-Z\\M-<", "\u06bc"], ["\\M-Z\\M-=", "\u06bd"], ["\\M-Z\\M->", "\u06be"], ["\\M-Z\\M-?", "\u06bf"], ["\\M-[\\M^@", "\u06c0"], ["\\M-[\\M^A", "\u06c1"], ["\\M-[\\M^B", "\u06c2"], ["\\M-[\\M^C", "\u06c3"], ["\\M-[\\M^D", "\u06c4"], ["\\M-[\\M^E", "\u06c5"], ["\\M-[\\M^F", "\u06c6"], ["\\M-[\\M^G", "\u06c7"], ["\\M-[\\M^H", "\u06c8"], ["\\M-[\\M^I", "\u06c9"], ["\\M-[\\M^J", "\u06ca"], ["\\M-[\\M^K", "\u06cb"], ["\\M-[\\M^L", "\u06cc"], ["\\M-[\\M^M", "\u06cd"], ["\\M-[\\M^N", "\u06ce"], ["\\M-[\\M^O", "\u06cf"], ["\\M-[\\M^P", "\u06d0"], ["\\M-[\\M^Q", "\u06d1"], ["\\M-[\\M^R", "\u06d2"], ["\\M-[\\M^S", "\u06d3"], ["\\M-[\\M^T", "\u06d4"], ["\\M-[\\M^U", "\u06d5"], ["\\M-[\\M^V", "\u06d6"], ["\\M-[\\M^W", "\u06d7"], ["\\M-[\\M^X", "\u06d8"], ["\\M-[\\M^Y", "\u06d9"], ["\\M-[\\M^Z", "\u06da"], ["\\M-[\\M^[", "\u06db"], ["\\M-[\\M^\\", "\u06dc"], ["\\M-[\\M^]", "\u06dd"], ["\\M-[\\M^^", "\u06de"], ["\\M-[\\M^_", "\u06df"], ["\\M-[\\240", "\u06e0"], ["\\M-[\\M-!", "\u06e1"], ["\\M-[\\M-\"", "\u06e2"], ["\\M-[\\M-#", "\u06e3"], ["\\M-[\\M-$", "\u06e4"], ["\\M-[\\M-%", "\u06e5"], ["\\M-[\\M-&", "\u06e6"], ["\\M-[\\M-'", "\u06e7"], ["\\M-[\\M-(", "\u06e8"], ["\\M-[\\M-)", "\u06e9"], ["\\M-[\\M-*", "\u06ea"], ["\\M-[\\M-+", "\u06eb"], ["\\M-[\\M-,", "\u06ec"], ["\\M-[\\M--", "\u06ed"], ["\\M-[\\M-.", "\u06ee"], ["\\M-[\\M-/", "\u06ef"], ["\\M-[\\M-0", "\u06f0"], ["\\M-[\\M-1", "\u06f1"], ["\\M-[\\M-2", "\u06f2"], ["\\M-[\\M-3", "\u06f3"], ["\\M-[\\M-4", "\u06f4"], ["\\M-[\\M-5", "\u06f5"], ["\\M-[\\M-6", "\u06f6"], ["\\M-[\\M-7", "\u06f7"], ["\\M-[\\M-8", "\u06f8"], ["\\M-[\\M-9", "\u06f9"], ["\\M-[\\M-:", "\u06fa"], ["\\M-[\\M-;", "\u06fb"], ["\\M-[\\M-<", "\u06fc"], ["\\M-[\\M-=", "\u06fd"], ["\\M-[\\M->", "\u06fe"], ["\\M-[\\M-?", "\u06ff"], ["\\M-b\\M-:\\M^@", "\u2e80"], ["\\M-b\\M-:\\M^A", "\u2e81"], ["\\M-b\\M-:\\M^B", "\u2e82"], ["\\M-b\\M-:\\M^C", "\u2e83"], ["\\M-b\\M-:\\M^D", "\u2e84"], ["\\M-b\\M-:\\M^E", "\u2e85"], ["\\M-b\\M-:\\M^F", "\u2e86"], ["\\M-b\\M-:\\M^G", "\u2e87"], ["\\M-b\\M-:\\M^H", "\u2e88"], ["\\M-b\\M-:\\M^I", "\u2e89"], ["\\M-b\\M-:\\M^J", "\u2e8a"], ["\\M-b\\M-:\\M^K", "\u2e8b"], ["\\M-b\\M-:\\M^L", "\u2e8c"], ["\\M-b\\M-:\\M^M", "\u2e8d"], ["\\M-b\\M-:\\M^N", "\u2e8e"], ["\\M-b\\M-:\\M^O", "\u2e8f"], ["\\M-b\\M-:\\M^P", "\u2e90"], ["\\M-b\\M-:\\M^Q", "\u2e91"], ["\\M-b\\M-:\\M^R", "\u2e92"], ["\\M-b\\M-:\\M^S", "\u2e93"], ["\\M-b\\M-:\\M^T", "\u2e94"], ["\\M-b\\M-:\\M^U", "\u2e95"], ["\\M-b\\M-:\\M^V", "\u2e96"], ["\\M-b\\M-:\\M^W", "\u2e97"], ["\\M-b\\M-:\\M^X", "\u2e98"], ["\\M-b\\M-:\\M^Y", "\u2e99"], ["\\M-b\\M-:\\M^Z", "\u2e9a"], ["\\M-b\\M-:\\M^[", "\u2e9b"], ["\\M-b\\M-:\\M^\\", "\u2e9c"], ["\\M-b\\M-:\\M^]", "\u2e9d"], ["\\M-b\\M-:\\M^^", "\u2e9e"], ["\\M-b\\M-:\\M^_", "\u2e9f"], ["\\M-b\\M-:\\240", "\u2ea0"], ["\\M-b\\M-:\\M-!", "\u2ea1"], ["\\M-b\\M-:\\M-\"", "\u2ea2"], ["\\M-b\\M-:\\M-#", "\u2ea3"], ["\\M-b\\M-:\\M-$", "\u2ea4"], ["\\M-b\\M-:\\M-%", "\u2ea5"], ["\\M-b\\M-:\\M-&", "\u2ea6"], ["\\M-b\\M-:\\M-'", "\u2ea7"], ["\\M-b\\M-:\\M-(", "\u2ea8"], ["\\M-b\\M-:\\M-)", "\u2ea9"], ["\\M-b\\M-:\\M-*", "\u2eaa"], ["\\M-b\\M-:\\M-+", "\u2eab"], ["\\M-b\\M-:\\M-,", "\u2eac"], ["\\M-b\\M-:\\M--", "\u2ead"], ["\\M-b\\M-:\\M-.", "\u2eae"], ["\\M-b\\M-:\\M-/", "\u2eaf"], ["\\M-b\\M-:\\M-0", "\u2eb0"], ["\\M-b\\M-:\\M-1", "\u2eb1"], ["\\M-b\\M-:\\M-2", "\u2eb2"], ["\\M-b\\M-:\\M-3", "\u2eb3"], ["\\M-b\\M-:\\M-4", "\u2eb4"], ["\\M-b\\M-:\\M-5", "\u2eb5"], ["\\M-b\\M-:\\M-6", "\u2eb6"], ["\\M-b\\M-:\\M-7", "\u2eb7"], ["\\M-b\\M-:\\M-8", "\u2eb8"], ["\\M-b\\M-:\\M-9", "\u2eb9"], ["\\M-b\\M-:\\M-:", "\u2eba"], ["\\M-b\\M-:\\M-;", "\u2ebb"], ["\\M-b\\M-:\\M-<", "\u2ebc"], ["\\M-b\\M-:\\M-=", "\u2ebd"], ["\\M-b\\M-:\\M->", "\u2ebe"], ["\\M-b\\M-:\\M-?", "\u2ebf"], ["\\M-b\\M-;\\M^@", "\u2ec0"], ["\\M-b\\M-;\\M^A", "\u2ec1"], ["\\M-b\\M-;\\M^B", "\u2ec2"], ["\\M-b\\M-;\\M^C", "\u2ec3"], ["\\M-b\\M-;\\M^D", "\u2ec4"], ["\\M-b\\M-;\\M^E", "\u2ec5"], ["\\M-b\\M-;\\M^F", "\u2ec6"], ["\\M-b\\M-;\\M^G", "\u2ec7"], ["\\M-b\\M-;\\M^H", "\u2ec8"], ["\\M-b\\M-;\\M^I", "\u2ec9"], ["\\M-b\\M-;\\M^J", "\u2eca"], ["\\M-b\\M-;\\M^K", "\u2ecb"], ["\\M-b\\M-;\\M^L", "\u2ecc"], ["\\M-b\\M-;\\M^M", "\u2ecd"], ["\\M-b\\M-;\\M^N", "\u2ece"], ["\\M-b\\M-;\\M^O", "\u2ecf"], ["\\M-b\\M-;\\M^P", "\u2ed0"], ["\\M-b\\M-;\\M^Q", "\u2ed1"], ["\\M-b\\M-;\\M^R", "\u2ed2"], ["\\M-b\\M-;\\M^S", "\u2ed3"], ["\\M-b\\M-;\\M^T", "\u2ed4"], ["\\M-b\\M-;\\M^U", "\u2ed5"], ["\\M-b\\M-;\\M^V", "\u2ed6"], ["\\M-b\\M-;\\M^W", "\u2ed7"], ["\\M-b\\M-;\\M^X", "\u2ed8"], ["\\M-b\\M-;\\M^Y", "\u2ed9"], ["\\M-b\\M-;\\M^Z", "\u2eda"], ["\\M-b\\M-;\\M^[", "\u2edb"], ["\\M-b\\M-;\\M^\\", "\u2edc"], ["\\M-b\\M-;\\M^]", "\u2edd"], ["\\M-b\\M-;\\M^^", "\u2ede"], ["\\M-b\\M-;\\M^_", "\u2edf"], ["\\M-b\\M-;\\240", "\u2ee0"], ["\\M-b\\M-;\\M-!", "\u2ee1"], ["\\M-b\\M-;\\M-\"", "\u2ee2"], ["\\M-b\\M-;\\M-#", "\u2ee3"], ["\\M-b\\M-;\\M-$", "\u2ee4"], ["\\M-b\\M-;\\M-%", "\u2ee5"], ["\\M-b\\M-;\\M-&", "\u2ee6"], ["\\M-b\\M-;\\M-'", "\u2ee7"], ["\\M-b\\M-;\\M-(", "\u2ee8"], ["\\M-b\\M-;\\M-)", "\u2ee9"], ["\\M-b\\M-;\\M-*", "\u2eea"], ["\\M-b\\M-;\\M-+", "\u2eeb"], ["\\M-b\\M-;\\M-,", "\u2eec"], ["\\M-b\\M-;\\M--", "\u2eed"], ["\\M-b\\M-;\\M-.", "\u2eee"], ["\\M-b\\M-;\\M-/", "\u2eef"], ["\\M-b\\M-;\\M-0", "\u2ef0"], ["\\M-b\\M-;\\M-1", "\u2ef1"], ["\\M-b\\M-;\\M-2", "\u2ef2"], ["\\M-b\\M-;\\M-3", "\u2ef3"], ["\\M-b\\M-;\\M-4", "\u2ef4"], ["\\M-b\\M-;\\M-5", "\u2ef5"], ["\\M-b\\M-;\\M-6", "\u2ef6"], ["\\M-b\\M-;\\M-7", "\u2ef7"], ["\\M-b\\M-;\\M-8", "\u2ef8"], ["\\M-b\\M-;\\M-9", "\u2ef9"], ["\\M-b\\M-;\\M-:", "\u2efa"], ["\\M-b\\M-;\\M-;", "\u2efb"], ["\\M-b\\M-;\\M-<", "\u2efc"], ["\\M-b\\M-;\\M-=", "\u2efd"], ["\\M-b\\M-;\\M->", "\u2efe"], ["\\M-b\\M-;\\M-?", "\u2eff"], ["\\M-c\\M^A\\M^@", "\u3040"], ["\\M-c\\M^A\\M^A", "\u3041"], ["\\M-c\\M^A\\M^B", "\u3042"], ["\\M-c\\M^A\\M^C", "\u3043"], ["\\M-c\\M^A\\M^D", "\u3044"], ["\\M-c\\M^A\\M^E", "\u3045"], ["\\M-c\\M^A\\M^F", "\u3046"], ["\\M-c\\M^A\\M^G", "\u3047"], ["\\M-c\\M^A\\M^H", "\u3048"], ["\\M-c\\M^A\\M^I", "\u3049"], ["\\M-c\\M^A\\M^J", "\u304a"], ["\\M-c\\M^A\\M^K", "\u304b"], ["\\M-c\\M^A\\M^L", "\u304c"], ["\\M-c\\M^A\\M^M", "\u304d"], ["\\M-c\\M^A\\M^N", "\u304e"], ["\\M-c\\M^A\\M^O", "\u304f"], ["\\M-c\\M^A\\M^P", "\u3050"], ["\\M-c\\M^A\\M^Q", "\u3051"], ["\\M-c\\M^A\\M^R", "\u3052"], ["\\M-c\\M^A\\M^S", "\u3053"], ["\\M-c\\M^A\\M^T", "\u3054"], ["\\M-c\\M^A\\M^U", "\u3055"], ["\\M-c\\M^A\\M^V", "\u3056"], ["\\M-c\\M^A\\M^W", "\u3057"], ["\\M-c\\M^A\\M^X", "\u3058"], ["\\M-c\\M^A\\M^Y", "\u3059"], ["\\M-c\\M^A\\M^Z", "\u305a"], ["\\M-c\\M^A\\M^[", "\u305b"], ["\\M-c\\M^A\\M^\\", "\u305c"], ["\\M-c\\M^A\\M^]", "\u305d"], ["\\M-c\\M^A\\M^^", "\u305e"], ["\\M-c\\M^A\\M^_", "\u305f"], ["\\M-c\\M^A\\240", "\u3060"], ["\\M-c\\M^A\\M-!", "\u3061"], ["\\M-c\\M^A\\M-\"", "\u3062"], ["\\M-c\\M^A\\M-#", "\u3063"], ["\\M-c\\M^A\\M-$", "\u3064"], ["\\M-c\\M^A\\M-%", "\u3065"], ["\\M-c\\M^A\\M-&", "\u3066"], ["\\M-c\\M^A\\M-'", "\u3067"], ["\\M-c\\M^A\\M-(", "\u3068"], ["\\M-c\\M^A\\M-)", "\u3069"], ["\\M-c\\M^A\\M-*", "\u306a"], ["\\M-c\\M^A\\M-+", "\u306b"], ["\\M-c\\M^A\\M-,", "\u306c"], ["\\M-c\\M^A\\M--", "\u306d"], ["\\M-c\\M^A\\M-.", "\u306e"], ["\\M-c\\M^A\\M-/", "\u306f"], ["\\M-c\\M^A\\M-0", "\u3070"], ["\\M-c\\M^A\\M-1", "\u3071"], ["\\M-c\\M^A\\M-2", "\u3072"], ["\\M-c\\M^A\\M-3", "\u3073"], ["\\M-c\\M^A\\M-4", "\u3074"], ["\\M-c\\M^A\\M-5", "\u3075"], ["\\M-c\\M^A\\M-6", "\u3076"], ["\\M-c\\M^A\\M-7", "\u3077"], ["\\M-c\\M^A\\M-8", "\u3078"], ["\\M-c\\M^A\\M-9", "\u3079"], ["\\M-c\\M^A\\M-:", "\u307a"], ["\\M-c\\M^A\\M-;", "\u307b"], ["\\M-c\\M^A\\M-<", "\u307c"], ["\\M-c\\M^A\\M-=", "\u307d"], ["\\M-c\\M^A\\M->", "\u307e"], ["\\M-c\\M^A\\M-?", "\u307f"], ["\\M-c\\M^B\\M^@", "\u3080"], ["\\M-c\\M^B\\M^A", "\u3081"], ["\\M-c\\M^B\\M^B", "\u3082"], ["\\M-c\\M^B\\M^C", "\u3083"], ["\\M-c\\M^B\\M^D", "\u3084"], ["\\M-c\\M^B\\M^E", "\u3085"], ["\\M-c\\M^B\\M^F", "\u3086"], ["\\M-c\\M^B\\M^G", "\u3087"], ["\\M-c\\M^B\\M^H", "\u3088"], ["\\M-c\\M^B\\M^I", "\u3089"], ["\\M-c\\M^B\\M^J", "\u308a"], ["\\M-c\\M^B\\M^K", "\u308b"], ["\\M-c\\M^B\\M^L", "\u308c"], ["\\M-c\\M^B\\M^M", "\u308d"], ["\\M-c\\M^B\\M^N", "\u308e"], ["\\M-c\\M^B\\M^O", "\u308f"], ["\\M-c\\M^B\\M^P", "\u3090"], ["\\M-c\\M^B\\M^Q", "\u3091"], ["\\M-c\\M^B\\M^R", "\u3092"], ["\\M-c\\M^B\\M^S", "\u3093"], ["\\M-c\\M^B\\M^T", "\u3094"], ["\\M-c\\M^B\\M^U", "\u3095"], ["\\M-c\\M^B\\M^V", "\u3096"], ["\\M-c\\M^B\\M^W", "\u3097"], ["\\M-c\\M^B\\M^X", "\u3098"], ["\\M-c\\M^B\\M^Y", "\u3099"], ["\\M-c\\M^B\\M^Z", "\u309a"], ["\\M-c\\M^B\\M^[", "\u309b"], ["\\M-c\\M^B\\M^\\", "\u309c"], ["\\M-c\\M^B\\M^]", "\u309d"], ["\\M-c\\M^B\\M^^", "\u309e"], ["\\M-c\\M^B\\M^_", "\u309f"], ["\\M-c\\M^B\\240", "\u30a0"], ["\\M-c\\M^B\\M-!", "\u30a1"], ["\\M-c\\M^B\\M-\"", "\u30a2"], ["\\M-c\\M^B\\M-#", "\u30a3"], ["\\M-c\\M^B\\M-$", "\u30a4"], ["\\M-c\\M^B\\M-%", "\u30a5"], ["\\M-c\\M^B\\M-&", "\u30a6"], ["\\M-c\\M^B\\M-'", "\u30a7"], ["\\M-c\\M^B\\M-(", "\u30a8"], ["\\M-c\\M^B\\M-)", "\u30a9"], ["\\M-c\\M^B\\M-*", "\u30aa"], ["\\M-c\\M^B\\M-+", "\u30ab"], ["\\M-c\\M^B\\M-,", "\u30ac"], ["\\M-c\\M^B\\M--", "\u30ad"], ["\\M-c\\M^B\\M-.", "\u30ae"], ["\\M-c\\M^B\\M-/", "\u30af"], ["\\M-c\\M^B\\M-0", "\u30b0"], ["\\M-c\\M^B\\M-1", "\u30b1"], ["\\M-c\\M^B\\M-2", "\u30b2"], ["\\M-c\\M^B\\M-3", "\u30b3"], ["\\M-c\\M^B\\M-4", "\u30b4"], ["\\M-c\\M^B\\M-5", "\u30b5"], ["\\M-c\\M^B\\M-6", "\u30b6"], ["\\M-c\\M^B\\M-7", "\u30b7"], ["\\M-c\\M^B\\M-8", "\u30b8"], ["\\M-c\\M^B\\M-9", "\u30b9"], ["\\M-c\\M^B\\M-:", "\u30ba"], ["\\M-c\\M^B\\M-;", "\u30bb"], ["\\M-c\\M^B\\M-<", "\u30bc"], ["\\M-c\\M^B\\M-=", "\u30bd"], ["\\M-c\\M^B\\M->", "\u30be"], ["\\M-c\\M^B\\M-?", "\u30bf"], ["\\M-c\\M^C\\M^@", "\u30c0"], ["\\M-c\\M^C\\M^A", "\u30c1"], ["\\M-c\\M^C\\M^B", "\u30c2"], ["\\M-c\\M^C\\M^C", "\u30c3"], ["\\M-c\\M^C\\M^D", "\u30c4"], ["\\M-c\\M^C\\M^E", "\u30c5"], ["\\M-c\\M^C\\M^F", "\u30c6"], ["\\M-c\\M^C\\M^G", "\u30c7"], ["\\M-c\\M^C\\M^H", "\u30c8"], ["\\M-c\\M^C\\M^I", "\u30c9"], ["\\M-c\\M^C\\M^J", "\u30ca"], ["\\M-c\\M^C\\M^K", "\u30cb"], ["\\M-c\\M^C\\M^L", "\u30cc"], ["\\M-c\\M^C\\M^M", "\u30cd"], ["\\M-c\\M^C\\M^N", "\u30ce"], ["\\M-c\\M^C\\M^O", "\u30cf"], ["\\M-c\\M^C\\M^P", "\u30d0"], ["\\M-c\\M^C\\M^Q", "\u30d1"], ["\\M-c\\M^C\\M^R", "\u30d2"], ["\\M-c\\M^C\\M^S", "\u30d3"], ["\\M-c\\M^C\\M^T", "\u30d4"], ["\\M-c\\M^C\\M^U", "\u30d5"], ["\\M-c\\M^C\\M^V", "\u30d6"], ["\\M-c\\M^C\\M^W", "\u30d7"], ["\\M-c\\M^C\\M^X", "\u30d8"], ["\\M-c\\M^C\\M^Y", "\u30d9"], ["\\M-c\\M^C\\M^Z", "\u30da"], ["\\M-c\\M^C\\M^[", "\u30db"], ["\\M-c\\M^C\\M^\\", "\u30dc"], ["\\M-c\\M^C\\M^]", "\u30dd"], ["\\M-c\\M^C\\M^^", "\u30de"], ["\\M-c\\M^C\\M^_", "\u30df"], ["\\M-c\\M^C\\240", "\u30e0"], ["\\M-c\\M^C\\M-!", "\u30e1"], ["\\M-c\\M^C\\M-\"", "\u30e2"], ["\\M-c\\M^C\\M-#", "\u30e3"], ["\\M-c\\M^C\\M-$", "\u30e4"], ["\\M-c\\M^C\\M-%", "\u30e5"], ["\\M-c\\M^C\\M-&", "\u30e6"], ["\\M-c\\M^C\\M-'", "\u30e7"], ["\\M-c\\M^C\\M-(", "\u30e8"], ["\\M-c\\M^C\\M-)", "\u30e9"], ["\\M-c\\M^C\\M-*", "\u30ea"], ["\\M-c\\M^C\\M-+", "\u30eb"], ["\\M-c\\M^C\\M-,", "\u30ec"], ["\\M-c\\M^C\\M--", "\u30ed"], ["\\M-c\\M^C\\M-.", "\u30ee"], ["\\M-c\\M^C\\M-/", "\u30ef"], ["\\M-c\\M^C\\M-0", "\u30f0"], ["\\M-c\\M^C\\M-1", "\u30f1"], ["\\M-c\\M^C\\M-2", "\u30f2"], ["\\M-c\\M^C\\M-3", "\u30f3"], ["\\M-c\\M^C\\M-4", "\u30f4"], ["\\M-c\\M^C\\M-5", "\u30f5"], ["\\M-c\\M^C\\M-6", "\u30f6"], ["\\M-c\\M^C\\M-7", "\u30f7"], ["\\M-c\\M^C\\M-8", "\u30f8"], ["\\M-c\\M^C\\M-9", "\u30f9"], ["\\M-c\\M^C\\M-:", "\u30fa"], ["\\M-c\\M^C\\M-;", "\u30fb"], ["\\M-c\\M^C\\M-<", "\u30fc"], ["\\M-c\\M^C\\M-=", "\u30fd"], ["\\M-c\\M^C\\M->", "\u30fe"], ["\\M-c\\M^C\\M-?", "\u30ff"], ["foo\\040bar", "foo bar"], ["foo\\^Jbar", "foo\nbar"], ["$bar\\040=\\040'baz';", "$bar = 'baz';"], ["$foo\\040=\\040\"\\\\x20\\\\\\\\x20\\\\\\\\\\\\x20\\\\\\\\\\\\\\\\x20\"", "$foo = \"\\x20\\\\x20\\\\\\x20\\\\\\\\x20\""], ["$foo\\040=\\040function($bar)\\040use($baz)\\040{\\^J\\^Ireturn\\040$baz->getFoo()\\^J};", "$foo = function($bar) use($baz) {\n\treturn $baz->getFoo()\n};"], ["", ""]] \ No newline at end of file diff --git a/vendor/psy/psysh/test/tools/gen_unvis_fixtures.py b/vendor/psy/psysh/test/tools/gen_unvis_fixtures.py new file mode 100755 index 000000000..e02a74145 --- /dev/null +++ b/vendor/psy/psysh/test/tools/gen_unvis_fixtures.py @@ -0,0 +1,94 @@ +#! /usr/bin/env python3 +import sys +from os.path import abspath, expanduser, dirname, join +from itertools import chain +import json +import argparse + +from vis import vis, unvis, VIS_WHITE + + +__dir__ = dirname(abspath(__file__)) + +OUTPUT_FILE = join(__dir__, '..', 'fixtures', 'unvis_fixtures.json') + +# Add custom fixtures here +CUSTOM_FIXTURES = [ + # test long multibyte string + ''.join(chr(cp) for cp in range(1024)), + 'foo bar', + 'foo\nbar', + "$bar = 'baz';", + r'$foo = "\x20\\x20\\\x20\\\\x20"', + '$foo = function($bar) use($baz) {\n\treturn $baz->getFoo()\n};' +] + +RANGES = { + # All valid codepoints in the BMP + 'bmp': chain(range(0x0000, 0xD800), range(0xE000, 0xFFFF)), + # Smaller set of pertinent? codepoints inside BMP + # see: http://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane + 'small': chain( + # latin blocks + range(0x0000, 0x0250), + # Greek, Cyrillic + range(0x0370, 0x0530), + # Hebrew, Arabic + range(0x590, 0x0700), + # CJK radicals + range(0x2E80, 0x2F00), + # Hiragana, Katakana + range(0x3040, 0x3100) + ) +} + + +if __name__ == '__main__': + + argp = argparse.ArgumentParser( + description='Generates test data for Psy\\Test\\Util\\StrTest') + argp.add_argument('-f', '--format-output', action='store_true', + help='Indent JSON output to ease debugging') + argp.add_argument('-a', '--all', action='store_true', + help="""Generates test data for all codepoints of the BMP. + (same as --range=bmp). WARNING: You will need quite + a lot of RAM to run the testsuite ! + """) + argp.add_argument('-r', '--range', + help="""Choose the range of codepoints used to generate + test data.""", + choices=list(RANGES.keys()), + default='small') + argp.add_argument('-o', '--output-file', + help="""Write test data to OUTPUT_FILE + (defaults to PSYSH_DIR/test/fixtures)""") + args = argp.parse_args() + + cp_range = RANGES['bmp'] if args.all else RANGES[args.range] + indent = 2 if args.format_output else None + if args.output_file: + OUTPUT_FILE = abspath(expanduser(args.output_file)) + + fixtures = [] + + # use SMALL_RANGE by default, it should be enough. + # use BMP_RANGE for a more complete smoke test + for codepoint in cp_range: + char = chr(codepoint) + encoded = vis(char, VIS_WHITE) + decoded = unvis(encoded) + fixtures.append((encoded, decoded)) + + # Add our own custom fixtures at the end, + # since they would fail anyway if one of the previous did. + for fixture in CUSTOM_FIXTURES: + encoded = vis(fixture, VIS_WHITE) + decoded = unvis(encoded) + fixtures.append((encoded, decoded)) + + with open(OUTPUT_FILE, 'w') as fp: + # dump as json to avoid backslashin and quotin nightmare + # between php and python + json.dump(fixtures, fp, indent=indent) + + sys.exit(0) diff --git a/vendor/psy/psysh/test/tools/vis.py b/vendor/psy/psysh/test/tools/vis.py new file mode 100755 index 000000000..4e45c4c93 --- /dev/null +++ b/vendor/psy/psysh/test/tools/vis.py @@ -0,0 +1,126 @@ +""" +vis.py +====== + +Ctypes based module to access libbsd's strvis & strunvis functions. + +The `vis` function is the equivalent of strvis. +The `unvis` function is the equivalent of strunvis. +All functions accept unicode string as input and return a unicode string. + +Constants: +---------- + +* to select alternate encoding format + `VIS_OCTAL`: use octal \ddd format + `VIS_CSTYLE`: use \[nrft0..] where appropiate + +* to alter set of characters encoded + (default is to encode all non-graphic except space, tab, and newline). + `VIS_SP`: also encode space + `VIS_TAB`: also encode tab + `VIS_NL`: also encode newline + `VIS_WHITE`: same as (VIS_SP | VIS_TAB | VIS_NL) + `VIS_SAFE`: only encode "unsafe" characters + +* other + `VIS_NOSLASH`: inhibit printing '\' + `VIS_HTTP1808`: http-style escape % hex hex + `VIS_HTTPSTYLE`: http-style escape % hex hex + `VIS_MIMESTYLE`: mime-style escape = HEX HEX + `VIS_HTTP1866`: http-style &#num; or &string; + `VIS_NOESCAPE`: don't decode `\' + `VIS_GLOB`: encode glob(3) magic characters + +:Authors: + - ju1ius (http://github.com/ju1ius) +:Version: 1 +:Date: 2014-01-05 +""" +from ctypes import CDLL, c_char_p, c_int +from ctypes.util import find_library + + +__all__ = [ + 'vis', 'unvis', + 'VIS_OCTAL', 'VIS_CSTYLE', + 'VIS_SP', 'VIS_TAB', 'VIS_NL', 'VIS_WHITE', 'VIS_SAFE', + 'VIS_NOSLASH', 'VIS_HTTP1808', 'VIS_HTTPSTYLE', 'VIS_MIMESTYLE', + 'VIS_HTTP1866', 'VIS_NOESCAPE', 'VIS_GLOB' +] + + +############################################################# +# Constants from bsd/vis.h +############################################################# + +#to select alternate encoding format +VIS_OCTAL = 0x0001 +VIS_CSTYLE = 0x0002 +# to alter set of characters encoded +# (default is to encode all non-graphic except space, tab, and newline). +VIS_SP = 0x0004 +VIS_TAB = 0x0008 +VIS_NL = 0x0010 +VIS_WHITE = VIS_SP | VIS_TAB | VIS_NL +VIS_SAFE = 0x0020 +# other +VIS_NOSLASH = 0x0040 +VIS_HTTP1808 = 0x0080 +VIS_HTTPSTYLE = 0x0080 +VIS_MIMESTYLE = 0x0100 +VIS_HTTP1866 = 0x0200 +VIS_NOESCAPE = 0x0400 +VIS_GLOB = 0x1000 + +############################################################# +# Import libbsd/vis functions +############################################################# + +_libbsd = CDLL(find_library('bsd')) + +_strvis = _libbsd.strvis +_strvis.argtypes = [c_char_p, c_char_p, c_int] +_strvis.restype = c_int + +_strunvis = _libbsd.strunvis +_strvis.argtypes = [c_char_p, c_char_p] +_strvis.restype = c_int + + +def vis(src, flags=VIS_WHITE): + """ + Encodes the string `src` into libbsd's vis encoding. + `flags` must be one of the VIS_* constants + + C definition: + int strvis(char *dst, char *src, int flags); + """ + src = bytes(src, 'utf-8') + dst_p = c_char_p(bytes(len(src) * 4)) + src_p = c_char_p(src) + flags = c_int(flags) + + bytes_written = _strvis(dst_p, src_p, flags) + if -1 == bytes_written: + raise RuntimeError('vis failed to encode string "{}"'.format(src)) + + return dst_p.value.decode('utf-8') + + +def unvis(src): + """ + Decodes a string encoded by vis. + + C definition: + int strunvis(char *dst, char *src); + """ + src = bytes(src, 'utf-8') + dst_p = c_char_p(bytes(len(src))) + src_p = c_char_p(src) + + bytes_written = _strunvis(dst_p, src_p) + if -1 == bytes_written: + raise RuntimeError('unvis failed to decode string "{}"'.format(src)) + + return dst_p.value.decode('utf-8') diff --git a/vendor/sebastian/diff/.gitignore b/vendor/sebastian/diff/.gitignore new file mode 100644 index 000000000..36a9658a6 --- /dev/null +++ b/vendor/sebastian/diff/.gitignore @@ -0,0 +1,4 @@ +/.idea +/composer.lock +/vendor +/.php_cs.cache \ No newline at end of file diff --git a/vendor/sebastian/diff/.php_cs b/vendor/sebastian/diff/.php_cs new file mode 100644 index 000000000..ef46beadd --- /dev/null +++ b/vendor/sebastian/diff/.php_cs @@ -0,0 +1,79 @@ + + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +EOF; + +return PhpCsFixer\Config::create() + ->setRiskyAllowed(true) + ->setRules( + [ + 'array_syntax' => ['syntax' => 'long'], + 'binary_operator_spaces' => [ + 'align_double_arrow' => true, + 'align_equals' => true + ], + 'blank_line_after_namespace' => true, + 'blank_line_before_return' => true, + 'braces' => true, + 'cast_spaces' => true, + 'concat_space' => ['spacing' => 'one'], + 'elseif' => true, + 'encoding' => true, + 'full_opening_tag' => true, + 'function_declaration' => true, + 'header_comment' => ['header' => $header, 'separate' => 'none'], + 'indentation_type' => true, + 'line_ending' => true, + 'lowercase_constants' => true, + 'lowercase_keywords' => true, + 'method_argument_space' => true, + 'native_function_invocation' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_closing_tag' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_consecutive_blank_lines' => true, + 'no_leading_namespace_whitespace' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_trailing_whitespace' => true, + 'no_unused_imports' => true, + 'no_whitespace_in_blank_line' => true, + 'phpdoc_align' => true, + 'phpdoc_indent' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_to_comment' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'phpdoc_var_without_name' => true, + 'self_accessor' => true, + 'simplified_null_return' => true, + 'single_blank_line_at_eof' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'single_quote' => true, + 'ternary_operator_spaces' => true, + 'trim_array_spaces' => true, + 'visibility_required' => true, + ] + ) + ->setFinder( + PhpCsFixer\Finder::create() + ->files() + ->in(__DIR__ . '/src') + ->in(__DIR__ . '/tests') + ->name('*.php') + ); diff --git a/vendor/sebastian/diff/.travis.yml b/vendor/sebastian/diff/.travis.yml new file mode 100644 index 000000000..fa69ad1c3 --- /dev/null +++ b/vendor/sebastian/diff/.travis.yml @@ -0,0 +1,31 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - 7.0snapshot + - 7.1 + - 7.1snapshot + - master + +sudo: false + +before_install: + - composer self-update + - composer clear-cache + +install: + - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable + +script: + - ./vendor/bin/phpunit --coverage-clover=coverage.xml + +after_success: + - bash <(curl -s https://codecov.io/bash) + +notifications: + email: false + diff --git a/vendor/sebastian/diff/LICENSE b/vendor/sebastian/diff/LICENSE index 0941c065e..e1ddf136a 100644 --- a/vendor/sebastian/diff/LICENSE +++ b/vendor/sebastian/diff/LICENSE @@ -1,6 +1,6 @@ -Diff +sebastian/diff -Copyright (c) 2002-2015, Sebastian Bergmann . +Copyright (c) 2002-2017, Sebastian Bergmann . All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/vendor/sebastian/diff/README.md b/vendor/sebastian/diff/README.md new file mode 100644 index 000000000..956038b45 --- /dev/null +++ b/vendor/sebastian/diff/README.md @@ -0,0 +1,126 @@ +# sebastian/diff + +Diff implementation for PHP, factored out of PHPUnit into a stand-alone component. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require sebastian/diff + +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 sebastian/diff + +### Usage + +The `Differ` class can be used to generate a textual representation of the difference between two strings: + +```php +use SebastianBergmann\Diff\Differ; + +$differ = new Differ; +print $differ->diff('foo', 'bar'); +``` + +The code above yields the output below: + + --- Original + +++ New + @@ @@ + -foo + +bar + +The `Parser` class can be used to parse a unified diff into an object graph: + +```php +use SebastianBergmann\Diff\Parser; +use SebastianBergmann\Git; + +$git = new Git('/usr/local/src/money'); + +$diff = $git->getDiff( + '948a1a07768d8edd10dcefa8315c1cbeffb31833', + 'c07a373d2399f3e686234c4f7f088d635eb9641b' +); + +$parser = new Parser; + +print_r($parser->parse($diff)); +``` + +The code above yields the output below: + + Array + ( + [0] => SebastianBergmann\Diff\Diff Object + ( + [from:SebastianBergmann\Diff\Diff:private] => a/tests/MoneyTest.php + [to:SebastianBergmann\Diff\Diff:private] => b/tests/MoneyTest.php + [chunks:SebastianBergmann\Diff\Diff:private] => Array + ( + [0] => SebastianBergmann\Diff\Chunk Object + ( + [start:SebastianBergmann\Diff\Chunk:private] => 87 + [startRange:SebastianBergmann\Diff\Chunk:private] => 7 + [end:SebastianBergmann\Diff\Chunk:private] => 87 + [endRange:SebastianBergmann\Diff\Chunk:private] => 7 + [lines:SebastianBergmann\Diff\Chunk:private] => Array + ( + [0] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::add + ) + + [1] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::newMoney + ) + + [2] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => */ + ) + + [3] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 2 + [content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyWithSameCurrencyObjectCanBeAdded() + ) + + [4] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 1 + [content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyObjectWithSameCurrencyCanBeAdded() + ) + + [5] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => { + ) + + [6] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => $a = new Money(1, new Currency('EUR')); + ) + + [7] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => $b = new Money(2, new Currency('EUR')); + ) + + ) + + ) + + ) + + ) + + ) diff --git a/vendor/sebastian/diff/build.xml b/vendor/sebastian/diff/build.xml new file mode 100644 index 000000000..fa7b7e2b9 --- /dev/null +++ b/vendor/sebastian/diff/build.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/sebastian/diff/composer.json b/vendor/sebastian/diff/composer.json index 4b4b8d148..8f2bcf3d0 100644 --- a/vendor/sebastian/diff/composer.json +++ b/vendor/sebastian/diff/composer.json @@ -15,10 +15,10 @@ } ], "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "autoload": { "classmap": [ diff --git a/vendor/sebastian/diff/phpunit.xml b/vendor/sebastian/diff/phpunit.xml new file mode 100644 index 000000000..68febeb04 --- /dev/null +++ b/vendor/sebastian/diff/phpunit.xml @@ -0,0 +1,19 @@ + + + + tests + + + + + src + + + diff --git a/vendor/sebastian/diff/src/Chunk.php b/vendor/sebastian/diff/src/Chunk.php index eb0810387..1a6ea7300 100644 --- a/vendor/sebastian/diff/src/Chunk.php +++ b/vendor/sebastian/diff/src/Chunk.php @@ -1,6 +1,6 @@ * @@ -10,8 +10,6 @@ namespace SebastianBergmann\Diff; -/** - */ class Chunk { /** @@ -28,6 +26,7 @@ class Chunk * @var int */ private $end; + /** * @var int */ diff --git a/vendor/sebastian/diff/src/Diff.php b/vendor/sebastian/diff/src/Diff.php index c4a089240..d3ab3ef4b 100644 --- a/vendor/sebastian/diff/src/Diff.php +++ b/vendor/sebastian/diff/src/Diff.php @@ -1,6 +1,6 @@ * @@ -10,8 +10,6 @@ namespace SebastianBergmann\Diff; -/** - */ class Diff { /** diff --git a/vendor/sebastian/diff/src/Differ.php b/vendor/sebastian/diff/src/Differ.php index 4960111ed..116c99c4b 100644 --- a/vendor/sebastian/diff/src/Differ.php +++ b/vendor/sebastian/diff/src/Differ.php @@ -1,6 +1,6 @@ * @@ -31,6 +31,7 @@ class Differ /** * @param string $header + * @param bool $showNonDiffLines */ public function __construct($header = "--- Original\n+++ New\n", $showNonDiffLines = true) { @@ -49,23 +50,52 @@ class Differ */ public function diff($from, $to, LongestCommonSubsequence $lcs = null) { - if (!is_array($from) && !is_string($from)) { - $from = (string) $from; + $from = $this->validateDiffInput($from); + $to = $this->validateDiffInput($to); + $diff = $this->diffToArray($from, $to, $lcs); + $old = $this->checkIfDiffInOld($diff); + $start = isset($old[0]) ? $old[0] : 0; + $end = \count($diff); + + if ($tmp = \array_search($end, $old)) { + $end = $tmp; } - if (!is_array($to) && !is_string($to)) { - $to = (string) $to; + return $this->getBuffer($diff, $old, $start, $end); + } + + /** + * Casts variable to string if it is not a string or array. + * + * @param mixed $input + * + * @return string + */ + private function validateDiffInput($input) + { + if (!\is_array($input) && !\is_string($input)) { + return (string) $input; } - $buffer = $this->header; - $diff = $this->diffToArray($from, $to, $lcs); + return $input; + } + /** + * Takes input of the diff array and returns the old array. + * Iterates through diff line by line, + * + * @param array $diff + * + * @return array + */ + private function checkIfDiffInOld(array $diff) + { $inOld = false; $i = 0; $old = array(); foreach ($diff as $line) { - if ($line[1] === 0 /* OLD */) { + if ($line[1] === 0 /* OLD */) { if ($inOld === false) { $inOld = $i; } @@ -80,46 +110,85 @@ class Differ ++$i; } - $start = isset($old[0]) ? $old[0] : 0; - $end = count($diff); + return $old; + } - if ($tmp = array_search($end, $old)) { - $end = $tmp; - } + /** + * Generates buffer in string format, returning the patch. + * + * @param array $diff + * @param array $old + * @param int $start + * @param int $end + * + * @return string + */ + private function getBuffer(array $diff, array $old, $start, $end) + { + $buffer = $this->header; - $newChunk = true; + if (!isset($old[$start])) { + $buffer = $this->getDiffBufferElementNew($diff, $buffer, $start); + ++$start; + } for ($i = $start; $i < $end; $i++) { if (isset($old[$i])) { - $buffer .= "\n"; - $newChunk = true; - $i = $old[$i]; + $i = $old[$i]; + $buffer = $this->getDiffBufferElementNew($diff, $buffer, $i); + } else { + $buffer = $this->getDiffBufferElement($diff, $buffer, $i); } + } - if ($newChunk) { - if ($this->showNonDiffLines === true) { - $buffer .= "@@ @@\n"; - } - $newChunk = false; - } + return $buffer; + } - if ($diff[$i][1] === 1 /* ADDED */) { - $buffer .= '+' . $diff[$i][0] . "\n"; - } elseif ($diff[$i][1] === 2 /* REMOVED */) { - $buffer .= '-' . $diff[$i][0] . "\n"; - } elseif ($this->showNonDiffLines === true) { - $buffer .= ' ' . $diff[$i][0] . "\n"; - } + /** + * Gets individual buffer element. + * + * @param array $diff + * @param string $buffer + * @param int $diffIndex + * + * @return string + */ + private function getDiffBufferElement(array $diff, $buffer, $diffIndex) + { + if ($diff[$diffIndex][1] === 1 /* ADDED */) { + $buffer .= '+' . $diff[$diffIndex][0] . "\n"; + } elseif ($diff[$diffIndex][1] === 2 /* REMOVED */) { + $buffer .= '-' . $diff[$diffIndex][0] . "\n"; + } elseif ($this->showNonDiffLines === true) { + $buffer .= ' ' . $diff[$diffIndex][0] . "\n"; } return $buffer; } + /** + * Gets individual buffer element with opening. + * + * @param array $diff + * @param string $buffer + * @param int $diffIndex + * + * @return string + */ + private function getDiffBufferElementNew(array $diff, $buffer, $diffIndex) + { + if ($this->showNonDiffLines === true) { + $buffer .= "@@ @@\n"; + } + + return $this->getDiffBufferElement($diff, $buffer, $diffIndex); + } + /** * Returns the diff between two arrays or strings as array. * * Each array element contains two elements: - * - [0] => string $token + * - [0] => mixed $token * - [1] => 2|1|0 * * - 2: REMOVED: $token was removed from $from @@ -134,55 +203,37 @@ class Differ */ public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null) { - preg_match_all('(\r\n|\r|\n)', $from, $fromMatches); - preg_match_all('(\r\n|\r|\n)', $to, $toMatches); - - if (is_string($from)) { - $from = preg_split('(\r\n|\r|\n)', $from); + if (\is_string($from)) { + $fromMatches = $this->getNewLineMatches($from); + $from = $this->splitStringByLines($from); + } elseif (\is_array($from)) { + $fromMatches = array(); + } else { + throw new \InvalidArgumentException('"from" must be an array or string.'); } - if (is_string($to)) { - $to = preg_split('(\r\n|\r|\n)', $to); + if (\is_string($to)) { + $toMatches = $this->getNewLineMatches($to); + $to = $this->splitStringByLines($to); + } elseif (\is_array($to)) { + $toMatches = array(); + } else { + throw new \InvalidArgumentException('"to" must be an array or string.'); } - $start = array(); - $end = array(); - $fromLength = count($from); - $toLength = count($to); - $length = min($fromLength, $toLength); - - for ($i = 0; $i < $length; ++$i) { - if ($from[$i] === $to[$i]) { - $start[] = $from[$i]; - unset($from[$i], $to[$i]); - } else { - break; - } - } - - $length -= $i; - - for ($i = 1; $i < $length; ++$i) { - if ($from[$fromLength - $i] === $to[$toLength - $i]) { - array_unshift($end, $from[$fromLength - $i]); - unset($from[$fromLength - $i], $to[$toLength - $i]); - } else { - break; - } - } + list($from, $to, $start, $end) = self::getArrayDiffParted($from, $to); if ($lcs === null) { $lcs = $this->selectLcsImplementation($from, $to); } - $common = $lcs->calculate(array_values($from), array_values($to)); + $common = $lcs->calculate(\array_values($from), \array_values($to)); $diff = array(); - if (isset($fromMatches[0]) && $toMatches[0] && - count($fromMatches[0]) === count($toMatches[0]) && - $fromMatches[0] !== $toMatches[0]) { + if ($this->detectUnmatchedLineEndings($fromMatches, $toMatches)) { $diff[] = array( - '#Warning: Strings contain different line endings!', 0 + '#Warning: Strings contain different line endings!', + 0 ); } @@ -190,29 +241,29 @@ class Differ $diff[] = array($token, 0 /* OLD */); } - reset($from); - reset($to); + \reset($from); + \reset($to); foreach ($common as $token) { - while ((($fromToken = reset($from)) !== $token)) { - $diff[] = array(array_shift($from), 2 /* REMOVED */); + while (($fromToken = \reset($from)) !== $token) { + $diff[] = array(\array_shift($from), 2 /* REMOVED */); } - while ((($toToken = reset($to)) !== $token)) { - $diff[] = array(array_shift($to), 1 /* ADDED */); + while (($toToken = \reset($to)) !== $token) { + $diff[] = array(\array_shift($to), 1 /* ADDED */); } $diff[] = array($token, 0 /* OLD */); - array_shift($from); - array_shift($to); + \array_shift($from); + \array_shift($to); } - while (($token = array_shift($from)) !== null) { + while (($token = \array_shift($from)) !== null) { $diff[] = array($token, 2 /* REMOVED */); } - while (($token = array_shift($to)) !== null) { + while (($token = \array_shift($to)) !== null) { $diff[] = array($token, 1 /* ADDED */); } @@ -223,6 +274,32 @@ class Differ return $diff; } + /** + * Get new strings denoting new lines from a given string. + * + * @param string $string + * + * @return array + */ + private function getNewLineMatches($string) + { + \preg_match_all('(\r\n|\r|\n)', $string, $stringMatches); + + return $stringMatches; + } + + /** + * Checks if input is string, if so it will split it line-by-line. + * + * @param string $input + * + * @return array + */ + private function splitStringByLines($input) + { + return \preg_split('(\r\n|\r|\n)', $input); + } + /** * @param array $from * @param array $to @@ -250,12 +327,73 @@ class Differ * @param array $from * @param array $to * - * @return int + * @return int|float */ private function calculateEstimatedFootprint(array $from, array $to) { - $itemSize = PHP_INT_SIZE == 4 ? 76 : 144; + $itemSize = PHP_INT_SIZE === 4 ? 76 : 144; + + return $itemSize * \pow(\min(\count($from), \count($to)), 2); + } + + /** + * Returns true if line ends don't match on fromMatches and toMatches. + * + * @param array $fromMatches + * @param array $toMatches + * + * @return bool + */ + private function detectUnmatchedLineEndings(array $fromMatches, array $toMatches) + { + return isset($fromMatches[0], $toMatches[0]) && + \count($fromMatches[0]) === \count($toMatches[0]) && + $fromMatches[0] !== $toMatches[0]; + } + + /** + * @param array $from + * @param array $to + * + * @return array + */ + private static function getArrayDiffParted(array &$from, array &$to) + { + $start = array(); + $end = array(); + + \reset($to); + + foreach ($from as $k => $v) { + $toK = \key($to); + + if ($toK === $k && $v === $to[$k]) { + $start[$k] = $v; + + unset($from[$k], $to[$k]); + } else { + break; + } + } + + \end($from); + \end($to); + + do { + $fromK = \key($from); + $toK = \key($to); + + if (null === $fromK || null === $toK || \current($from) !== \current($to)) { + break; + } + + \prev($from); + \prev($to); + + $end = array($fromK => $from[$fromK]) + $end; + unset($from[$fromK], $to[$toK]); + } while (true); - return $itemSize * pow(min(count($from), count($to)), 2); + return array($from, $to, $start, $end); } } diff --git a/vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php b/vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php index 5ea9cf962..28674abea 100644 --- a/vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php +++ b/vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php @@ -1,6 +1,6 @@ * diff --git a/vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php b/vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php index b990dc03c..c1b312182 100644 --- a/vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php +++ b/vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php @@ -1,6 +1,6 @@ * @@ -25,43 +25,45 @@ class MemoryEfficientImplementation implements LongestCommonSubsequence */ public function calculate(array $from, array $to) { - $cFrom = count($from); - $cTo = count($to); + $cFrom = \count($from); + $cTo = \count($to); - if ($cFrom == 0) { + if ($cFrom === 0) { return array(); - } elseif ($cFrom == 1) { - if (in_array($from[0], $to)) { + } + + if ($cFrom === 1) { + if (\in_array($from[0], $to, true)) { return array($from[0]); - } else { - return array(); } - } else { - $i = intval($cFrom / 2); - $fromStart = array_slice($from, 0, $i); - $fromEnd = array_slice($from, $i); - $llB = $this->length($fromStart, $to); - $llE = $this->length(array_reverse($fromEnd), array_reverse($to)); - $jMax = 0; - $max = 0; - for ($j = 0; $j <= $cTo; $j++) { - $m = $llB[$j] + $llE[$cTo - $j]; + return array(); + } - if ($m >= $max) { - $max = $m; - $jMax = $j; - } - } + $i = (int) ($cFrom / 2); + $fromStart = \array_slice($from, 0, $i); + $fromEnd = \array_slice($from, $i); + $llB = $this->length($fromStart, $to); + $llE = $this->length(\array_reverse($fromEnd), \array_reverse($to)); + $jMax = 0; + $max = 0; - $toStart = array_slice($to, 0, $jMax); - $toEnd = array_slice($to, $jMax); + for ($j = 0; $j <= $cTo; $j++) { + $m = $llB[$j] + $llE[$cTo - $j]; - return array_merge( - $this->calculate($fromStart, $toStart), - $this->calculate($fromEnd, $toEnd) - ); + if ($m >= $max) { + $max = $m; + $jMax = $j; + } } + + $toStart = \array_slice($to, 0, $jMax); + $toEnd = \array_slice($to, $jMax); + + return \array_merge( + $this->calculate($fromStart, $toStart), + $this->calculate($fromEnd, $toEnd) + ); } /** @@ -72,18 +74,18 @@ class MemoryEfficientImplementation implements LongestCommonSubsequence */ private function length(array $from, array $to) { - $current = array_fill(0, count($to) + 1, 0); - $cFrom = count($from); - $cTo = count($to); + $current = \array_fill(0, \count($to) + 1, 0); + $cFrom = \count($from); + $cTo = \count($to); for ($i = 0; $i < $cFrom; $i++) { $prev = $current; for ($j = 0; $j < $cTo; $j++) { - if ($from[$i] == $to[$j]) { + if ($from[$i] === $to[$j]) { $current[$j + 1] = $prev[$j] + 1; } else { - $current[$j + 1] = max($current[$j], $prev[$j + 1]); + $current[$j + 1] = \max($current[$j], $prev[$j + 1]); } } } diff --git a/vendor/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php b/vendor/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php index 4fc9d3ecf..f31db3eb8 100644 --- a/vendor/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php +++ b/vendor/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php @@ -1,6 +1,6 @@ * @@ -26,8 +26,8 @@ class TimeEfficientImplementation implements LongestCommonSubsequence public function calculate(array $from, array $to) { $common = array(); - $fromLength = count($from); - $toLength = count($to); + $fromLength = \count($from); + $toLength = \count($to); $width = $fromLength + 1; $matrix = new \SplFixedArray($width * ($toLength + 1)); @@ -42,7 +42,7 @@ class TimeEfficientImplementation implements LongestCommonSubsequence for ($i = 1; $i <= $fromLength; ++$i) { for ($j = 1; $j <= $toLength; ++$j) { $o = ($j * $width) + $i; - $matrix[$o] = max( + $matrix[$o] = \max( $matrix[$o - 1], $matrix[$o - $width], $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0 @@ -54,12 +54,13 @@ class TimeEfficientImplementation implements LongestCommonSubsequence $j = $toLength; while ($i > 0 && $j > 0) { - if ($from[$i-1] === $to[$j-1]) { - $common[] = $from[$i-1]; + if ($from[$i - 1] === $to[$j - 1]) { + $common[] = $from[$i - 1]; --$i; --$j; } else { $o = ($j * $width) + $i; + if ($matrix[$o - $width] > $matrix[$o - 1]) { --$j; } else { @@ -68,6 +69,6 @@ class TimeEfficientImplementation implements LongestCommonSubsequence } } - return array_reverse($common); + return \array_reverse($common); } } diff --git a/vendor/sebastian/diff/src/Line.php b/vendor/sebastian/diff/src/Line.php index e0a96b90a..89b86835e 100644 --- a/vendor/sebastian/diff/src/Line.php +++ b/vendor/sebastian/diff/src/Line.php @@ -1,6 +1,6 @@ * @@ -10,8 +10,6 @@ namespace SebastianBergmann\Diff; -/** - */ class Line { const ADDED = 1; diff --git a/vendor/sebastian/diff/src/Parser.php b/vendor/sebastian/diff/src/Parser.php index b01511b41..312c8411e 100644 --- a/vendor/sebastian/diff/src/Parser.php +++ b/vendor/sebastian/diff/src/Parser.php @@ -1,6 +1,6 @@ * @@ -22,33 +22,42 @@ class Parser */ public function parse($string) { - $lines = preg_split('(\r\n|\r|\n)', $string); - $lineCount = count($lines); + $lines = \preg_split('(\r\n|\r|\n)', $string); + + if (!empty($lines) && $lines[\count($lines) - 1] == '') { + \array_pop($lines); + } + + $lineCount = \count($lines); $diffs = array(); $diff = null; $collected = array(); for ($i = 0; $i < $lineCount; ++$i) { - if (preg_match('(^---\\s+(?P\\S+))', $lines[$i], $fromMatch) && - preg_match('(^\\+\\+\\+\\s+(?P\\S+))', $lines[$i + 1], $toMatch)) { + if (\preg_match('(^---\\s+(?P\\S+))', $lines[$i], $fromMatch) && + \preg_match('(^\\+\\+\\+\\s+(?P\\S+))', $lines[$i + 1], $toMatch)) { if ($diff !== null) { $this->parseFileDiff($diff, $collected); + $diffs[] = $diff; $collected = array(); } $diff = new Diff($fromMatch['file'], $toMatch['file']); + ++$i; } else { - if (preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) { + if (\preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) { continue; } + $collected[] = $lines[$i]; } } - if (count($collected) && ($diff !== null)) { + if ($diff !== null && \count($collected)) { $this->parseFileDiff($diff, $collected); + $diffs[] = $diff; } @@ -62,33 +71,35 @@ class Parser private function parseFileDiff(Diff $diff, array $lines) { $chunks = array(); + $chunk = null; foreach ($lines as $line) { - if (preg_match('/^@@\s+-(?P\d+)(?:,\s*(?P\d+))?\s+\+(?P\d+)(?:,\s*(?P\d+))?\s+@@/', $line, $match)) { + if (\preg_match('/^@@\s+-(?P\d+)(?:,\s*(?P\d+))?\s+\+(?P\d+)(?:,\s*(?P\d+))?\s+@@/', $line, $match)) { $chunk = new Chunk( $match['start'], - isset($match['startrange']) ? max(1, $match['startrange']) : 1, + isset($match['startrange']) ? \max(1, $match['startrange']) : 1, $match['end'], - isset($match['endrange']) ? max(1, $match['endrange']) : 1 + isset($match['endrange']) ? \max(1, $match['endrange']) : 1 ); $chunks[] = $chunk; $diffLines = array(); + continue; } - if (preg_match('/^(?P[+ -])?(?P.*)/', $line, $match)) { + if (\preg_match('/^(?P[+ -])?(?P.*)/', $line, $match)) { $type = Line::UNCHANGED; - if ($match['type'] == '+') { + if ($match['type'] === '+') { $type = Line::ADDED; - } elseif ($match['type'] == '-') { + } elseif ($match['type'] === '-') { $type = Line::REMOVED; } $diffLines[] = new Line($type, $match['line']); - if (isset($chunk)) { + if (null !== $chunk) { $chunk->setLines($diffLines); } } diff --git a/vendor/sebastian/diff/tests/ChunkTest.php b/vendor/sebastian/diff/tests/ChunkTest.php new file mode 100644 index 000000000..d065c133d --- /dev/null +++ b/vendor/sebastian/diff/tests/ChunkTest.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\Diff; + +use PHPUnit\Framework\TestCase; + +/** + * @covers SebastianBergmann\Diff\Chunk + */ +class ChunkTest extends TestCase +{ + /** + * @var Chunk + */ + private $chunk; + + protected function setUp() + { + $this->chunk = new Chunk; + } + + public function testCanBeCreatedWithoutArguments() + { + $this->assertInstanceOf('SebastianBergmann\Diff\Chunk', $this->chunk); + } + + public function testStartCanBeRetrieved() + { + $this->assertEquals(0, $this->chunk->getStart()); + } + + public function testStartRangeCanBeRetrieved() + { + $this->assertEquals(1, $this->chunk->getStartRange()); + } + + public function testEndCanBeRetrieved() + { + $this->assertEquals(0, $this->chunk->getEnd()); + } + + public function testEndRangeCanBeRetrieved() + { + $this->assertEquals(1, $this->chunk->getEndRange()); + } + + public function testLinesCanBeRetrieved() + { + $this->assertEquals(array(), $this->chunk->getLines()); + } + + public function testLinesCanBeSet() + { + $this->assertEquals(array(), $this->chunk->getLines()); + + $testValue = array('line0', 'line1'); + $this->chunk->setLines($testValue); + $this->assertEquals($testValue, $this->chunk->getLines()); + } +} diff --git a/vendor/sebastian/diff/tests/DiffTest.php b/vendor/sebastian/diff/tests/DiffTest.php new file mode 100644 index 000000000..e1fa55d6d --- /dev/null +++ b/vendor/sebastian/diff/tests/DiffTest.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\Diff; + +use PHPUnit\Framework\TestCase; + +/** + * @covers SebastianBergmann\Diff\Diff + * + * @uses SebastianBergmann\Diff\Chunk + */ +final class DiffTest extends TestCase +{ + public function testGettersAfterConstructionWithDefault() + { + $from = 'line1a'; + $to = 'line2a'; + $diff = new Diff($from, $to); + + $this->assertSame($from, $diff->getFrom()); + $this->assertSame($to, $diff->getTo()); + $this->assertSame(array(), $diff->getChunks(), 'Expect chunks to be default value "array()".'); + } + + public function testGettersAfterConstructionWithChunks() + { + $from = 'line1b'; + $to = 'line2b'; + $chunks = array(new Chunk(), new Chunk(2, 3)); + + $diff = new Diff($from, $to, $chunks); + + $this->assertSame($from, $diff->getFrom()); + $this->assertSame($to, $diff->getTo()); + $this->assertSame($chunks, $diff->getChunks(), 'Expect chunks to be passed value.'); + } + + public function testSetChunksAfterConstruction() + { + $diff = new Diff('line1c', 'line2c'); + $this->assertSame(array(), $diff->getChunks(), 'Expect chunks to be default value "array()".'); + + $chunks = array(new Chunk(), new Chunk(2, 3)); + $diff->setChunks($chunks); + $this->assertSame($chunks, $diff->getChunks(), 'Expect chunks to be passed value.'); + } +} diff --git a/vendor/sebastian/diff/tests/DifferTest.php b/vendor/sebastian/diff/tests/DifferTest.php new file mode 100644 index 000000000..b9403f218 --- /dev/null +++ b/vendor/sebastian/diff/tests/DifferTest.php @@ -0,0 +1,415 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\Diff; + +use SebastianBergmann\Diff\LCS\MemoryEfficientImplementation; +use SebastianBergmann\Diff\LCS\TimeEfficientImplementation; +use PHPUnit\Framework\TestCase; + +/** + * @covers SebastianBergmann\Diff\Differ + * + * @uses SebastianBergmann\Diff\LCS\MemoryEfficientImplementation + * @uses SebastianBergmann\Diff\LCS\TimeEfficientImplementation + * @uses SebastianBergmann\Diff\Chunk + * @uses SebastianBergmann\Diff\Diff + * @uses SebastianBergmann\Diff\Line + * @uses SebastianBergmann\Diff\Parser + */ +class DifferTest extends TestCase +{ + const REMOVED = 2; + const ADDED = 1; + const OLD = 0; + + /** + * @var Differ + */ + private $differ; + + protected function setUp() + { + $this->differ = new Differ; + } + + /** + * @param array $expected + * @param string|array $from + * @param string|array $to + * @dataProvider arrayProvider + */ + public function testArrayRepresentationOfDiffCanBeRenderedUsingTimeEfficientLcsImplementation(array $expected, $from, $to) + { + $this->assertEquals($expected, $this->differ->diffToArray($from, $to, new TimeEfficientImplementation)); + } + + /** + * @param string $expected + * @param string $from + * @param string $to + * @dataProvider textProvider + */ + public function testTextRepresentationOfDiffCanBeRenderedUsingTimeEfficientLcsImplementation($expected, $from, $to) + { + $this->assertEquals($expected, $this->differ->diff($from, $to, new TimeEfficientImplementation)); + } + + /** + * @param array $expected + * @param string|array $from + * @param string|array $to + * @dataProvider arrayProvider + */ + public function testArrayRepresentationOfDiffCanBeRenderedUsingMemoryEfficientLcsImplementation(array $expected, $from, $to) + { + $this->assertEquals($expected, $this->differ->diffToArray($from, $to, new MemoryEfficientImplementation)); + } + + /** + * @param string $expected + * @param string $from + * @param string $to + * @dataProvider textProvider + */ + public function testTextRepresentationOfDiffCanBeRenderedUsingMemoryEfficientLcsImplementation($expected, $from, $to) + { + $this->assertEquals($expected, $this->differ->diff($from, $to, new MemoryEfficientImplementation)); + } + + public function testCustomHeaderCanBeUsed() + { + $differ = new Differ('CUSTOM HEADER'); + + $this->assertEquals( + "CUSTOM HEADER@@ @@\n-a\n+b\n", + $differ->diff('a', 'b') + ); + } + + public function testTypesOtherThanArrayAndStringCanBePassed() + { + $this->assertEquals( + "--- Original\n+++ New\n@@ @@\n-1\n+2\n", + $this->differ->diff(1, 2) + ); + } + + /** + * @param string $diff + * @param Diff[] $expected + * @dataProvider diffProvider + */ + public function testParser($diff, array $expected) + { + $parser = new Parser; + $result = $parser->parse($diff); + + $this->assertEquals($expected, $result); + } + + public function arrayProvider() + { + return array( + array( + array( + array('a', self::REMOVED), + array('b', self::ADDED) + ), + 'a', + 'b' + ), + array( + array( + array('ba', self::REMOVED), + array('bc', self::ADDED) + ), + 'ba', + 'bc' + ), + array( + array( + array('ab', self::REMOVED), + array('cb', self::ADDED) + ), + 'ab', + 'cb' + ), + array( + array( + array('abc', self::REMOVED), + array('adc', self::ADDED) + ), + 'abc', + 'adc' + ), + array( + array( + array('ab', self::REMOVED), + array('abc', self::ADDED) + ), + 'ab', + 'abc' + ), + array( + array( + array('bc', self::REMOVED), + array('abc', self::ADDED) + ), + 'bc', + 'abc' + ), + array( + array( + array('abc', self::REMOVED), + array('abbc', self::ADDED) + ), + 'abc', + 'abbc' + ), + array( + array( + array('abcdde', self::REMOVED), + array('abcde', self::ADDED) + ), + 'abcdde', + 'abcde' + ), + 'same start' => array( + array( + array(17, self::OLD), + array('b', self::REMOVED), + array('d', self::ADDED), + ), + array(30 => 17, 'a' => 'b'), + array(30 => 17, 'c' => 'd'), + ), + 'same end' => array( + array( + array(1, self::REMOVED), + array(2, self::ADDED), + array('b', self::OLD), + ), + array(1 => 1, 'a' => 'b'), + array(1 => 2, 'a' => 'b'), + ), + 'same start (2), same end (1)' => array( + array( + array(17, self::OLD), + array(2, self::OLD), + array(4, self::REMOVED), + array('a', self::ADDED), + array(5, self::ADDED), + array('x', self::OLD), + ), + array(30 => 17, 1 => 2, 2 => 4, 'z' => 'x'), + array(30 => 17, 1 => 2, 3 => 'a', 2 => 5, 'z' => 'x'), + ), + 'same' => array( + array( + array('x', self::OLD), + ), + array('z' => 'x'), + array('z' => 'x'), + ), + 'diff' => array( + array( + array('y', self::REMOVED), + array('x', self::ADDED), + ), + array('x' => 'y'), + array('z' => 'x'), + ), + 'diff 2' => array( + array( + array('y', self::REMOVED), + array('b', self::REMOVED), + array('x', self::ADDED), + array('d', self::ADDED), + ), + array('x' => 'y', 'a' => 'b'), + array('z' => 'x', 'c' => 'd'), + ), + 'test line diff detection' => array( + array( + array( + '#Warning: Strings contain different line endings!', + self::OLD, + ), + array( + 'assertSame($expected, $differ->diff($from, $to)); + } + + public function textForNoNonDiffLinesProvider() + { + return array( + array( + '', 'a', 'a' + ), + array( + "-A\n+C\n", + "A\n\n\nB", + "C\n\n\nB", + ), + ); + } + + /** + * @requires PHPUnit 5.7 + */ + public function testDiffToArrayInvalidFromType() + { + $differ = new Differ; + + $this->expectException('\InvalidArgumentException'); + $this->expectExceptionMessageRegExp('#^"from" must be an array or string\.$#'); + + $differ->diffToArray(null, ''); + } + + /** + * @requires PHPUnit 5.7 + */ + public function testDiffInvalidToType() + { + $differ = new Differ; + + $this->expectException('\InvalidArgumentException'); + $this->expectExceptionMessageRegExp('#^"to" must be an array or string\.$#'); + + $differ->diffToArray('', new \stdClass); + } +} diff --git a/vendor/sebastian/diff/tests/LCS/LongestCommonSubsequenceTest.php b/vendor/sebastian/diff/tests/LCS/LongestCommonSubsequenceTest.php new file mode 100644 index 000000000..b4b408403 --- /dev/null +++ b/vendor/sebastian/diff/tests/LCS/LongestCommonSubsequenceTest.php @@ -0,0 +1,198 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\Diff\LCS; + +use PHPUnit\Framework\TestCase; + +abstract class LongestCommonSubsequenceTest extends TestCase +{ + /** + * @var LongestCommonSubsequence + */ + private $implementation; + + /** + * @var string + */ + private $memoryLimit; + + /** + * @var int[] + */ + private $stress_sizes = array(1, 2, 3, 100, 500, 1000, 2000); + + protected function setUp() + { + $this->memoryLimit = \ini_get('memory_limit'); + \ini_set('memory_limit', '256M'); + + $this->implementation = $this->createImplementation(); + } + + /** + * @return LongestCommonSubsequence + */ + abstract protected function createImplementation(); + + protected function tearDown() + { + \ini_set('memory_limit', $this->memoryLimit); + } + + public function testBothEmpty() + { + $from = array(); + $to = array(); + $common = $this->implementation->calculate($from, $to); + + $this->assertEquals(array(), $common); + } + + public function testIsStrictComparison() + { + $from = array( + false, 0, 0.0, '', null, array(), + true, 1, 1.0, 'foo', array('foo', 'bar'), array('foo' => 'bar') + ); + $to = $from; + $common = $this->implementation->calculate($from, $to); + + $this->assertEquals($from, $common); + + $to = array( + false, false, false, false, false, false, + true, true, true, true, true, true + ); + + $expected = array( + false, + true, + ); + + $common = $this->implementation->calculate($from, $to); + + $this->assertEquals($expected, $common); + } + + public function testEqualSequences() + { + foreach ($this->stress_sizes as $size) { + $range = \range(1, $size); + $from = $range; + $to = $range; + $common = $this->implementation->calculate($from, $to); + + $this->assertEquals($range, $common); + } + } + + public function testDistinctSequences() + { + $from = array('A'); + $to = array('B'); + $common = $this->implementation->calculate($from, $to); + $this->assertEquals(array(), $common); + + $from = array('A', 'B', 'C'); + $to = array('D', 'E', 'F'); + $common = $this->implementation->calculate($from, $to); + $this->assertEquals(array(), $common); + + foreach ($this->stress_sizes as $size) { + $from = \range(1, $size); + $to = \range($size + 1, $size * 2); + $common = $this->implementation->calculate($from, $to); + $this->assertEquals(array(), $common); + } + } + + public function testCommonSubsequence() + { + $from = array('A', 'C', 'E', 'F', 'G'); + $to = array('A', 'B', 'D', 'E', 'H'); + $expected = array('A', 'E'); + $common = $this->implementation->calculate($from, $to); + $this->assertEquals($expected, $common); + + $from = array('A', 'C', 'E', 'F', 'G'); + $to = array('B', 'C', 'D', 'E', 'F', 'H'); + $expected = array('C', 'E', 'F'); + $common = $this->implementation->calculate($from, $to); + $this->assertEquals($expected, $common); + + foreach ($this->stress_sizes as $size) { + $from = $size < 2 ? array(1) : \range(1, $size + 1, 2); + $to = $size < 3 ? array(1) : \range(1, $size + 1, 3); + $expected = $size < 6 ? array(1) : \range(1, $size + 1, 6); + $common = $this->implementation->calculate($from, $to); + + $this->assertEquals($expected, $common); + } + } + + public function testSingleElementSubsequenceAtStart() + { + foreach ($this->stress_sizes as $size) { + $from = \range(1, $size); + $to = \array_slice($from, 0, 1); + $common = $this->implementation->calculate($from, $to); + + $this->assertEquals($to, $common); + } + } + + public function testSingleElementSubsequenceAtMiddle() + { + foreach ($this->stress_sizes as $size) { + $from = \range(1, $size); + $to = \array_slice($from, (int) $size / 2, 1); + $common = $this->implementation->calculate($from, $to); + + $this->assertEquals($to, $common); + } + } + + public function testSingleElementSubsequenceAtEnd() + { + foreach ($this->stress_sizes as $size) { + $from = \range(1, $size); + $to = \array_slice($from, $size - 1, 1); + $common = $this->implementation->calculate($from, $to); + + $this->assertEquals($to, $common); + } + } + + public function testReversedSequences() + { + $from = array('A', 'B'); + $to = array('B', 'A'); + $expected = array('A'); + $common = $this->implementation->calculate($from, $to); + $this->assertEquals($expected, $common); + + foreach ($this->stress_sizes as $size) { + $from = \range(1, $size); + $to = \array_reverse($from); + $common = $this->implementation->calculate($from, $to); + + $this->assertEquals(array(1), $common); + } + } + + public function testStrictTypeCalculate() + { + $diff = $this->implementation->calculate(array('5'), array('05')); + + $this->assertInternalType('array', $diff); + $this->assertCount(0, $diff); + } +} diff --git a/vendor/sebastian/diff/tests/LCS/MemoryEfficientImplementationTest.php b/vendor/sebastian/diff/tests/LCS/MemoryEfficientImplementationTest.php new file mode 100644 index 000000000..b0e57a472 --- /dev/null +++ b/vendor/sebastian/diff/tests/LCS/MemoryEfficientImplementationTest.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\Diff\LCS; + +/** + * @covers SebastianBergmann\Diff\LCS\MemoryEfficientImplementation + */ +class MemoryEfficientImplementationTest extends LongestCommonSubsequenceTest +{ + protected function createImplementation() + { + return new MemoryEfficientImplementation; + } +} diff --git a/vendor/sebastian/diff/tests/LCS/TimeEfficientImplementationTest.php b/vendor/sebastian/diff/tests/LCS/TimeEfficientImplementationTest.php new file mode 100644 index 000000000..a3ecb570d --- /dev/null +++ b/vendor/sebastian/diff/tests/LCS/TimeEfficientImplementationTest.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\Diff\LCS; + +/** + * @covers SebastianBergmann\Diff\LCS\TimeEfficientImplementation + */ +class TimeEfficientImplementationTest extends LongestCommonSubsequenceTest +{ + protected function createImplementation() + { + return new TimeEfficientImplementation; + } +} diff --git a/vendor/sebastian/diff/tests/LineTest.php b/vendor/sebastian/diff/tests/LineTest.php new file mode 100644 index 000000000..6fd8c1676 --- /dev/null +++ b/vendor/sebastian/diff/tests/LineTest.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\Diff; + +use PHPUnit\Framework\TestCase; + +/** + * @covers SebastianBergmann\Diff\Line + */ +class LineTest extends TestCase +{ + /** + * @var Line + */ + private $line; + + protected function setUp() + { + $this->line = new Line; + } + + public function testCanBeCreatedWithoutArguments() + { + $this->assertInstanceOf('SebastianBergmann\Diff\Line', $this->line); + } + + public function testTypeCanBeRetrieved() + { + $this->assertEquals(Line::UNCHANGED, $this->line->getType()); + } + + public function testContentCanBeRetrieved() + { + $this->assertEquals('', $this->line->getContent()); + } +} diff --git a/vendor/sebastian/diff/tests/ParserTest.php b/vendor/sebastian/diff/tests/ParserTest.php new file mode 100644 index 000000000..0963d83ae --- /dev/null +++ b/vendor/sebastian/diff/tests/ParserTest.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\Diff; + +use PHPUnit\Framework\TestCase; + +/** + * @covers SebastianBergmann\Diff\Parser + * + * @uses SebastianBergmann\Diff\Chunk + * @uses SebastianBergmann\Diff\Diff + * @uses SebastianBergmann\Diff\Line + */ +class ParserTest extends TestCase +{ + /** + * @var Parser + */ + private $parser; + + protected function setUp() + { + $this->parser = new Parser; + } + + public function testParse() + { + $content = \file_get_contents(__DIR__ . '/fixtures/patch.txt'); + + $diffs = $this->parser->parse($content); + + $this->assertInternalType('array', $diffs); + $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Diff', $diffs); + $this->assertCount(1, $diffs); + + $chunks = $diffs[0]->getChunks(); + $this->assertInternalType('array', $chunks); + $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Chunk', $chunks); + + $this->assertCount(1, $chunks); + + $this->assertEquals(20, $chunks[0]->getStart()); + + $this->assertCount(4, $chunks[0]->getLines()); + } + + public function testParseWithMultipleChunks() + { + $content = \file_get_contents(__DIR__ . '/fixtures/patch2.txt'); + + $diffs = $this->parser->parse($content); + + $this->assertCount(1, $diffs); + + $chunks = $diffs[0]->getChunks(); + $this->assertCount(3, $chunks); + + $this->assertEquals(20, $chunks[0]->getStart()); + $this->assertEquals(320, $chunks[1]->getStart()); + $this->assertEquals(600, $chunks[2]->getStart()); + + $this->assertCount(5, $chunks[0]->getLines()); + $this->assertCount(5, $chunks[1]->getLines()); + $this->assertCount(4, $chunks[2]->getLines()); + } + + public function testParseWithRemovedLines() + { + $content = <<parser->parse($content); + $this->assertInternalType('array', $diffs); + $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Diff', $diffs); + $this->assertCount(1, $diffs); + + $chunks = $diffs[0]->getChunks(); + + $this->assertInternalType('array', $chunks); + $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Chunk', $chunks); + $this->assertCount(1, $chunks); + + $chunk = $chunks[0]; + $this->assertSame(49, $chunk->getStart()); + $this->assertSame(49, $chunk->getEnd()); + $this->assertSame(9, $chunk->getStartRange()); + $this->assertSame(8, $chunk->getEndRange()); + + $lines = $chunk->getLines(); + $this->assertInternalType('array', $lines); + $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Line', $lines); + $this->assertCount(2, $lines); + + /** @var Line $line */ + $line = $lines[0]; + $this->assertSame('A', $line->getContent()); + $this->assertSame(Line::UNCHANGED, $line->getType()); + + $line = $lines[1]; + $this->assertSame('B', $line->getContent()); + $this->assertSame(Line::REMOVED, $line->getType()); + } + + public function testParseDiffForMulitpleFiles() + { + $content = <<parser->parse($content); + $this->assertCount(2, $diffs); + + /** @var Diff $diff */ + $diff = $diffs[0]; + $this->assertSame('a/Test.txt', $diff->getFrom()); + $this->assertSame('b/Test.txt', $diff->getTo()); + $this->assertCount(1, $diff->getChunks()); + + $diff = $diffs[1]; + $this->assertSame('a/Test2.txt', $diff->getFrom()); + $this->assertSame('b/Test2.txt', $diff->getTo()); + $this->assertCount(1, $diff->getChunks()); + } +} diff --git a/vendor/sebastian/diff/tests/fixtures/patch.txt b/vendor/sebastian/diff/tests/fixtures/patch.txt new file mode 100644 index 000000000..144b61d01 --- /dev/null +++ b/vendor/sebastian/diff/tests/fixtures/patch.txt @@ -0,0 +1,9 @@ +diff --git a/Foo.php b/Foo.php +index abcdefg..abcdefh 100644 +--- a/Foo.php ++++ b/Foo.php +@@ -20,4 +20,5 @@ class Foo + const ONE = 1; + const TWO = 2; ++ const THREE = 3; + const FOUR = 4; diff --git a/vendor/sebastian/diff/tests/fixtures/patch2.txt b/vendor/sebastian/diff/tests/fixtures/patch2.txt new file mode 100644 index 000000000..41fbc9597 --- /dev/null +++ b/vendor/sebastian/diff/tests/fixtures/patch2.txt @@ -0,0 +1,21 @@ +diff --git a/Foo.php b/Foo.php +index abcdefg..abcdefh 100644 +--- a/Foo.php ++++ b/Foo.php +@@ -20,4 +20,5 @@ class Foo + const ONE = 1; + const TWO = 2; ++ const THREE = 3; + const FOUR = 4; + +@@ -320,4 +320,5 @@ class Foo + const A = 'A'; + const B = 'B'; ++ const C = 'C'; + const D = 'D'; + +@@ -600,4 +600,5 @@ class Foo + public function doSomething() { + ++ return 'foo'; + } diff --git a/vendor/symfony-cmf/routing/Candidates/Candidates.php b/vendor/symfony-cmf/routing/Candidates/Candidates.php index 21bef5514..b0a3ab4ca 100644 --- a/vendor/symfony-cmf/routing/Candidates/Candidates.php +++ b/vendor/symfony-cmf/routing/Candidates/Candidates.php @@ -108,7 +108,7 @@ class Candidates implements CandidatesInterface } $matches = array(); - if (preg_match('#('.implode('|', $this->locales).')(/|$)#', $url, $matches)) { + if (preg_match('#^/('.implode('|', $this->locales).')(/|$)#', $url, $matches)) { return $matches[1]; } diff --git a/vendor/symfony-cmf/routing/README.md b/vendor/symfony-cmf/routing/README.md index 2a18ed161..dbafdd207 100644 --- a/vendor/symfony-cmf/routing/README.md +++ b/vendor/symfony-cmf/routing/README.md @@ -1,6 +1,6 @@ # Symfony CMF Routing Component -[![Build Status](https://secure.travis-ci.org/symfony-cmf/Routing.png?branch=master)](http://travis-ci.org/symfony-cmf/Routing) +[![Build Status](https://travis-ci.org/symfony-cmf/routing.svg?branch=master)](https://travis-ci.org/symfony-cmf/routing) [![Latest Stable Version](https://poser.pugx.org/symfony-cmf/routing/version.png)](https://packagist.org/packages/symfony-cmf/routing) [![Total Downloads](https://poser.pugx.org/symfony-cmf/routing/d/total.png)](https://packagist.org/packages/symfony-cmf/routing) diff --git a/vendor/symfony-cmf/routing/Tests/Routing/DynamicRouterTest.php b/vendor/symfony-cmf/routing/Tests/Routing/DynamicRouterTest.php index 1204b03b6..b7c8ecaa8 100644 --- a/vendor/symfony-cmf/routing/Tests/Routing/DynamicRouterTest.php +++ b/vendor/symfony-cmf/routing/Tests/Routing/DynamicRouterTest.php @@ -29,7 +29,7 @@ class DynamicRouterTest extends CmfUnitTestCase protected $context; public $request; - protected $url = '/foo/bar'; + const URL = '/foo/bar'; public function setUp() { @@ -40,7 +40,7 @@ class DynamicRouterTest extends CmfUnitTestCase $this->enhancer = $this->buildMock('Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface', array('enhance')); $this->context = $this->buildMock('Symfony\Component\Routing\RequestContext'); - $this->request = Request::create($this->url); + $this->request = Request::create(self::URL); $this->router = new DynamicRouter($this->context, $this->matcher, $this->generator); $this->router->addRouteEnhancer($this->enhancer); @@ -142,18 +142,21 @@ class DynamicRouterTest extends CmfUnitTestCase $routeDefaults = array('foo' => 'bar'); $this->matcher->expects($this->once()) ->method('match') - ->with($this->url) + ->with(self::URL) ->will($this->returnValue($routeDefaults)) ; $expected = array('this' => 'that'); + $test = $this; $this->enhancer->expects($this->once()) ->method('enhance') - ->with($this->equalTo($routeDefaults), $this->equalTo($this->request)) + ->with($this->equalTo($routeDefaults), $this->callback(function (Request $request) use ($test) { + return DynamicRouterTest::URL === $request->server->get('REQUEST_URI'); + })) ->will($this->returnValue($expected)) ; - $results = $this->router->match($this->url); + $results = $this->router->match(self::URL); $this->assertEquals($expected, $results); } @@ -164,15 +167,17 @@ class DynamicRouterTest extends CmfUnitTestCase $this->matcher->expects($this->once()) ->method('match') - ->with($this->url) + ->with(self::URL) ->will($this->returnValue($routeDefaults)) ; $expected = array('this' => 'that'); + $test = $this; $this->enhancer->expects($this->once()) ->method('enhance') - // somehow request object gets confused, check on instance only - ->with($this->equalTo($routeDefaults), $this->isInstanceOf('Symfony\Component\HttpFoundation\Request')) + ->with($this->equalTo($routeDefaults), $this->callback(function (Request $request) use ($test) { + return DynamicRouterTest::URL === $request->server->get('REQUEST_URI'); + })) ->will($this->returnValue($expected)) ; @@ -195,9 +200,12 @@ class DynamicRouterTest extends CmfUnitTestCase ; $expected = array('this' => 'that'); + $test = $this; $this->enhancer->expects($this->once()) ->method('enhance') - ->with($this->equalTo($routeDefaults), $this->equalTo($this->request)) + ->with($this->equalTo($routeDefaults), $this->callback(function (Request $request) use ($test) { + return DynamicRouterTest::URL === $request->server->get('REQUEST_URI'); + })) ->will($this->returnValue($expected)) ; @@ -223,7 +231,7 @@ class DynamicRouterTest extends CmfUnitTestCase ->method('enhance') ; - $router->match($this->url); + $router->match(self::URL); } /** @@ -256,7 +264,7 @@ class DynamicRouterTest extends CmfUnitTestCase $matcher = $this->buildMock('Symfony\Component\Routing\Matcher\RequestMatcherInterface', array('matchRequest', 'setContext', 'getContext')); $router = new DynamicRouter($this->context, $matcher, $this->generator); - $router->match($this->url); + $router->match(self::URL); } /** @@ -301,11 +309,11 @@ class DynamicRouterTest extends CmfUnitTestCase $routeDefaults = array('foo' => 'bar'); $this->matcher->expects($this->once()) ->method('match') - ->with($this->url) + ->with(self::URL) ->will($this->returnValue($routeDefaults)) ; - $this->assertEquals($routeDefaults, $router->match($this->url)); + $this->assertEquals($routeDefaults, $router->match(self::URL)); } public function testEventHandlerRequest() @@ -327,7 +335,7 @@ class DynamicRouterTest extends CmfUnitTestCase $routeDefaults = array('foo' => 'bar'); $this->matcher->expects($this->once()) ->method('match') - ->with($this->url) + ->with(self::URL) ->will($this->returnValue($routeDefaults)) ; diff --git a/vendor/symfony/browser-kit/CHANGELOG.md b/vendor/symfony/browser-kit/CHANGELOG.md index 37b6f6e99..036595c9b 100644 --- a/vendor/symfony/browser-kit/CHANGELOG.md +++ b/vendor/symfony/browser-kit/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +3.3.0 +----- + + * [BC BREAK] The request method is dropped from POST to GET when the response + status code is 301. + 3.2.0 ----- diff --git a/vendor/symfony/browser-kit/Client.php b/vendor/symfony/browser-kit/Client.php index e6911d1b0..286f2f98c 100644 --- a/vendor/symfony/browser-kit/Client.php +++ b/vendor/symfony/browser-kit/Client.php @@ -474,7 +474,7 @@ abstract class Client $request = $this->internalRequest; - if (in_array($this->internalResponse->getStatus(), array(302, 303))) { + if (in_array($this->internalResponse->getStatus(), array(301, 302, 303))) { $method = 'GET'; $files = array(); $content = null; diff --git a/vendor/symfony/browser-kit/Tests/ClientTest.php b/vendor/symfony/browser-kit/Tests/ClientTest.php index 9e1530168..5bd4dad7b 100644 --- a/vendor/symfony/browser-kit/Tests/ClientTest.php +++ b/vendor/symfony/browser-kit/Tests/ClientTest.php @@ -510,6 +510,28 @@ class ClientTest extends TestCase $this->assertEquals('POST', $client->getRequest()->getMethod(), '->followRedirect() keeps request method'); } + public function testFollowRedirectDropPostMethod() + { + $parameters = array('foo' => 'bar'); + $files = array('myfile.foo' => 'baz'); + $server = array('X_TEST_FOO' => 'bazbar'); + $content = 'foobarbaz'; + + $client = new TestClient(); + + foreach (array(301, 302, 303) as $code) { + $client->setNextResponse(new Response('', $code, array('Location' => 'http://www.example.com/redirected'))); + $client->request('POST', 'http://www.example.com/foo/foobar', $parameters, $files, $server, $content); + + $this->assertEquals('http://www.example.com/redirected', $client->getRequest()->getUri(), '->followRedirect() follows a redirect with POST method on response code: '.$code.'.'); + $this->assertEmpty($client->getRequest()->getParameters(), '->followRedirect() drops parameters with POST method on response code: '.$code.'.'); + $this->assertEmpty($client->getRequest()->getFiles(), '->followRedirect() drops files with POST method on response code: '.$code.'.'); + $this->assertArrayHasKey('X_TEST_FOO', $client->getRequest()->getServer(), '->followRedirect() keeps $_SERVER with POST method on response code: '.$code.'.'); + $this->assertEmpty($client->getRequest()->getContent(), '->followRedirect() drops content with POST method on response code: '.$code.'.'); + $this->assertEquals('GET', $client->getRequest()->getMethod(), '->followRedirect() drops request method to GET on response code: '.$code.'.'); + } + } + public function testBack() { $client = new TestClient(); diff --git a/vendor/symfony/browser-kit/composer.json b/vendor/symfony/browser-kit/composer.json index 3ff07e96f..a18d66e81 100644 --- a/vendor/symfony/browser-kit/composer.json +++ b/vendor/symfony/browser-kit/composer.json @@ -35,7 +35,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "3.3-dev" } } } diff --git a/vendor/symfony/browser-kit/phpunit.xml.dist b/vendor/symfony/browser-kit/phpunit.xml.dist index d76b2b98a..fa6d06a80 100644 --- a/vendor/symfony/browser-kit/phpunit.xml.dist +++ b/vendor/symfony/browser-kit/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/class-loader/ClassCollectionLoader.php b/vendor/symfony/class-loader/ClassCollectionLoader.php index 6f88286de..cd3c433ed 100644 --- a/vendor/symfony/class-loader/ClassCollectionLoader.php +++ b/vendor/symfony/class-loader/ClassCollectionLoader.php @@ -232,7 +232,7 @@ REGEX; $output .= self::compressCode($rawChunk); - if (PHP_VERSION_ID >= 70000) { + if (\PHP_VERSION_ID >= 70000) { // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 unset($tokens, $rawChunk); gc_mem_caches(); diff --git a/vendor/symfony/class-loader/ClassMapGenerator.php b/vendor/symfony/class-loader/ClassMapGenerator.php index 2976eb81c..a35c90ca1 100644 --- a/vendor/symfony/class-loader/ClassMapGenerator.php +++ b/vendor/symfony/class-loader/ClassMapGenerator.php @@ -12,7 +12,7 @@ namespace Symfony\Component\ClassLoader; if (!defined('SYMFONY_TRAIT')) { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { define('SYMFONY_TRAIT', T_TRAIT); } else { define('SYMFONY_TRAIT', 0); @@ -72,7 +72,7 @@ class ClassMapGenerator $classes = self::findClasses($path); - if (PHP_VERSION_ID >= 70000) { + if (\PHP_VERSION_ID >= 70000) { // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 gc_mem_caches(); } diff --git a/vendor/symfony/class-loader/Tests/ClassMapGeneratorTest.php b/vendor/symfony/class-loader/Tests/ClassMapGeneratorTest.php index db7fb962c..c12182497 100644 --- a/vendor/symfony/class-loader/Tests/ClassMapGeneratorTest.php +++ b/vendor/symfony/class-loader/Tests/ClassMapGeneratorTest.php @@ -108,7 +108,7 @@ class ClassMapGeneratorTest extends TestCase )), ); - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $data[] = array(__DIR__.'/Fixtures/php5.4', array( 'TFoo' => __DIR__.'/Fixtures/php5.4/traits.php', 'CFoo' => __DIR__.'/Fixtures/php5.4/traits.php', @@ -119,7 +119,7 @@ class ClassMapGeneratorTest extends TestCase )); } - if (PHP_VERSION_ID >= 50500) { + if (\PHP_VERSION_ID >= 50500) { $data[] = array(__DIR__.'/Fixtures/php5.5', array( 'ClassCons\\Foo' => __DIR__.'/Fixtures/php5.5/class_cons.php', )); diff --git a/vendor/symfony/class-loader/phpunit.xml.dist b/vendor/symfony/class-loader/phpunit.xml.dist index 4856db5be..5158b22f2 100644 --- a/vendor/symfony/class-loader/phpunit.xml.dist +++ b/vendor/symfony/class-loader/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/config/Tests/ConfigCacheFactoryTest.php b/vendor/symfony/config/Tests/ConfigCacheFactoryTest.php new file mode 100644 index 000000000..c523e5cd5 --- /dev/null +++ b/vendor/symfony/config/Tests/ConfigCacheFactoryTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\ConfigCacheFactory; + +class ConfigCacheFactoryTest extends TestCase +{ + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid type for callback argument. Expected callable, but got "object". + */ + public function testCachWithInvalidCallback() + { + $cacheFactory = new ConfigCacheFactory(true); + + $cacheFactory->cache('file', new \stdClass()); + } +} diff --git a/vendor/symfony/config/Tests/ConfigCacheTest.php b/vendor/symfony/config/Tests/ConfigCacheTest.php new file mode 100644 index 000000000..bf8131d51 --- /dev/null +++ b/vendor/symfony/config/Tests/ConfigCacheTest.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\Config\Tests\Resource\ResourceStub; + +class ConfigCacheTest extends TestCase +{ + private $cacheFile = null; + + protected function setUp() + { + $this->cacheFile = tempnam(sys_get_temp_dir(), 'config_'); + } + + protected function tearDown() + { + $files = array($this->cacheFile, $this->cacheFile.'.meta'); + + foreach ($files as $file) { + if (file_exists($file)) { + unlink($file); + } + } + } + + /** + * @dataProvider debugModes + */ + public function testCacheIsNotValidIfNothingHasBeenCached($debug) + { + unlink($this->cacheFile); // remove tempnam() side effect + $cache = new ConfigCache($this->cacheFile, $debug); + + $this->assertFalse($cache->isFresh()); + } + + public function testIsAlwaysFreshInProduction() + { + $staleResource = new ResourceStub(); + $staleResource->setFresh(false); + + $cache = new ConfigCache($this->cacheFile, false); + $cache->write('', array($staleResource)); + + $this->assertTrue($cache->isFresh()); + } + + /** + * @dataProvider debugModes + */ + public function testIsFreshWhenNoResourceProvided($debug) + { + $cache = new ConfigCache($this->cacheFile, $debug); + $cache->write('', array()); + $this->assertTrue($cache->isFresh()); + } + + public function testFreshResourceInDebug() + { + $freshResource = new ResourceStub(); + $freshResource->setFresh(true); + + $cache = new ConfigCache($this->cacheFile, true); + $cache->write('', array($freshResource)); + + $this->assertTrue($cache->isFresh()); + } + + public function testStaleResourceInDebug() + { + $staleResource = new ResourceStub(); + $staleResource->setFresh(false); + + $cache = new ConfigCache($this->cacheFile, true); + $cache->write('', array($staleResource)); + + $this->assertFalse($cache->isFresh()); + } + + public function debugModes() + { + return array( + array(true), + array(false), + ); + } +} diff --git a/vendor/symfony/config/Tests/Definition/ArrayNodeTest.php b/vendor/symfony/config/Tests/Definition/ArrayNodeTest.php new file mode 100644 index 000000000..0b5565e0b --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/ArrayNodeTest.php @@ -0,0 +1,219 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\ArrayNode; +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use Symfony\Component\Config\Definition\ScalarNode; + +class ArrayNodeTest extends TestCase +{ + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException + */ + public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed() + { + $node = new ArrayNode('root'); + $node->normalize(false); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage Unrecognized option "foo" under "root" + */ + public function testExceptionThrownOnUnrecognizedChild() + { + $node = new ArrayNode('root'); + $node->normalize(array('foo' => 'bar')); + } + + public function ignoreAndRemoveMatrixProvider() + { + $unrecognizedOptionException = new InvalidConfigurationException('Unrecognized option "foo" under "root"'); + + return array( + array(true, true, array(), 'no exception is thrown for an unrecognized child if the ignoreExtraKeys option is set to true'), + array(true, false, array('foo' => 'bar'), 'extra keys are not removed when ignoreExtraKeys second option is set to false'), + array(false, true, $unrecognizedOptionException), + array(false, false, $unrecognizedOptionException), + ); + } + + /** + * @dataProvider ignoreAndRemoveMatrixProvider + */ + public function testIgnoreAndRemoveBehaviors($ignore, $remove, $expected, $message = '') + { + if ($expected instanceof \Exception) { + if (method_exists($this, 'expectException')) { + $this->expectException(get_class($expected)); + $this->expectExceptionMessage($expected->getMessage()); + } else { + $this->setExpectedException(get_class($expected), $expected->getMessage()); + } + } + $node = new ArrayNode('root'); + $node->setIgnoreExtraKeys($ignore, $remove); + $result = $node->normalize(array('foo' => 'bar')); + $this->assertSame($expected, $result, $message); + } + + /** + * @dataProvider getPreNormalizationTests + */ + public function testPreNormalize($denormalized, $normalized) + { + $node = new ArrayNode('foo'); + + $r = new \ReflectionMethod($node, 'preNormalize'); + $r->setAccessible(true); + + $this->assertSame($normalized, $r->invoke($node, $denormalized)); + } + + public function getPreNormalizationTests() + { + return array( + array( + array('foo-bar' => 'foo'), + array('foo_bar' => 'foo'), + ), + array( + array('foo-bar_moo' => 'foo'), + array('foo-bar_moo' => 'foo'), + ), + array( + array('anything-with-dash-and-no-underscore' => 'first', 'no_dash' => 'second'), + array('anything_with_dash_and_no_underscore' => 'first', 'no_dash' => 'second'), + ), + array( + array('foo-bar' => null, 'foo_bar' => 'foo'), + array('foo-bar' => null, 'foo_bar' => 'foo'), + ), + ); + } + + /** + * @dataProvider getZeroNamedNodeExamplesData + */ + public function testNodeNameCanBeZero($denormalized, $normalized) + { + $zeroNode = new ArrayNode(0); + $zeroNode->addChild(new ScalarNode('name')); + $fiveNode = new ArrayNode(5); + $fiveNode->addChild(new ScalarNode(0)); + $fiveNode->addChild(new ScalarNode('new_key')); + $rootNode = new ArrayNode('root'); + $rootNode->addChild($zeroNode); + $rootNode->addChild($fiveNode); + $rootNode->addChild(new ScalarNode('string_key')); + $r = new \ReflectionMethod($rootNode, 'normalizeValue'); + $r->setAccessible(true); + + $this->assertSame($normalized, $r->invoke($rootNode, $denormalized)); + } + + public function getZeroNamedNodeExamplesData() + { + return array( + array( + array( + 0 => array( + 'name' => 'something', + ), + 5 => array( + 0 => 'this won\'t work too', + 'new_key' => 'some other value', + ), + 'string_key' => 'just value', + ), + array( + 0 => array( + 'name' => 'something', + ), + 5 => array( + 0 => 'this won\'t work too', + 'new_key' => 'some other value', + ), + 'string_key' => 'just value', + ), + ), + ); + } + + /** + * @dataProvider getPreNormalizedNormalizedOrderedData + */ + public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized) + { + $scalar1 = new ScalarNode('1'); + $scalar2 = new ScalarNode('2'); + $scalar3 = new ScalarNode('3'); + $node = new ArrayNode('foo'); + $node->addChild($scalar1); + $node->addChild($scalar3); + $node->addChild($scalar2); + + $r = new \ReflectionMethod($node, 'normalizeValue'); + $r->setAccessible(true); + + $this->assertSame($normalized, $r->invoke($node, $prenormalized)); + } + + public function getPreNormalizedNormalizedOrderedData() + { + return array( + array( + array('2' => 'two', '1' => 'one', '3' => 'three'), + array('2' => 'two', '1' => 'one', '3' => 'three'), + ), + ); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Child nodes must be named. + */ + public function testAddChildEmptyName() + { + $node = new ArrayNode('root'); + + $childNode = new ArrayNode(''); + $node->addChild($childNode); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage A child node named "foo" already exists. + */ + public function testAddChildNameAlreadyExists() + { + $node = new ArrayNode('root'); + + $childNode = new ArrayNode('foo'); + $node->addChild($childNode); + + $childNodeWithSameName = new ArrayNode('foo'); + $node->addChild($childNodeWithSameName); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage The node at path "foo" has no default value. + */ + public function testGetDefaultValueWithoutDefaultValue() + { + $node = new ArrayNode('foo'); + $node->getDefaultValue(); + } +} diff --git a/vendor/symfony/config/Tests/Definition/BooleanNodeTest.php b/vendor/symfony/config/Tests/Definition/BooleanNodeTest.php new file mode 100644 index 000000000..ab1d31641 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/BooleanNodeTest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\BooleanNode; + +class BooleanNodeTest extends TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new BooleanNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + /** + * @dataProvider getValidValues + * + * @param bool $value + */ + public function testValidNonEmptyValues($value) + { + $node = new BooleanNode('test'); + $node->setAllowEmptyValue(false); + + $this->assertSame($value, $node->finalize($value)); + } + + public function getValidValues() + { + return array( + array(false), + array(true), + ); + } + + /** + * @dataProvider getInvalidValues + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $node = new BooleanNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return array( + array(null), + array(''), + array('foo'), + array(0), + array(1), + array(0.0), + array(0.1), + array(array()), + array(array('foo' => 'bar')), + array(new \stdClass()), + ); + } +} diff --git a/vendor/symfony/config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php b/vendor/symfony/config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php new file mode 100644 index 000000000..63efd719b --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php @@ -0,0 +1,253 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition; +use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; + +class ArrayNodeDefinitionTest extends TestCase +{ + public function testAppendingSomeNode() + { + $parent = new ArrayNodeDefinition('root'); + $child = new ScalarNodeDefinition('child'); + + $parent + ->children() + ->scalarNode('foo')->end() + ->scalarNode('bar')->end() + ->end() + ->append($child); + + $this->assertCount(3, $this->getField($parent, 'children')); + $this->assertTrue(in_array($child, $this->getField($parent, 'children'))); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException + * @dataProvider providePrototypeNodeSpecificCalls + */ + public function testPrototypeNodeSpecificOption($method, $args) + { + $node = new ArrayNodeDefinition('root'); + + call_user_func_array(array($node, $method), $args); + + $node->getNode(); + } + + public function providePrototypeNodeSpecificCalls() + { + return array( + array('defaultValue', array(array())), + array('addDefaultChildrenIfNoneSet', array()), + array('requiresAtLeastOneElement', array()), + array('useAttributeAsKey', array('foo')), + ); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException + */ + public function testConcreteNodeSpecificOption() + { + $node = new ArrayNodeDefinition('root'); + $node + ->addDefaultsIfNotSet() + ->prototype('array') + ; + $node->getNode(); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException + */ + public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaultChildren() + { + $node = new ArrayNodeDefinition('root'); + $node + ->defaultValue(array()) + ->addDefaultChildrenIfNoneSet('foo') + ->prototype('array') + ; + $node->getNode(); + } + + public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren() + { + $node = new ArrayNodeDefinition('root'); + $node + ->addDefaultChildrenIfNoneSet() + ->prototype('array') + ; + $tree = $node->getNode(); + $this->assertEquals(array(array()), $tree->getDefaultValue()); + } + + /** + * @dataProvider providePrototypedArrayNodeDefaults + */ + public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults) + { + $node = new ArrayNodeDefinition('root'); + $node + ->addDefaultChildrenIfNoneSet($args) + ->prototype('array') + ; + + try { + $tree = $node->getNode(); + $this->assertFalse($shouldThrowWhenNotUsingAttrAsKey); + $this->assertEquals($defaults, $tree->getDefaultValue()); + } catch (InvalidDefinitionException $e) { + $this->assertTrue($shouldThrowWhenNotUsingAttrAsKey); + } + + $node = new ArrayNodeDefinition('root'); + $node + ->useAttributeAsKey('attr') + ->addDefaultChildrenIfNoneSet($args) + ->prototype('array') + ; + + try { + $tree = $node->getNode(); + $this->assertFalse($shouldThrowWhenUsingAttrAsKey); + $this->assertEquals($defaults, $tree->getDefaultValue()); + } catch (InvalidDefinitionException $e) { + $this->assertTrue($shouldThrowWhenUsingAttrAsKey); + } + } + + public function providePrototypedArrayNodeDefaults() + { + return array( + array(null, true, false, array(array())), + array(2, true, false, array(array(), array())), + array('2', false, true, array('2' => array())), + array('foo', false, true, array('foo' => array())), + array(array('foo'), false, true, array('foo' => array())), + array(array('foo', 'bar'), false, true, array('foo' => array(), 'bar' => array())), + ); + } + + public function testNestedPrototypedArrayNodes() + { + $nodeDefinition = new ArrayNodeDefinition('root'); + $nodeDefinition + ->addDefaultChildrenIfNoneSet() + ->prototype('array') + ->prototype('array') + ; + $node = $nodeDefinition->getNode(); + + $this->assertInstanceOf('Symfony\Component\Config\Definition\PrototypedArrayNode', $node); + $this->assertInstanceOf('Symfony\Component\Config\Definition\PrototypedArrayNode', $node->getPrototype()); + } + + public function testEnabledNodeDefaults() + { + $node = new ArrayNodeDefinition('root'); + $node + ->canBeEnabled() + ->children() + ->scalarNode('foo')->defaultValue('bar')->end() + ; + + $this->assertEquals(array('enabled' => false, 'foo' => 'bar'), $node->getNode()->getDefaultValue()); + } + + /** + * @dataProvider getEnableableNodeFixtures + */ + public function testTrueEnableEnabledNode($expected, $config, $message) + { + $processor = new Processor(); + $node = new ArrayNodeDefinition('root'); + $node + ->canBeEnabled() + ->children() + ->scalarNode('foo')->defaultValue('bar')->end() + ; + + $this->assertEquals( + $expected, + $processor->process($node->getNode(), $config), + $message + ); + } + + public function testCanBeDisabled() + { + $node = new ArrayNodeDefinition('root'); + $node->canBeDisabled(); + + $this->assertTrue($this->getField($node, 'addDefaults')); + $this->assertEquals(array('enabled' => false), $this->getField($node, 'falseEquivalent')); + $this->assertEquals(array('enabled' => true), $this->getField($node, 'trueEquivalent')); + $this->assertEquals(array('enabled' => true), $this->getField($node, 'nullEquivalent')); + + $nodeChildren = $this->getField($node, 'children'); + $this->assertArrayHasKey('enabled', $nodeChildren); + + $enabledNode = $nodeChildren['enabled']; + $this->assertTrue($this->getField($enabledNode, 'default')); + $this->assertTrue($this->getField($enabledNode, 'defaultValue')); + } + + public function testIgnoreExtraKeys() + { + $node = new ArrayNodeDefinition('root'); + + $this->assertFalse($this->getField($node, 'ignoreExtraKeys')); + + $result = $node->ignoreExtraKeys(); + + $this->assertEquals($node, $result); + $this->assertTrue($this->getField($node, 'ignoreExtraKeys')); + } + + public function testNormalizeKeys() + { + $node = new ArrayNodeDefinition('root'); + + $this->assertTrue($this->getField($node, 'normalizeKeys')); + + $result = $node->normalizeKeys(false); + + $this->assertEquals($node, $result); + $this->assertFalse($this->getField($node, 'normalizeKeys')); + } + + public function getEnableableNodeFixtures() + { + return array( + array(array('enabled' => true, 'foo' => 'bar'), array(true), 'true enables an enableable node'), + array(array('enabled' => true, 'foo' => 'bar'), array(null), 'null enables an enableable node'), + array(array('enabled' => true, 'foo' => 'bar'), array(array('enabled' => true)), 'An enableable node can be enabled'), + array(array('enabled' => true, 'foo' => 'baz'), array(array('foo' => 'baz')), 'any configuration enables an enableable node'), + array(array('enabled' => false, 'foo' => 'baz'), array(array('foo' => 'baz', 'enabled' => false)), 'An enableable node can be disabled'), + array(array('enabled' => false, 'foo' => 'bar'), array(false), 'false disables an enableable node'), + ); + } + + protected function getField($object, $field) + { + $reflection = new \ReflectionProperty($object, $field); + $reflection->setAccessible(true); + + return $reflection->getValue($object); + } +} diff --git a/vendor/symfony/config/Tests/Definition/Builder/EnumNodeDefinitionTest.php b/vendor/symfony/config/Tests/Definition/Builder/EnumNodeDefinitionTest.php new file mode 100644 index 000000000..0f09b78e7 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/Builder/EnumNodeDefinitionTest.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\EnumNodeDefinition; + +class EnumNodeDefinitionTest extends TestCase +{ + public function testWithOneValue() + { + $def = new EnumNodeDefinition('foo'); + $def->values(array('foo')); + + $node = $def->getNode(); + $this->assertEquals(array('foo'), $node->getValues()); + } + + public function testWithOneDistinctValue() + { + $def = new EnumNodeDefinition('foo'); + $def->values(array('foo', 'foo')); + + $node = $def->getNode(); + $this->assertEquals(array('foo'), $node->getValues()); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must call ->values() on enum nodes. + */ + public function testNoValuesPassed() + { + $def = new EnumNodeDefinition('foo'); + $def->getNode(); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage ->values() must be called with at least one value. + */ + public function testWithNoValues() + { + $def = new EnumNodeDefinition('foo'); + $def->values(array()); + } + + public function testGetNode() + { + $def = new EnumNodeDefinition('foo'); + $def->values(array('foo', 'bar')); + + $node = $def->getNode(); + $this->assertEquals(array('foo', 'bar'), $node->getValues()); + } +} diff --git a/vendor/symfony/config/Tests/Definition/Builder/ExprBuilderTest.php b/vendor/symfony/config/Tests/Definition/Builder/ExprBuilderTest.php new file mode 100644 index 000000000..1b90ebfeb --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/Builder/ExprBuilderTest.php @@ -0,0 +1,236 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +class ExprBuilderTest extends TestCase +{ + public function testAlwaysExpression() + { + $test = $this->getTestBuilder() + ->always($this->returnClosure('new_value')) + ->end(); + + $this->assertFinalizedValueIs('new_value', $test); + } + + public function testIfTrueExpression() + { + $test = $this->getTestBuilder() + ->ifTrue() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test, array('key' => true)); + + $test = $this->getTestBuilder() + ->ifTrue(function ($v) { return true; }) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + + $test = $this->getTestBuilder() + ->ifTrue(function ($v) { return false; }) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('value', $test); + } + + public function testIfStringExpression() + { + $test = $this->getTestBuilder() + ->ifString() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + + $test = $this->getTestBuilder() + ->ifString() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs(45, $test, array('key' => 45)); + } + + public function testIfNullExpression() + { + $test = $this->getTestBuilder() + ->ifNull() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test, array('key' => null)); + + $test = $this->getTestBuilder() + ->ifNull() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('value', $test); + } + + public function testIfArrayExpression() + { + $test = $this->getTestBuilder() + ->ifArray() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test, array('key' => array())); + + $test = $this->getTestBuilder() + ->ifArray() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('value', $test); + } + + public function testIfInArrayExpression() + { + $test = $this->getTestBuilder() + ->ifInArray(array('foo', 'bar', 'value')) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + + $test = $this->getTestBuilder() + ->ifInArray(array('foo', 'bar')) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('value', $test); + } + + public function testIfNotInArrayExpression() + { + $test = $this->getTestBuilder() + ->ifNotInArray(array('foo', 'bar')) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + + $test = $this->getTestBuilder() + ->ifNotInArray(array('foo', 'bar', 'value_from_config')) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + } + + public function testThenEmptyArrayExpression() + { + $test = $this->getTestBuilder() + ->ifString() + ->thenEmptyArray() + ->end(); + $this->assertFinalizedValueIs(array(), $test); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testThenInvalid() + { + $test = $this->getTestBuilder() + ->ifString() + ->thenInvalid('Invalid value') + ->end(); + $this->finalizeTestBuilder($test); + } + + public function testThenUnsetExpression() + { + $test = $this->getTestBuilder() + ->ifString() + ->thenUnset() + ->end(); + $this->assertEquals(array(), $this->finalizeTestBuilder($test)); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must specify an if part. + */ + public function testEndIfPartNotSpecified() + { + $this->getTestBuilder()->end(); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must specify a then part. + */ + public function testEndThenPartNotSpecified() + { + $builder = $this->getTestBuilder(); + $builder->ifPart = 'test'; + $builder->end(); + } + + /** + * Create a test treebuilder with a variable node, and init the validation. + * + * @return TreeBuilder + */ + protected function getTestBuilder() + { + $builder = new TreeBuilder(); + + return $builder + ->root('test') + ->children() + ->variableNode('key') + ->validate() + ; + } + + /** + * Close the validation process and finalize with the given config. + * + * @param TreeBuilder $testBuilder The tree builder to finalize + * @param array $config The config you want to use for the finalization, if nothing provided + * a simple array('key'=>'value') will be used + * + * @return array The finalized config values + */ + protected function finalizeTestBuilder($testBuilder, $config = null) + { + return $testBuilder + ->end() + ->end() + ->end() + ->buildTree() + ->finalize(null === $config ? array('key' => 'value') : $config) + ; + } + + /** + * Return a closure that will return the given value. + * + * @param mixed $val The value that the closure must return + * + * @return \Closure + */ + protected function returnClosure($val) + { + return function ($v) use ($val) { + return $val; + }; + } + + /** + * Assert that the given test builder, will return the given value. + * + * @param mixed $value The value to test + * @param TreeBuilder $treeBuilder The tree builder to finalize + * @param mixed $config The config values that new to be finalized + */ + protected function assertFinalizedValueIs($value, $treeBuilder, $config = null) + { + $this->assertEquals(array('key' => $value), $this->finalizeTestBuilder($treeBuilder, $config)); + } +} diff --git a/vendor/symfony/config/Tests/Definition/Builder/NodeBuilderTest.php b/vendor/symfony/config/Tests/Definition/Builder/NodeBuilderTest.php new file mode 100644 index 000000000..887756567 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/Builder/NodeBuilderTest.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder; +use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition; + +class NodeBuilderTest extends TestCase +{ + /** + * @expectedException \RuntimeException + */ + public function testThrowsAnExceptionWhenTryingToCreateANonRegisteredNodeType() + { + $builder = new BaseNodeBuilder(); + $builder->node('', 'foobar'); + } + + /** + * @expectedException \RuntimeException + */ + public function testThrowsAnExceptionWhenTheNodeClassIsNotFound() + { + $builder = new BaseNodeBuilder(); + $builder + ->setNodeClass('noclasstype', '\\foo\\bar\\noclass') + ->node('', 'noclasstype'); + } + + public function testAddingANewNodeType() + { + $class = __NAMESPACE__.'\\SomeNodeDefinition'; + + $builder = new BaseNodeBuilder(); + $node = $builder + ->setNodeClass('newtype', $class) + ->node('', 'newtype'); + + $this->assertInstanceOf($class, $node); + } + + public function testOverridingAnExistingNodeType() + { + $class = __NAMESPACE__.'\\SomeNodeDefinition'; + + $builder = new BaseNodeBuilder(); + $node = $builder + ->setNodeClass('variable', $class) + ->node('', 'variable'); + + $this->assertInstanceOf($class, $node); + } + + public function testNodeTypesAreNotCaseSensitive() + { + $builder = new BaseNodeBuilder(); + + $node1 = $builder->node('', 'VaRiAbLe'); + $node2 = $builder->node('', 'variable'); + + $this->assertInstanceOf(get_class($node1), $node2); + + $builder->setNodeClass('CuStOm', __NAMESPACE__.'\\SomeNodeDefinition'); + + $node1 = $builder->node('', 'CUSTOM'); + $node2 = $builder->node('', 'custom'); + + $this->assertInstanceOf(get_class($node1), $node2); + } + + public function testNumericNodeCreation() + { + $builder = new BaseNodeBuilder(); + + $node = $builder->integerNode('foo')->min(3)->max(5); + $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition', $node); + + $node = $builder->floatNode('bar')->min(3.0)->max(5.0); + $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\FloatNodeDefinition', $node); + } +} + +class SomeNodeDefinition extends BaseVariableNodeDefinition +{ +} diff --git a/vendor/symfony/config/Tests/Definition/Builder/NumericNodeDefinitionTest.php b/vendor/symfony/config/Tests/Definition/Builder/NumericNodeDefinitionTest.php new file mode 100644 index 000000000..efe0f1948 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/Builder/NumericNodeDefinitionTest.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition as NumericNodeDefinition; +use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition; +use Symfony\Component\Config\Definition\Builder\FloatNodeDefinition; + +class NumericNodeDefinitionTest extends TestCase +{ + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage You cannot define a min(4) as you already have a max(3) + */ + public function testIncoherentMinAssertion() + { + $def = new NumericNodeDefinition('foo'); + $def->max(3)->min(4); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage You cannot define a max(2) as you already have a min(3) + */ + public function testIncoherentMaxAssertion() + { + $node = new NumericNodeDefinition('foo'); + $node->min(3)->max(2); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value 4 is too small for path "foo". Should be greater than or equal to 5 + */ + public function testIntegerMinAssertion() + { + $def = new IntegerNodeDefinition('foo'); + $def->min(5)->getNode()->finalize(4); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value 4 is too big for path "foo". Should be less than or equal to 3 + */ + public function testIntegerMaxAssertion() + { + $def = new IntegerNodeDefinition('foo'); + $def->max(3)->getNode()->finalize(4); + } + + public function testIntegerValidMinMaxAssertion() + { + $def = new IntegerNodeDefinition('foo'); + $node = $def->min(3)->max(7)->getNode(); + $this->assertEquals(4, $node->finalize(4)); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value 400 is too small for path "foo". Should be greater than or equal to 500 + */ + public function testFloatMinAssertion() + { + $def = new FloatNodeDefinition('foo'); + $def->min(5E2)->getNode()->finalize(4e2); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value 4.3 is too big for path "foo". Should be less than or equal to 0.3 + */ + public function testFloatMaxAssertion() + { + $def = new FloatNodeDefinition('foo'); + $def->max(0.3)->getNode()->finalize(4.3); + } + + public function testFloatValidMinMaxAssertion() + { + $def = new FloatNodeDefinition('foo'); + $node = $def->min(3.0)->max(7e2)->getNode(); + $this->assertEquals(4.5, $node->finalize(4.5)); + } +} diff --git a/vendor/symfony/config/Tests/Definition/Builder/TreeBuilderTest.php b/vendor/symfony/config/Tests/Definition/Builder/TreeBuilderTest.php new file mode 100644 index 000000000..13304fae3 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/Builder/TreeBuilderTest.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder as CustomNodeBuilder; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +require __DIR__.'/../../Fixtures/Builder/NodeBuilder.php'; +require __DIR__.'/../../Fixtures/Builder/BarNodeDefinition.php'; +require __DIR__.'/../../Fixtures/Builder/VariableNodeDefinition.php'; + +class TreeBuilderTest extends TestCase +{ + public function testUsingACustomNodeBuilder() + { + $builder = new TreeBuilder(); + $root = $builder->root('custom', 'array', new CustomNodeBuilder()); + + $nodeBuilder = $root->children(); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder); + + $nodeBuilder = $nodeBuilder->arrayNode('deeper')->children(); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder); + } + + public function testOverrideABuiltInNodeType() + { + $builder = new TreeBuilder(); + $root = $builder->root('override', 'array', new CustomNodeBuilder()); + + $definition = $root->children()->variableNode('variable'); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition', $definition); + } + + public function testAddANodeType() + { + $builder = new TreeBuilder(); + $root = $builder->root('override', 'array', new CustomNodeBuilder()); + + $definition = $root->children()->barNode('variable'); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\BarNodeDefinition', $definition); + } + + public function testCreateABuiltInNodeTypeWithACustomNodeBuilder() + { + $builder = new TreeBuilder(); + $root = $builder->root('builtin', 'array', new CustomNodeBuilder()); + + $definition = $root->children()->booleanNode('boolean'); + + $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition', $definition); + } + + public function testPrototypedArrayNodeUseTheCustomNodeBuilder() + { + $builder = new TreeBuilder(); + $root = $builder->root('override', 'array', new CustomNodeBuilder()); + + $root->prototype('bar')->end(); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\BarNode', $root->getNode(true)->getPrototype()); + } + + public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren() + { + $builder = new TreeBuilder(); + + $builder->root('propagation') + ->children() + ->setNodeClass('extended', 'Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition') + ->node('foo', 'extended')->end() + ->arrayNode('child') + ->children() + ->node('foo', 'extended') + ->end() + ->end() + ->end() + ->end(); + + $node = $builder->buildTree(); + $children = $node->getChildren(); + + $this->assertInstanceOf('Symfony\Component\Config\Definition\BooleanNode', $children['foo']); + + $childChildren = $children['child']->getChildren(); + + $this->assertInstanceOf('Symfony\Component\Config\Definition\BooleanNode', $childChildren['foo']); + } + + public function testDefinitionInfoGetsTransferredToNode() + { + $builder = new TreeBuilder(); + + $builder->root('test')->info('root info') + ->children() + ->node('child', 'variable')->info('child info')->defaultValue('default') + ->end() + ->end(); + + $tree = $builder->buildTree(); + $children = $tree->getChildren(); + + $this->assertEquals('root info', $tree->getInfo()); + $this->assertEquals('child info', $children['child']->getInfo()); + } + + public function testDefinitionExampleGetsTransferredToNode() + { + $builder = new TreeBuilder(); + + $builder->root('test') + ->example(array('key' => 'value')) + ->children() + ->node('child', 'variable')->info('child info')->defaultValue('default')->example('example') + ->end() + ->end(); + + $tree = $builder->buildTree(); + $children = $tree->getChildren(); + + $this->assertInternalType('array', $tree->getExample()); + $this->assertEquals('example', $children['child']->getExample()); + } +} diff --git a/vendor/symfony/config/Tests/Definition/Dumper/XmlReferenceDumperTest.php b/vendor/symfony/config/Tests/Definition/Dumper/XmlReferenceDumperTest.php new file mode 100644 index 000000000..61f5d3c4c --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/Dumper/XmlReferenceDumperTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Dumper\XmlReferenceDumper; +use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration; + +class XmlReferenceDumperTest extends TestCase +{ + public function testDumper() + { + $configuration = new ExampleConfiguration(); + + $dumper = new XmlReferenceDumper(); + $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration)); + } + + public function testNamespaceDumper() + { + $configuration = new ExampleConfiguration(); + + $dumper = new XmlReferenceDumper(); + $this->assertEquals(str_replace('http://example.org/schema/dic/acme_root', 'http://symfony.com/schema/dic/symfony', $this->getConfigurationAsString()), $dumper->dump($configuration, 'http://symfony.com/schema/dic/symfony')); + } + + private function getConfigurationAsString() + { + return str_replace("\n", PHP_EOL, <<<'EOL' + + + + + + + + + + + + scalar value + + + + + + +EOL + ); + } +} diff --git a/vendor/symfony/config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/vendor/symfony/config/Tests/Definition/Dumper/YamlReferenceDumperTest.php new file mode 100644 index 000000000..9dda41554 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/Dumper/YamlReferenceDumperTest.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper; +use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration; + +class YamlReferenceDumperTest extends TestCase +{ + public function testDumper() + { + $configuration = new ExampleConfiguration(); + + $dumper = new YamlReferenceDumper(); + + $this->assertContains($this->getConfigurationAsString(), $dumper->dump($configuration)); + $this->markTestIncomplete('The Yaml Dumper currently does not support prototyped arrays'); + } + + private function getConfigurationAsString() + { + return <<<'EOL' +acme_root: + boolean: true + scalar_empty: ~ + scalar_null: null + scalar_true: true + scalar_false: false + scalar_default: default + scalar_array_empty: [] + scalar_array_defaults: + + # Defaults: + - elem1 + - elem2 + scalar_required: ~ # Required + node_with_a_looong_name: ~ + enum_with_default: this # One of "this"; "that" + enum: ~ # One of "this"; "that" + + # some info + array: + child1: ~ + child2: ~ + + # this is a long + # multi-line info text + # which should be indented + child3: ~ # Example: example setting + parameters: + + # Prototype: Parameter name + name: ~ +EOL; + } +} diff --git a/vendor/symfony/config/Tests/Definition/EnumNodeTest.php b/vendor/symfony/config/Tests/Definition/EnumNodeTest.php new file mode 100644 index 000000000..e3e7ef059 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/EnumNodeTest.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\EnumNode; + +class EnumNodeTest extends TestCase +{ + public function testFinalizeValue() + { + $node = new EnumNode('foo', null, array('foo', 'bar')); + $this->assertSame('foo', $node->finalize('foo')); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage $values must contain at least one element. + */ + public function testConstructionWithNoValues() + { + new EnumNode('foo', null, array()); + } + + public function testConstructionWithOneValue() + { + $node = new EnumNode('foo', null, array('foo')); + $this->assertSame('foo', $node->finalize('foo')); + } + + public function testConstructionWithOneDistinctValue() + { + $node = new EnumNode('foo', null, array('foo', 'foo')); + $this->assertSame('foo', $node->finalize('foo')); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The value "foobar" is not allowed for path "foo". Permissible values: "foo", "bar" + */ + public function testFinalizeWithInvalidValue() + { + $node = new EnumNode('foo', null, array('foo', 'bar')); + $node->finalize('foobar'); + } +} diff --git a/vendor/symfony/config/Tests/Definition/FinalizationTest.php b/vendor/symfony/config/Tests/Definition/FinalizationTest.php new file mode 100644 index 000000000..733f60085 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/FinalizationTest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Config\Definition\NodeInterface; + +class FinalizationTest extends TestCase +{ + public function testUnsetKeyWithDeepHierarchy() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('config', 'array') + ->children() + ->node('level1', 'array') + ->canBeUnset() + ->children() + ->node('level2', 'array') + ->canBeUnset() + ->children() + ->node('somevalue', 'scalar')->end() + ->node('anothervalue', 'scalar')->end() + ->end() + ->end() + ->node('level1_scalar', 'scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = array( + 'level1' => array( + 'level2' => array( + 'somevalue' => 'foo', + 'anothervalue' => 'bar', + ), + 'level1_scalar' => 'foo', + ), + ); + + $b = array( + 'level1' => array( + 'level2' => false, + ), + ); + + $this->assertEquals(array( + 'level1' => array( + 'level1_scalar' => 'foo', + ), + ), $this->process($tree, array($a, $b))); + } + + protected function process(NodeInterface $tree, array $configs) + { + $processor = new Processor(); + + return $processor->process($tree, $configs); + } +} diff --git a/vendor/symfony/config/Tests/Definition/FloatNodeTest.php b/vendor/symfony/config/Tests/Definition/FloatNodeTest.php new file mode 100644 index 000000000..b7ec12fa7 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/FloatNodeTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\FloatNode; + +class FloatNodeTest extends TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new FloatNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + /** + * @dataProvider getValidValues + * + * @param int $value + */ + public function testValidNonEmptyValues($value) + { + $node = new FloatNode('test'); + $node->setAllowEmptyValue(false); + + $this->assertSame($value, $node->finalize($value)); + } + + public function getValidValues() + { + return array( + array(1798.0), + array(-678.987), + array(12.56E45), + array(0.0), + // Integer are accepted too, they will be cast + array(17), + array(-10), + array(0), + ); + } + + /** + * @dataProvider getInvalidValues + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $node = new FloatNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return array( + array(null), + array(''), + array('foo'), + array(true), + array(false), + array(array()), + array(array('foo' => 'bar')), + array(new \stdClass()), + ); + } +} diff --git a/vendor/symfony/config/Tests/Definition/IntegerNodeTest.php b/vendor/symfony/config/Tests/Definition/IntegerNodeTest.php new file mode 100644 index 000000000..55e8a137b --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/IntegerNodeTest.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\IntegerNode; + +class IntegerNodeTest extends TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new IntegerNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + /** + * @dataProvider getValidValues + * + * @param int $value + */ + public function testValidNonEmptyValues($value) + { + $node = new IntegerNode('test'); + $node->setAllowEmptyValue(false); + + $this->assertSame($value, $node->finalize($value)); + } + + public function getValidValues() + { + return array( + array(1798), + array(-678), + array(0), + ); + } + + /** + * @dataProvider getInvalidValues + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $node = new IntegerNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return array( + array(null), + array(''), + array('foo'), + array(true), + array(false), + array(0.0), + array(0.1), + array(array()), + array(array('foo' => 'bar')), + array(new \stdClass()), + ); + } +} diff --git a/vendor/symfony/config/Tests/Definition/MergeTest.php b/vendor/symfony/config/Tests/Definition/MergeTest.php new file mode 100644 index 000000000..e539e25f3 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/MergeTest.php @@ -0,0 +1,196 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +class MergeTest extends TestCase +{ + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException + */ + public function testForbiddenOverwrite() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->children() + ->node('foo', 'scalar') + ->cannotBeOverwritten() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = array( + 'foo' => 'bar', + ); + + $b = array( + 'foo' => 'moo', + ); + + $tree->merge($a, $b); + } + + public function testUnsetKey() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->children() + ->node('foo', 'scalar')->end() + ->node('bar', 'scalar')->end() + ->node('unsettable', 'array') + ->canBeUnset() + ->children() + ->node('foo', 'scalar')->end() + ->node('bar', 'scalar')->end() + ->end() + ->end() + ->node('unsetted', 'array') + ->canBeUnset() + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = array( + 'foo' => 'bar', + 'unsettable' => array( + 'foo' => 'a', + 'bar' => 'b', + ), + 'unsetted' => false, + ); + + $b = array( + 'foo' => 'moo', + 'bar' => 'b', + 'unsettable' => false, + 'unsetted' => array('a', 'b'), + ); + + $this->assertEquals(array( + 'foo' => 'moo', + 'bar' => 'b', + 'unsettable' => false, + 'unsetted' => array('a', 'b'), + ), $tree->merge($a, $b)); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testDoesNotAllowNewKeysInSubsequentConfigs() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('config', 'array') + ->children() + ->node('test', 'array') + ->disallowNewKeysInSubsequentConfigs() + ->useAttributeAsKey('key') + ->prototype('array') + ->children() + ->node('value', 'scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree(); + + $a = array( + 'test' => array( + 'a' => array('value' => 'foo'), + ), + ); + + $b = array( + 'test' => array( + 'b' => array('value' => 'foo'), + ), + ); + + $tree->merge($a, $b); + } + + public function testPerformsNoDeepMerging() + { + $tb = new TreeBuilder(); + + $tree = $tb + ->root('config', 'array') + ->children() + ->node('no_deep_merging', 'array') + ->performNoDeepMerging() + ->children() + ->node('foo', 'scalar')->end() + ->node('bar', 'scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = array( + 'no_deep_merging' => array( + 'foo' => 'a', + 'bar' => 'b', + ), + ); + + $b = array( + 'no_deep_merging' => array( + 'c' => 'd', + ), + ); + + $this->assertEquals(array( + 'no_deep_merging' => array( + 'c' => 'd', + ), + ), $tree->merge($a, $b)); + } + + public function testPrototypeWithoutAKeyAttribute() + { + $tb = new TreeBuilder(); + + $tree = $tb + ->root('config', 'array') + ->children() + ->arrayNode('append_elements') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = array( + 'append_elements' => array('a', 'b'), + ); + + $b = array( + 'append_elements' => array('c', 'd'), + ); + + $this->assertEquals(array('append_elements' => array('a', 'b', 'c', 'd')), $tree->merge($a, $b)); + } +} diff --git a/vendor/symfony/config/Tests/Definition/NormalizationTest.php b/vendor/symfony/config/Tests/Definition/NormalizationTest.php new file mode 100644 index 000000000..f011f5422 --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/NormalizationTest.php @@ -0,0 +1,230 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\NodeInterface; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +class NormalizationTest extends TestCase +{ + /** + * @dataProvider getEncoderTests + */ + public function testNormalizeEncoders($denormalized) + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root_name', 'array') + ->fixXmlConfig('encoder') + ->children() + ->node('encoders', 'array') + ->useAttributeAsKey('class') + ->prototype('array') + ->beforeNormalization()->ifString()->then(function ($v) { return array('algorithm' => $v); })->end() + ->children() + ->node('algorithm', 'scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $normalized = array( + 'encoders' => array( + 'foo' => array('algorithm' => 'plaintext'), + ), + ); + + $this->assertNormalized($tree, $denormalized, $normalized); + } + + public function getEncoderTests() + { + $configs = array(); + + // XML + $configs[] = array( + 'encoder' => array( + array('class' => 'foo', 'algorithm' => 'plaintext'), + ), + ); + + // XML when only one element of this type + $configs[] = array( + 'encoder' => array('class' => 'foo', 'algorithm' => 'plaintext'), + ); + + // YAML/PHP + $configs[] = array( + 'encoders' => array( + array('class' => 'foo', 'algorithm' => 'plaintext'), + ), + ); + + // YAML/PHP + $configs[] = array( + 'encoders' => array( + 'foo' => 'plaintext', + ), + ); + + // YAML/PHP + $configs[] = array( + 'encoders' => array( + 'foo' => array('algorithm' => 'plaintext'), + ), + ); + + return array_map(function ($v) { + return array($v); + }, $configs); + } + + /** + * @dataProvider getAnonymousKeysTests + */ + public function testAnonymousKeysArray($denormalized) + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->children() + ->node('logout', 'array') + ->fixXmlConfig('handler') + ->children() + ->node('handlers', 'array') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $normalized = array('logout' => array('handlers' => array('a', 'b', 'c'))); + + $this->assertNormalized($tree, $denormalized, $normalized); + } + + public function getAnonymousKeysTests() + { + $configs = array(); + + $configs[] = array( + 'logout' => array( + 'handlers' => array('a', 'b', 'c'), + ), + ); + + $configs[] = array( + 'logout' => array( + 'handler' => array('a', 'b', 'c'), + ), + ); + + return array_map(function ($v) { return array($v); }, $configs); + } + + /** + * @dataProvider getNumericKeysTests + */ + public function testNumericKeysAsAttributes($denormalized) + { + $normalized = array( + 'thing' => array(42 => array('foo', 'bar'), 1337 => array('baz', 'qux')), + ); + + $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, $normalized); + } + + public function getNumericKeysTests() + { + $configs = array(); + + $configs[] = array( + 'thing' => array( + 42 => array('foo', 'bar'), 1337 => array('baz', 'qux'), + ), + ); + + $configs[] = array( + 'thing' => array( + array('foo', 'bar', 'id' => 42), array('baz', 'qux', 'id' => 1337), + ), + ); + + return array_map(function ($v) { return array($v); }, $configs); + } + + /** + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage The attribute "id" must be set for path "root.thing". + */ + public function testNonAssociativeArrayThrowsExceptionIfAttributeNotSet() + { + $denormalized = array( + 'thing' => array( + array('foo', 'bar'), array('baz', 'qux'), + ), + ); + + $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, array()); + } + + public function testAssociativeArrayPreserveKeys() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->prototype('array') + ->children() + ->node('foo', 'scalar')->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $data = array('first' => array('foo' => 'bar')); + + $this->assertNormalized($tree, $data, $data); + } + + public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized) + { + self::assertSame($normalized, $tree->normalize($denormalized)); + } + + private function getNumericKeysTestTree() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->children() + ->node('thing', 'array') + ->useAttributeAsKey('id') + ->prototype('array') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + return $tree; + } +} diff --git a/vendor/symfony/config/Tests/Definition/PrototypedArrayNodeTest.php b/vendor/symfony/config/Tests/Definition/PrototypedArrayNodeTest.php new file mode 100644 index 000000000..1a5de41cc --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/PrototypedArrayNodeTest.php @@ -0,0 +1,342 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\PrototypedArrayNode; +use Symfony\Component\Config\Definition\ArrayNode; +use Symfony\Component\Config\Definition\ScalarNode; +use Symfony\Component\Config\Definition\VariableNode; + +class PrototypedArrayNodeTest extends TestCase +{ + public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes() + { + $node = new PrototypedArrayNode('root'); + $prototype = new ArrayNode(null, $node); + $node->setPrototype($prototype); + $this->assertEmpty($node->getDefaultValue()); + } + + public function testGetDefaultValueReturnsDefaultValueForPrototypes() + { + $node = new PrototypedArrayNode('root'); + $prototype = new ArrayNode(null, $node); + $node->setPrototype($prototype); + $node->setDefaultValue(array('test')); + $this->assertEquals(array('test'), $node->getDefaultValue()); + } + + // a remapped key (e.g. "mapping" -> "mappings") should be unset after being used + public function testRemappedKeysAreUnset() + { + $node = new ArrayNode('root'); + $mappingsNode = new PrototypedArrayNode('mappings'); + $node->addChild($mappingsNode); + + // each item under mappings is just a scalar + $prototype = new ScalarNode(null, $mappingsNode); + $mappingsNode->setPrototype($prototype); + + $remappings = array(); + $remappings[] = array('mapping', 'mappings'); + $node->setXmlRemappings($remappings); + + $normalized = $node->normalize(array('mapping' => array('foo', 'bar'))); + $this->assertEquals(array('mappings' => array('foo', 'bar')), $normalized); + } + + /** + * Tests that when a key attribute is mapped, that key is removed from the array. + * + * + * + * + * The above should finally be mapped to an array that looks like this + * (because "id" is the key attribute). + * + * array( + * 'things' => array( + * 'option1' => 'foo', + * 'option2' => 'bar', + * ) + * ) + */ + public function testMappedAttributeKeyIsRemoved() + { + $node = new PrototypedArrayNode('root'); + $node->setKeyAttribute('id', true); + + // each item under the root is an array, with one scalar item + $prototype = new ArrayNode(null, $node); + $prototype->addChild(new ScalarNode('foo')); + $node->setPrototype($prototype); + + $children = array(); + $children[] = array('id' => 'item_name', 'foo' => 'bar'); + $normalized = $node->normalize($children); + + $expected = array(); + $expected['item_name'] = array('foo' => 'bar'); + $this->assertEquals($expected, $normalized); + } + + /** + * Tests the opposite of the testMappedAttributeKeyIsRemoved because + * the removal can be toggled with an option. + */ + public function testMappedAttributeKeyNotRemoved() + { + $node = new PrototypedArrayNode('root'); + $node->setKeyAttribute('id', false); + + // each item under the root is an array, with two scalar items + $prototype = new ArrayNode(null, $node); + $prototype->addChild(new ScalarNode('foo')); + $prototype->addChild(new ScalarNode('id')); // the key attribute will remain + $node->setPrototype($prototype); + + $children = array(); + $children[] = array('id' => 'item_name', 'foo' => 'bar'); + $normalized = $node->normalize($children); + + $expected = array(); + $expected['item_name'] = array('id' => 'item_name', 'foo' => 'bar'); + $this->assertEquals($expected, $normalized); + } + + public function testAddDefaultChildren() + { + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setAddChildrenIfNoneSet(); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setKeyAttribute('foobar'); + $node->setAddChildrenIfNoneSet(); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(array('defaults' => array('foo' => 'bar')), $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setKeyAttribute('foobar'); + $node->setAddChildrenIfNoneSet('defaultkey'); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setKeyAttribute('foobar'); + $node->setAddChildrenIfNoneSet(array('defaultkey')); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setKeyAttribute('foobar'); + $node->setAddChildrenIfNoneSet(array('dk1', 'dk2')); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(array('dk1' => array('foo' => 'bar'), 'dk2' => array('foo' => 'bar')), $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setAddChildrenIfNoneSet(array(5, 6)); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(array(0 => array('foo' => 'bar'), 1 => array('foo' => 'bar')), $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setAddChildrenIfNoneSet(2); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(array(array('foo' => 'bar'), array('foo' => 'bar')), $node->getDefaultValue()); + } + + public function testDefaultChildrenWinsOverDefaultValue() + { + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setAddChildrenIfNoneSet(); + $node->setDefaultValue(array('bar' => 'foo')); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue()); + } + + protected function getPrototypeNodeWithDefaultChildren() + { + $node = new PrototypedArrayNode('root'); + $prototype = new ArrayNode(null, $node); + $child = new ScalarNode('foo'); + $child->setDefaultValue('bar'); + $prototype->addChild($child); + $prototype->setAddIfNotSet(true); + $node->setPrototype($prototype); + + return $node; + } + + /** + * Tests that when a key attribute is mapped, that key is removed from the array. + * And if only 'value' element is left in the array, it will replace its wrapper array. + * + * + * + * + * The above should finally be mapped to an array that looks like this + * (because "id" is the key attribute). + * + * array( + * 'things' => array( + * 'option1' => 'value1' + * ) + * ) + * + * It's also possible to mix 'value-only' and 'non-value-only' elements in the array. + * + * + * + * + * The above should finally be mapped to an array as follows + * + * array( + * 'things' => array( + * 'option1' => 'value1', + * 'option2' => array( + * 'value' => 'value2', + * 'foo' => 'foo2' + * ) + * ) + * ) + * + * The 'value' element can also be ArrayNode: + * + * + * + * + * + * The above should be finally be mapped to an array as follows + * + * array( + * 'things' => array( + * 'option1' => array( + * 'foo' => 'foo1', + * 'bar' => 'bar1' + * ) + * ) + * ) + * + * If using VariableNode for value node, it's also possible to mix different types of value nodes: + * + * + * + * + * + * The above should be finally mapped to an array as follows + * + * array( + * 'things' => array( + * 'option1' => array( + * 'foo' => 'foo1', + * 'bar' => 'bar1' + * ), + * 'option2' => 'value2' + * ) + * ) + * + * + * @dataProvider getDataForKeyRemovedLeftValueOnly + */ + public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $expected) + { + $node = new PrototypedArrayNode('root'); + $node->setKeyAttribute('id', true); + + // each item under the root is an array, with one scalar item + $prototype = new ArrayNode(null, $node); + $prototype->addChild(new ScalarNode('id')); + $prototype->addChild(new ScalarNode('foo')); + $prototype->addChild($value); + $node->setPrototype($prototype); + + $normalized = $node->normalize($children); + $this->assertEquals($expected, $normalized); + } + + public function getDataForKeyRemovedLeftValueOnly() + { + $scalarValue = new ScalarNode('value'); + + $arrayValue = new ArrayNode('value'); + $arrayValue->addChild(new ScalarNode('foo')); + $arrayValue->addChild(new ScalarNode('bar')); + + $variableValue = new VariableNode('value'); + + return array( + array( + $scalarValue, + array( + array('id' => 'option1', 'value' => 'value1'), + ), + array('option1' => 'value1'), + ), + + array( + $scalarValue, + array( + array('id' => 'option1', 'value' => 'value1'), + array('id' => 'option2', 'value' => 'value2', 'foo' => 'foo2'), + ), + array( + 'option1' => 'value1', + 'option2' => array('value' => 'value2', 'foo' => 'foo2'), + ), + ), + + array( + $arrayValue, + array( + array( + 'id' => 'option1', + 'value' => array('foo' => 'foo1', 'bar' => 'bar1'), + ), + ), + array( + 'option1' => array('foo' => 'foo1', 'bar' => 'bar1'), + ), + ), + + array($variableValue, + array( + array( + 'id' => 'option1', 'value' => array('foo' => 'foo1', 'bar' => 'bar1'), + ), + array('id' => 'option2', 'value' => 'value2'), + ), + array( + 'option1' => array('foo' => 'foo1', 'bar' => 'bar1'), + 'option2' => 'value2', + ), + ), + ); + } +} diff --git a/vendor/symfony/config/Tests/Definition/ScalarNodeTest.php b/vendor/symfony/config/Tests/Definition/ScalarNodeTest.php new file mode 100644 index 000000000..a402a61ef --- /dev/null +++ b/vendor/symfony/config/Tests/Definition/ScalarNodeTest.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\ScalarNode; + +class ScalarNodeTest extends TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new ScalarNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + public function getValidValues() + { + return array( + array(false), + array(true), + array(null), + array(''), + array('foo'), + array(0), + array(1), + array(0.0), + array(0.1), + ); + } + + /** + * @dataProvider getInvalidValues + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $node = new ScalarNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return array( + array(array()), + array(array('foo' => 'bar')), + array(new \stdClass()), + ); + } + + public function testNormalizeThrowsExceptionWithoutHint() + { + $node = new ScalarNode('test'); + + if (method_exists($this, 'expectException')) { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); + $this->expectExceptionMessage('Invalid type for path "test". Expected scalar, but got array.'); + } else { + $this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', 'Invalid type for path "test". Expected scalar, but got array.'); + } + + $node->normalize(array()); + } + + public function testNormalizeThrowsExceptionWithErrorMessage() + { + $node = new ScalarNode('test'); + $node->setInfo('"the test value"'); + + if (method_exists($this, 'expectException')) { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); + $this->expectExceptionMessage("Invalid type for path \"test\". Expected scalar, but got array.\nHint: \"the test value\""); + } else { + $this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', "Invalid type for path \"test\". Expected scalar, but got array.\nHint: \"the test value\""); + } + + $node->normalize(array()); + } + + /** + * @dataProvider getValidNonEmptyValues + * + * @param mixed $value + */ + public function testValidNonEmptyValues($value) + { + $node = new ScalarNode('test'); + $node->setAllowEmptyValue(false); + + $this->assertSame($value, $node->finalize($value)); + } + + public function getValidNonEmptyValues() + { + return array( + array(false), + array(true), + array('foo'), + array(0), + array(1), + array(0.0), + array(0.1), + ); + } + + /** + * @dataProvider getEmptyValues + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * + * @param mixed $value + */ + public function testNotAllowedEmptyValuesThrowException($value) + { + $node = new ScalarNode('test'); + $node->setAllowEmptyValue(false); + $node->finalize($value); + } + + public function getEmptyValues() + { + return array( + array(null), + array(''), + ); + } +} diff --git a/vendor/symfony/config/Tests/Exception/FileLoaderLoadExceptionTest.php b/vendor/symfony/config/Tests/Exception/FileLoaderLoadExceptionTest.php new file mode 100644 index 000000000..c1ad9150e --- /dev/null +++ b/vendor/symfony/config/Tests/Exception/FileLoaderLoadExceptionTest.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Exception; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Exception\FileLoaderLoadException; + +class FileLoaderLoadExceptionTest extends TestCase +{ + public function testMessageCannotLoadResource() + { + $exception = new FileLoaderLoadException('resource', null); + $this->assertEquals('Cannot load resource "resource".', $exception->getMessage()); + } + + public function testMessageCannotImportResourceFromSource() + { + $exception = new FileLoaderLoadException('resource', 'sourceResource'); + $this->assertEquals('Cannot import resource "resource" from "sourceResource".', $exception->getMessage()); + } + + public function testMessageCannotImportBundleResource() + { + $exception = new FileLoaderLoadException('@resource', 'sourceResource'); + $this->assertEquals( + 'Cannot import resource "@resource" from "sourceResource". '. + 'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class. '. + 'If the bundle is registered, make sure the bundle path "@resource" is not empty.', + $exception->getMessage() + ); + } + + public function testMessageHasPreviousErrorWithDotAndUnableToLoad() + { + $exception = new FileLoaderLoadException( + 'resource', + null, + null, + new \Exception('There was a previous error with an ending dot.') + ); + $this->assertEquals( + 'There was a previous error with an ending dot in resource (which is loaded in resource "resource").', + $exception->getMessage() + ); + } + + public function testMessageHasPreviousErrorWithoutDotAndUnableToLoad() + { + $exception = new FileLoaderLoadException( + 'resource', + null, + null, + new \Exception('There was a previous error with no ending dot') + ); + $this->assertEquals( + 'There was a previous error with no ending dot in resource (which is loaded in resource "resource").', + $exception->getMessage() + ); + } + + public function testMessageHasPreviousErrorAndUnableToLoadBundle() + { + $exception = new FileLoaderLoadException( + '@resource', + null, + null, + new \Exception('There was a previous error with an ending dot.') + ); + $this->assertEquals( + 'There was a previous error with an ending dot in @resource '. + '(which is loaded in resource "@resource"). '. + 'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class. '. + 'If the bundle is registered, make sure the bundle path "@resource" is not empty.', + $exception->getMessage() + ); + } +} diff --git a/vendor/symfony/config/Tests/FileLocatorTest.php b/vendor/symfony/config/Tests/FileLocatorTest.php new file mode 100644 index 000000000..5b69f4526 --- /dev/null +++ b/vendor/symfony/config/Tests/FileLocatorTest.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; + +class FileLocatorTest extends TestCase +{ + /** + * @dataProvider getIsAbsolutePathTests + */ + public function testIsAbsolutePath($path) + { + $loader = new FileLocator(array()); + $r = new \ReflectionObject($loader); + $m = $r->getMethod('isAbsolutePath'); + $m->setAccessible(true); + + $this->assertTrue($m->invoke($loader, $path), '->isAbsolutePath() returns true for an absolute path'); + } + + public function getIsAbsolutePathTests() + { + return array( + array('/foo.xml'), + array('c:\\\\foo.xml'), + array('c:/foo.xml'), + array('\\server\\foo.xml'), + array('https://server/foo.xml'), + array('phar://server/foo.xml'), + ); + } + + public function testLocate() + { + $loader = new FileLocator(__DIR__.'/Fixtures'); + + $this->assertEquals( + __DIR__.DIRECTORY_SEPARATOR.'FileLocatorTest.php', + $loader->locate('FileLocatorTest.php', __DIR__), + '->locate() returns the absolute filename if the file exists in the given path' + ); + + $this->assertEquals( + __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', + $loader->locate('foo.xml', __DIR__), + '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor' + ); + + $this->assertEquals( + __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', + $loader->locate(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__), + '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor' + ); + + $loader = new FileLocator(array(__DIR__.'/Fixtures', __DIR__.'/Fixtures/Again')); + + $this->assertEquals( + array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'), + $loader->locate('foo.xml', __DIR__, false), + '->locate() returns an array of absolute filenames' + ); + + $this->assertEquals( + array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'), + $loader->locate('foo.xml', __DIR__.'/Fixtures', false), + '->locate() returns an array of absolute filenames' + ); + + $loader = new FileLocator(__DIR__.'/Fixtures/Again'); + + $this->assertEquals( + array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'), + $loader->locate('foo.xml', __DIR__.'/Fixtures', false), + '->locate() returns an array of absolute filenames' + ); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The file "foobar.xml" does not exist + */ + public function testLocateThrowsAnExceptionIfTheFileDoesNotExists() + { + $loader = new FileLocator(array(__DIR__.'/Fixtures')); + + $loader->locate('foobar.xml', __DIR__); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testLocateThrowsAnExceptionIfTheFileDoesNotExistsInAbsolutePath() + { + $loader = new FileLocator(array(__DIR__.'/Fixtures')); + + $loader->locate(__DIR__.'/Fixtures/foobar.xml', __DIR__); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage An empty file name is not valid to be located. + */ + public function testLocateEmpty() + { + $loader = new FileLocator(array(__DIR__.'/Fixtures')); + + $loader->locate(null, __DIR__); + } +} diff --git a/vendor/symfony/config/Tests/Fixtures/Again/foo.xml b/vendor/symfony/config/Tests/Fixtures/Again/foo.xml new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/config/Tests/Fixtures/BarNode.php b/vendor/symfony/config/Tests/Fixtures/BarNode.php new file mode 100644 index 000000000..0b9c32ded --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/BarNode.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Fixtures; + +use Symfony\Component\Config\Definition\ArrayNode; + +class BarNode extends ArrayNode +{ +} diff --git a/vendor/symfony/config/Tests/Fixtures/Builder/BarNodeDefinition.php b/vendor/symfony/config/Tests/Fixtures/Builder/BarNodeDefinition.php new file mode 100644 index 000000000..0d46f3d2c --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/Builder/BarNodeDefinition.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\Config\Tests\Fixtures\BarNode; + +class BarNodeDefinition extends NodeDefinition +{ + protected function createNode() + { + return new BarNode($this->name); + } +} diff --git a/vendor/symfony/config/Tests/Fixtures/Builder/NodeBuilder.php b/vendor/symfony/config/Tests/Fixtures/Builder/NodeBuilder.php new file mode 100644 index 000000000..aa5986311 --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/Builder/NodeBuilder.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder; + +class NodeBuilder extends BaseNodeBuilder +{ + public function barNode($name) + { + return $this->node($name, 'bar'); + } + + protected function getNodeClass($type) + { + switch ($type) { + case 'variable': + return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition'; + case 'bar': + return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition'; + default: + return parent::getNodeClass($type); + } + } +} diff --git a/vendor/symfony/config/Tests/Fixtures/Builder/VariableNodeDefinition.php b/vendor/symfony/config/Tests/Fixtures/Builder/VariableNodeDefinition.php new file mode 100644 index 000000000..1017880c1 --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/Builder/VariableNodeDefinition.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition; + +class VariableNodeDefinition extends BaseVariableNodeDefinition +{ +} diff --git a/vendor/symfony/config/Tests/Fixtures/Configuration/ExampleConfiguration.php b/vendor/symfony/config/Tests/Fixtures/Configuration/ExampleConfiguration.php new file mode 100644 index 000000000..139b011af --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/Configuration/ExampleConfiguration.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Fixtures\Configuration; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +class ExampleConfiguration implements ConfigurationInterface +{ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('acme_root'); + + $rootNode + ->fixXmlConfig('parameter') + ->fixXmlConfig('connection') + ->children() + ->booleanNode('boolean')->defaultTrue()->end() + ->scalarNode('scalar_empty')->end() + ->scalarNode('scalar_null')->defaultNull()->end() + ->scalarNode('scalar_true')->defaultTrue()->end() + ->scalarNode('scalar_false')->defaultFalse()->end() + ->scalarNode('scalar_default')->defaultValue('default')->end() + ->scalarNode('scalar_array_empty')->defaultValue(array())->end() + ->scalarNode('scalar_array_defaults')->defaultValue(array('elem1', 'elem2'))->end() + ->scalarNode('scalar_required')->isRequired()->end() + ->scalarNode('node_with_a_looong_name')->end() + ->enumNode('enum_with_default')->values(array('this', 'that'))->defaultValue('this')->end() + ->enumNode('enum')->values(array('this', 'that'))->end() + ->arrayNode('array') + ->info('some info') + ->canBeUnset() + ->children() + ->scalarNode('child1')->end() + ->scalarNode('child2')->end() + ->scalarNode('child3') + ->info( + "this is a long\n". + "multi-line info text\n". + 'which should be indented' + ) + ->example('example setting') + ->end() + ->end() + ->end() + ->arrayNode('parameters') + ->useAttributeAsKey('name') + ->prototype('scalar')->info('Parameter name')->end() + ->end() + ->arrayNode('connections') + ->prototype('array') + ->children() + ->scalarNode('user')->end() + ->scalarNode('pass')->end() + ->end() + ->end() + ->end() + ->end() + ; + + return $treeBuilder; + } +} diff --git a/vendor/symfony/config/Tests/Fixtures/Util/document_type.xml b/vendor/symfony/config/Tests/Fixtures/Util/document_type.xml new file mode 100644 index 000000000..4c2522826 --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/Util/document_type.xml @@ -0,0 +1,3 @@ + +]> + diff --git a/vendor/symfony/config/Tests/Fixtures/Util/invalid.xml b/vendor/symfony/config/Tests/Fixtures/Util/invalid.xml new file mode 100644 index 000000000..a07af9fd8 --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/Util/invalid.xml @@ -0,0 +1,2 @@ + + diff --git a/vendor/symfony/config/Tests/Fixtures/Util/invalid_schema.xml b/vendor/symfony/config/Tests/Fixtures/Util/invalid_schema.xml new file mode 100644 index 000000000..e2725a2c2 --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/Util/invalid_schema.xml @@ -0,0 +1,2 @@ + + diff --git a/vendor/symfony/config/Tests/Fixtures/Util/schema.xsd b/vendor/symfony/config/Tests/Fixtures/Util/schema.xsd new file mode 100644 index 000000000..e56820f69 --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/Util/schema.xsd @@ -0,0 +1,9 @@ + + + + + + diff --git a/vendor/symfony/config/Tests/Fixtures/Util/valid.xml b/vendor/symfony/config/Tests/Fixtures/Util/valid.xml new file mode 100644 index 000000000..a96bb3826 --- /dev/null +++ b/vendor/symfony/config/Tests/Fixtures/Util/valid.xml @@ -0,0 +1,3 @@ + + + diff --git a/vendor/symfony/config/Tests/Fixtures/foo.xml b/vendor/symfony/config/Tests/Fixtures/foo.xml new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/config/Tests/Loader/DelegatingLoaderTest.php b/vendor/symfony/config/Tests/Loader/DelegatingLoaderTest.php new file mode 100644 index 000000000..4a01d26ad --- /dev/null +++ b/vendor/symfony/config/Tests/Loader/DelegatingLoaderTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Loader\DelegatingLoader; + +class DelegatingLoaderTest extends TestCase +{ + public function testConstructor() + { + $loader = new DelegatingLoader($resolver = new LoaderResolver()); + $this->assertTrue(true, '__construct() takes a loader resolver as its first argument'); + } + + public function testGetSetResolver() + { + $resolver = new LoaderResolver(); + $loader = new DelegatingLoader($resolver); + $this->assertSame($resolver, $loader->getResolver(), '->getResolver() gets the resolver loader'); + $loader->setResolver($resolver = new LoaderResolver()); + $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader'); + } + + public function testSupports() + { + $loader1 = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader1->expects($this->once())->method('supports')->will($this->returnValue(true)); + $loader = new DelegatingLoader(new LoaderResolver(array($loader1))); + $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable'); + + $loader1 = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader1->expects($this->once())->method('supports')->will($this->returnValue(false)); + $loader = new DelegatingLoader(new LoaderResolver(array($loader1))); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable'); + } + + public function testLoad() + { + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader->expects($this->once())->method('supports')->will($this->returnValue(true)); + $loader->expects($this->once())->method('load'); + $resolver = new LoaderResolver(array($loader)); + $loader = new DelegatingLoader($resolver); + + $loader->load('foo'); + } + + /** + * @expectedException \Symfony\Component\Config\Exception\FileLoaderLoadException + */ + public function testLoadThrowsAnExceptionIfTheResourceCannotBeLoaded() + { + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader->expects($this->once())->method('supports')->will($this->returnValue(false)); + $resolver = new LoaderResolver(array($loader)); + $loader = new DelegatingLoader($resolver); + + $loader->load('foo'); + } +} diff --git a/vendor/symfony/config/Tests/Loader/FileLoaderTest.php b/vendor/symfony/config/Tests/Loader/FileLoaderTest.php new file mode 100644 index 000000000..e1d23e45f --- /dev/null +++ b/vendor/symfony/config/Tests/Loader/FileLoaderTest.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Loader\FileLoader; +use Symfony\Component\Config\Loader\LoaderResolver; + +class FileLoaderTest extends TestCase +{ + public function testImportWithFileLocatorDelegation() + { + $locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock(); + + $locatorMockForAdditionalLoader = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock(); + $locatorMockForAdditionalLoader->expects($this->any())->method('locate')->will($this->onConsecutiveCalls( + array('path/to/file1'), // Default + array('path/to/file1', 'path/to/file2'), // First is imported + array('path/to/file1', 'path/to/file2'), // Second is imported + array('path/to/file1'), // Exception + array('path/to/file1', 'path/to/file2') // Exception + )); + + $fileLoader = new TestFileLoader($locatorMock); + $fileLoader->setSupports(false); + $fileLoader->setCurrentDir('.'); + + $additionalLoader = new TestFileLoader($locatorMockForAdditionalLoader); + $additionalLoader->setCurrentDir('.'); + + $fileLoader->setResolver($loaderResolver = new LoaderResolver(array($fileLoader, $additionalLoader))); + + // Default case + $this->assertSame('path/to/file1', $fileLoader->import('my_resource')); + + // Check first file is imported if not already loading + $this->assertSame('path/to/file1', $fileLoader->import('my_resource')); + + // Check second file is imported if first is already loading + $fileLoader->addLoading('path/to/file1'); + $this->assertSame('path/to/file2', $fileLoader->import('my_resource')); + + // Check exception throws if first (and only available) file is already loading + try { + $fileLoader->import('my_resource'); + $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading'); + } + + // Check exception throws if all files are already loading + try { + $fileLoader->addLoading('path/to/file2'); + $fileLoader->import('my_resource'); + $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading'); + } + } +} + +class TestFileLoader extends FileLoader +{ + private $supports = true; + + public function load($resource, $type = null) + { + return $resource; + } + + public function supports($resource, $type = null) + { + return $this->supports; + } + + public function addLoading($resource) + { + self::$loading[$resource] = true; + } + + public function removeLoading($resource) + { + unset(self::$loading[$resource]); + } + + public function clearLoading() + { + self::$loading = array(); + } + + public function setSupports($supports) + { + $this->supports = $supports; + } +} diff --git a/vendor/symfony/config/Tests/Loader/LoaderResolverTest.php b/vendor/symfony/config/Tests/Loader/LoaderResolverTest.php new file mode 100644 index 000000000..0bf56b610 --- /dev/null +++ b/vendor/symfony/config/Tests/Loader/LoaderResolverTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Loader\LoaderResolver; + +class LoaderResolverTest extends TestCase +{ + public function testConstructor() + { + $resolver = new LoaderResolver(array( + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(), + )); + + $this->assertEquals(array($loader), $resolver->getLoaders(), '__construct() takes an array of loaders as its first argument'); + } + + public function testResolve() + { + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $resolver = new LoaderResolver(array($loader)); + $this->assertFalse($resolver->resolve('foo.foo'), '->resolve() returns false if no loader is able to load the resource'); + + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader->expects($this->once())->method('supports')->will($this->returnValue(true)); + $resolver = new LoaderResolver(array($loader)); + $this->assertEquals($loader, $resolver->resolve(function () {}), '->resolve() returns the loader for the given resource'); + } + + public function testLoaders() + { + $resolver = new LoaderResolver(); + $resolver->addLoader($loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock()); + + $this->assertEquals(array($loader), $resolver->getLoaders(), 'addLoader() adds a loader'); + } +} diff --git a/vendor/symfony/config/Tests/Loader/LoaderTest.php b/vendor/symfony/config/Tests/Loader/LoaderTest.php new file mode 100644 index 000000000..fefb1d728 --- /dev/null +++ b/vendor/symfony/config/Tests/Loader/LoaderTest.php @@ -0,0 +1,118 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Loader\Loader; + +class LoaderTest extends TestCase +{ + public function testGetSetResolver() + { + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader'); + } + + public function testResolve() + { + $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + $resolver->expects($this->once()) + ->method('resolve') + ->with('foo.xml') + ->will($this->returnValue($resolvedLoader)); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $this->assertSame($loader, $loader->resolve('foo.foo'), '->resolve() finds a loader'); + $this->assertSame($resolvedLoader, $loader->resolve('foo.xml'), '->resolve() finds a loader'); + } + + /** + * @expectedException \Symfony\Component\Config\Exception\FileLoaderLoadException + */ + public function testResolveWhenResolverCannotFindLoader() + { + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + $resolver->expects($this->once()) + ->method('resolve') + ->with('FOOBAR') + ->will($this->returnValue(false)); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $loader->resolve('FOOBAR'); + } + + public function testImport() + { + $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $resolvedLoader->expects($this->once()) + ->method('load') + ->with('foo') + ->will($this->returnValue('yes')); + + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + $resolver->expects($this->once()) + ->method('resolve') + ->with('foo') + ->will($this->returnValue($resolvedLoader)); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $this->assertEquals('yes', $loader->import('foo')); + } + + public function testImportWithType() + { + $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $resolvedLoader->expects($this->once()) + ->method('load') + ->with('foo', 'bar') + ->will($this->returnValue('yes')); + + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + $resolver->expects($this->once()) + ->method('resolve') + ->with('foo', 'bar') + ->will($this->returnValue($resolvedLoader)); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $this->assertEquals('yes', $loader->import('foo', 'bar')); + } +} + +class ProjectLoader1 extends Loader +{ + public function load($resource, $type = null) + { + } + + public function supports($resource, $type = null) + { + return is_string($resource) && 'foo' === pathinfo($resource, PATHINFO_EXTENSION); + } + + public function getType() + { + } +} diff --git a/vendor/symfony/config/Tests/Resource/DirectoryResourceTest.php b/vendor/symfony/config/Tests/Resource/DirectoryResourceTest.php new file mode 100644 index 000000000..60bd616a4 --- /dev/null +++ b/vendor/symfony/config/Tests/Resource/DirectoryResourceTest.php @@ -0,0 +1,169 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\DirectoryResource; + +class DirectoryResourceTest extends TestCase +{ + protected $directory; + + protected function setUp() + { + $this->directory = sys_get_temp_dir().DIRECTORY_SEPARATOR.'symfonyDirectoryIterator'; + if (!file_exists($this->directory)) { + mkdir($this->directory); + } + touch($this->directory.'/tmp.xml'); + } + + protected function tearDown() + { + if (!is_dir($this->directory)) { + return; + } + $this->removeDirectory($this->directory); + } + + protected function removeDirectory($directory) + { + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::CHILD_FIRST); + foreach ($iterator as $path) { + if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) { + continue; + } + if ($path->isDir()) { + rmdir($path->__toString()); + } else { + unlink($path->__toString()); + } + } + rmdir($directory); + } + + public function testGetResource() + { + $resource = new DirectoryResource($this->directory); + $this->assertSame($this->directory, $resource->getResource(), '->getResource() returns the path to the resource'); + } + + public function testGetPattern() + { + $resource = new DirectoryResource('foo', 'bar'); + $this->assertEquals('bar', $resource->getPattern()); + } + + public function testIsFresh() + { + $resource = new DirectoryResource($this->directory); + $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed'); + $this->assertFalse($resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated'); + + $resource = new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999)); + $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist'); + } + + public function testIsFreshUpdateFile() + { + $resource = new DirectoryResource($this->directory); + touch($this->directory.'/tmp.xml', time() + 20); + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an existing file is modified'); + } + + public function testIsFreshNewFile() + { + $resource = new DirectoryResource($this->directory); + touch($this->directory.'/new.xml', time() + 20); + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file is added'); + } + + public function testIsFreshNewFileWithDifferentPattern() + { + $resource = new DirectoryResource($this->directory, '/.xml$/'); + touch($this->directory.'/new.yaml', time() + 20); + $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file with a non-matching pattern is added'); + } + + public function testIsFreshDeleteFile() + { + $resource = new DirectoryResource($this->directory); + $time = time(); + sleep(1); + unlink($this->directory.'/tmp.xml'); + $this->assertFalse($resource->isFresh($time), '->isFresh() returns false if an existing file is removed'); + } + + public function testIsFreshDeleteDirectory() + { + $resource = new DirectoryResource($this->directory); + $this->removeDirectory($this->directory); + $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the whole resource is removed'); + } + + public function testIsFreshCreateFileInSubdirectory() + { + $subdirectory = $this->directory.'/subdirectory'; + mkdir($subdirectory); + + $resource = new DirectoryResource($this->directory); + $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if an unmodified subdirectory exists'); + + touch($subdirectory.'/newfile.xml', time() + 20); + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file in a subdirectory is added'); + } + + public function testIsFreshModifySubdirectory() + { + $resource = new DirectoryResource($this->directory); + + $subdirectory = $this->directory.'/subdirectory'; + mkdir($subdirectory); + touch($subdirectory, time() + 20); + + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a subdirectory is modified (e.g. a file gets deleted)'); + } + + public function testFilterRegexListNoMatch() + { + $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + touch($this->directory.'/new.bar', time() + 20); + $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file not matching the filter regex is created'); + } + + public function testFilterRegexListMatch() + { + $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + touch($this->directory.'/new.xml', time() + 20); + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an new file matching the filter regex is created '); + } + + public function testSerializeUnserialize() + { + $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + $unserialized = unserialize(serialize($resource)); + + $this->assertSame($this->directory, $resource->getResource()); + $this->assertSame('/\.(foo|xml)$/', $resource->getPattern()); + } + + public function testResourcesWithDifferentPatternsAreDifferent() + { + $resourceA = new DirectoryResource($this->directory, '/.xml$/'); + $resourceB = new DirectoryResource($this->directory, '/.yaml$/'); + + $this->assertEquals(2, count(array_unique(array($resourceA, $resourceB)))); + } +} diff --git a/vendor/symfony/config/Tests/Resource/FileExistenceResourceTest.php b/vendor/symfony/config/Tests/Resource/FileExistenceResourceTest.php new file mode 100644 index 000000000..433f65e82 --- /dev/null +++ b/vendor/symfony/config/Tests/Resource/FileExistenceResourceTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\FileExistenceResource; + +class FileExistenceResourceTest extends TestCase +{ + protected $resource; + protected $file; + protected $time; + + protected function setUp() + { + $this->file = realpath(sys_get_temp_dir()).'/tmp.xml'; + $this->time = time(); + $this->resource = new FileExistenceResource($this->file); + } + + protected function tearDown() + { + if (file_exists($this->file)) { + unlink($this->file); + } + } + + public function testToString() + { + $this->assertSame($this->file, (string) $this->resource); + } + + public function testGetResource() + { + $this->assertSame($this->file, $this->resource->getResource(), '->getResource() returns the path to the resource'); + } + + public function testIsFreshWithExistingResource() + { + touch($this->file, $this->time); + $serialized = serialize(new FileExistenceResource($this->file)); + + $resource = unserialize($serialized); + $this->assertTrue($resource->isFresh($this->time), '->isFresh() returns true if the resource is still present'); + + unlink($this->file); + $resource = unserialize($serialized); + $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource has been deleted'); + } + + public function testIsFreshWithAbsentResource() + { + $serialized = serialize(new FileExistenceResource($this->file)); + + $resource = unserialize($serialized); + $this->assertTrue($resource->isFresh($this->time), '->isFresh() returns true if the resource is still absent'); + + touch($this->file, $this->time); + $resource = unserialize($serialized); + $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource has been created'); + } +} diff --git a/vendor/symfony/config/Tests/Resource/FileResourceTest.php b/vendor/symfony/config/Tests/Resource/FileResourceTest.php new file mode 100644 index 000000000..9e77c9480 --- /dev/null +++ b/vendor/symfony/config/Tests/Resource/FileResourceTest.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\FileResource; + +class FileResourceTest extends TestCase +{ + protected $resource; + protected $file; + protected $time; + + protected function setUp() + { + $this->file = realpath(sys_get_temp_dir()).'/tmp.xml'; + $this->time = time(); + touch($this->file, $this->time); + $this->resource = new FileResource($this->file); + } + + protected function tearDown() + { + unlink($this->file); + } + + public function testGetResource() + { + $this->assertSame(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource'); + } + + public function testToString() + { + $this->assertSame(realpath($this->file), (string) $this->resource); + } + + public function testIsFresh() + { + $this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second'); + $this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed'); + $this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated'); + + $resource = new FileResource('/____foo/foobar'.mt_rand(1, 999999)); + $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist'); + } + + public function testSerializeUnserialize() + { + $unserialized = unserialize(serialize($this->resource)); + + $this->assertSame(realpath($this->file), $this->resource->getResource()); + } +} diff --git a/vendor/symfony/config/Tests/Resource/ResourceStub.php b/vendor/symfony/config/Tests/Resource/ResourceStub.php new file mode 100644 index 000000000..78799d7b9 --- /dev/null +++ b/vendor/symfony/config/Tests/Resource/ResourceStub.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use Symfony\Component\Config\Resource\SelfCheckingResourceInterface; + +class ResourceStub implements SelfCheckingResourceInterface +{ + private $fresh = true; + + public function setFresh($isFresh) + { + $this->fresh = $isFresh; + } + + public function __toString() + { + return 'stub'; + } + + public function isFresh($timestamp) + { + return $this->fresh; + } + + public function getResource() + { + return 'stub'; + } +} diff --git a/vendor/symfony/config/Tests/ResourceCheckerConfigCacheTest.php b/vendor/symfony/config/Tests/ResourceCheckerConfigCacheTest.php new file mode 100644 index 000000000..d39742ad8 --- /dev/null +++ b/vendor/symfony/config/Tests/ResourceCheckerConfigCacheTest.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Tests\Resource\ResourceStub; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\ResourceCheckerConfigCache; + +class ResourceCheckerConfigCacheTest extends TestCase +{ + private $cacheFile = null; + + protected function setUp() + { + $this->cacheFile = tempnam(sys_get_temp_dir(), 'config_'); + } + + protected function tearDown() + { + $files = array($this->cacheFile, "{$this->cacheFile}.meta"); + + foreach ($files as $file) { + if (file_exists($file)) { + unlink($file); + } + } + } + + public function testGetPath() + { + $cache = new ResourceCheckerConfigCache($this->cacheFile); + + $this->assertSame($this->cacheFile, $cache->getPath()); + } + + public function testCacheIsNotFreshIfEmpty() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock() + ->expects($this->never())->method('supports'); + + /* If there is nothing in the cache, it needs to be filled (and thus it's not fresh). + It does not matter if you provide checkers or not. */ + + unlink($this->cacheFile); // remove tempnam() side effect + $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker)); + + $this->assertFalse($cache->isFresh()); + } + + public function testCacheIsFreshIfNocheckerProvided() + { + /* For example in prod mode, you may choose not to run any checkers + at all. In that case, the cache should always be considered fresh. */ + $cache = new ResourceCheckerConfigCache($this->cacheFile); + $this->assertTrue($cache->isFresh()); + } + + public function testResourcesWithoutcheckersAreIgnoredAndConsideredFresh() + { + /* As in the previous test, but this time we have a resource. */ + $cache = new ResourceCheckerConfigCache($this->cacheFile); + $cache->write('', array(new ResourceStub())); + + $this->assertTrue($cache->isFresh()); // no (matching) ResourceChecker passed + } + + public function testIsFreshWithchecker() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock(); + + $checker->expects($this->once()) + ->method('supports') + ->willReturn(true); + + $checker->expects($this->once()) + ->method('isFresh') + ->willReturn(true); + + $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker)); + $cache->write('', array(new ResourceStub())); + + $this->assertTrue($cache->isFresh()); + } + + public function testIsNotFreshWithchecker() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock(); + + $checker->expects($this->once()) + ->method('supports') + ->willReturn(true); + + $checker->expects($this->once()) + ->method('isFresh') + ->willReturn(false); + + $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker)); + $cache->write('', array(new ResourceStub())); + + $this->assertFalse($cache->isFresh()); + } + + public function testCacheIsNotFreshWhenUnserializeFails() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock(); + $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker)); + $cache->write('foo', array(new FileResource(__FILE__))); + + $metaFile = "{$this->cacheFile}.meta"; + file_put_contents($metaFile, str_replace('FileResource', 'ClassNotHere', file_get_contents($metaFile))); + + $this->assertFalse($cache->isFresh()); + } + + public function testCacheKeepsContent() + { + $cache = new ResourceCheckerConfigCache($this->cacheFile); + $cache->write('FOOBAR'); + + $this->assertSame('FOOBAR', file_get_contents($cache->getPath())); + } + + public function testCacheIsNotFreshIfNotExistsMetaFile() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock(); + $cache = new ResourceCheckerConfigCache($this->cacheFile, array($checker)); + $cache->write('foo', array(new FileResource(__FILE__))); + + $metaFile = "{$this->cacheFile}.meta"; + unlink($metaFile); + + $this->assertFalse($cache->isFresh()); + } +} diff --git a/vendor/symfony/config/Tests/Util/XmlUtilsTest.php b/vendor/symfony/config/Tests/Util/XmlUtilsTest.php new file mode 100644 index 000000000..29d64dba8 --- /dev/null +++ b/vendor/symfony/config/Tests/Util/XmlUtilsTest.php @@ -0,0 +1,208 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Util; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Util\XmlUtils; + +class XmlUtilsTest extends TestCase +{ + public function testLoadFile() + { + $fixtures = __DIR__.'/../Fixtures/Util/'; + + try { + XmlUtils::loadFile($fixtures.'invalid.xml'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('ERROR 77', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'document_type.xml'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('Document types are not allowed', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'invalid_schema.xml', $fixtures.'schema.xsd'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('ERROR 1845', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'invalid_schema.xml', 'invalid_callback_or_file'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('XSD file or callable', $e->getMessage()); + } + + $mock = $this->getMockBuilder(__NAMESPACE__.'\Validator')->getMock(); + $mock->expects($this->exactly(2))->method('validate')->will($this->onConsecutiveCalls(false, true)); + + try { + XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('is not valid', $e->getMessage()); + } + + $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'))); + $this->assertSame(array(), libxml_get_errors()); + } + + public function testLoadFileWithInternalErrorsEnabled() + { + $internalErrors = libxml_use_internal_errors(true); + + $this->assertSame(array(), libxml_get_errors()); + $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/invalid_schema.xml')); + $this->assertSame(array(), libxml_get_errors()); + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + } + + /** + * @dataProvider getDataForConvertDomToArray + */ + public function testConvertDomToArray($expected, $xml, $root = false, $checkPrefix = true) + { + $dom = new \DOMDocument(); + $dom->loadXML($root ? $xml : ''.$xml.''); + + $this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix)); + } + + public function getDataForConvertDomToArray() + { + return array( + array(null, ''), + array('bar', 'bar'), + array(array('bar' => 'foobar'), '', true), + array(array('foo' => null), ''), + array(array('foo' => 'bar'), 'bar'), + array(array('foo' => array('foo' => 'bar')), ''), + array(array('foo' => array('foo' => 0)), '0'), + array(array('foo' => array('foo' => 'bar')), 'bar'), + array(array('foo' => array('foo' => 'bar', 'value' => 'text')), 'text'), + array(array('foo' => array('attr' => 'bar', 'foo' => 'text')), 'text'), + array(array('foo' => array('bar', 'text')), 'bartext'), + array(array('foo' => array(array('foo' => 'bar'), array('foo' => 'text'))), ''), + array(array('foo' => array('foo' => array('bar', 'text'))), 'text'), + array(array('foo' => 'bar'), 'bar'), + array(array('foo' => 'text'), 'text'), + array(array('foo' => array('bar' => 'bar', 'value' => 'text')), 'text', false, false), + array(array('attr' => 1, 'b' => 'hello'), 'hello2', true), + ); + } + + /** + * @dataProvider getDataForPhpize + */ + public function testPhpize($expected, $value) + { + $this->assertSame($expected, XmlUtils::phpize($value)); + } + + public function getDataForPhpize() + { + return array( + array('', ''), + array(null, 'null'), + array(true, 'true'), + array(false, 'false'), + array(null, 'Null'), + array(true, 'True'), + array(false, 'False'), + array(0, '0'), + array(1, '1'), + array(-1, '-1'), + array(0777, '0777'), + array(255, '0xFF'), + array(100.0, '1e2'), + array(-120.0, '-1.2E2'), + array(-10100.1, '-10100.1'), + array('-10,100.1', '-10,100.1'), + array('1234 5678 9101 1121 3141', '1234 5678 9101 1121 3141'), + array('1,2,3,4', '1,2,3,4'), + array('11,22,33,44', '11,22,33,44'), + array('11,222,333,4', '11,222,333,4'), + array('1,222,333,444', '1,222,333,444'), + array('11,222,333,444', '11,222,333,444'), + array('111,222,333,444', '111,222,333,444'), + array('1111,2222,3333,4444,5555', '1111,2222,3333,4444,5555'), + array('foo', 'foo'), + array(6, '0b0110'), + ); + } + + public function testLoadEmptyXmlFile() + { + $file = __DIR__.'/../Fixtures/foo.xml'; + + if (method_exists($this, 'expectException')) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage(sprintf('File %s does not contain valid XML, it is empty.', $file)); + } else { + $this->setExpectedException('InvalidArgumentException', sprintf('File %s does not contain valid XML, it is empty.', $file)); + } + + XmlUtils::loadFile($file); + } + + // test for issue https://github.com/symfony/symfony/issues/9731 + public function testLoadWrongEmptyXMLWithErrorHandler() + { + $originalDisableEntities = libxml_disable_entity_loader(false); + $errorReporting = error_reporting(-1); + + set_error_handler(function ($errno, $errstr) { + throw new \Exception($errstr, $errno); + }); + + $file = __DIR__.'/../Fixtures/foo.xml'; + try { + try { + XmlUtils::loadFile($file); + $this->fail('An exception should have been raised'); + } catch (\InvalidArgumentException $e) { + $this->assertEquals(sprintf('File %s does not contain valid XML, it is empty.', $file), $e->getMessage()); + } + } catch (\Exception $e) { + restore_error_handler(); + error_reporting($errorReporting); + + throw $e; + } + + restore_error_handler(); + error_reporting($errorReporting); + + $disableEntities = libxml_disable_entity_loader(true); + libxml_disable_entity_loader($disableEntities); + + libxml_disable_entity_loader($originalDisableEntities); + + $this->assertFalse($disableEntities); + + // should not throw an exception + XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/valid.xml', __DIR__.'/../Fixtures/Util/schema.xsd'); + } +} + +interface Validator +{ + public function validate(); +} diff --git a/vendor/symfony/config/phpunit.xml.dist b/vendor/symfony/config/phpunit.xml.dist index 3fe6fd87c..36ef339fd 100644 --- a/vendor/symfony/config/phpunit.xml.dist +++ b/vendor/symfony/config/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/console/Application.php b/vendor/symfony/console/Application.php index a72875d7b..f764020c3 100644 --- a/vendor/symfony/console/Application.php +++ b/vendor/symfony/console/Application.php @@ -16,6 +16,7 @@ use Symfony\Component\Console\Descriptor\XmlDescriptor; use Symfony\Component\Console\Exception\ExceptionInterface; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\DebugFormatterHelper; +use Symfony\Component\Console\Helper\Helper; use Symfony\Component\Console\Helper\ProcessHelper; use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; @@ -106,6 +107,8 @@ class Application * @param OutputInterface $output An Output instance * * @return int 0 if everything went fine, or an error code + * + * @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}. */ public function run(InputInterface $input = null, OutputInterface $output = null) { @@ -120,10 +123,17 @@ class Application $this->configureIO($input, $output); try { + $e = null; $exitCode = $this->doRun($input, $output); - } catch (\Exception $e) { - if (!$this->catchExceptions) { - throw $e; + } catch (\Exception $x) { + $e = $x; + } catch (\Throwable $x) { + $e = new FatalThrowableError($x); + } + + if (null !== $e) { + if (!$this->catchExceptions || !$x instanceof \Exception) { + throw $x; } if ($output instanceof ConsoleOutputInterface) { @@ -185,6 +195,7 @@ class Application $input = new ArrayInput(array('command' => $this->defaultCommand)); } + $this->runningCommand = null; // the command name MUST be the first element of the input $command = $this->find($name); @@ -646,7 +657,7 @@ class Application do { $title = sprintf(' [%s] ', get_class($e)); - $len = $this->stringWidth($title); + $len = Helper::strlen($title); $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX; // HHVM only accepts 32 bits integer in str_split, even when PHP_INT_MAX is a 64 bit integer: https://github.com/facebook/hhvm/issues/1327 @@ -657,7 +668,7 @@ class Application foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) { foreach ($this->splitStringByWidth($line, $width - 4) as $line) { // pre-format lines to get the right string length - $lineLength = $this->stringWidth($line) + 4; + $lineLength = Helper::strlen($line) + 4; $lines[] = array($line, $lineLength); $len = max($lineLength, $len); @@ -666,7 +677,7 @@ class Application $messages = array(); $messages[] = $emptyLine = sprintf('%s', str_repeat(' ', $len)); - $messages[] = sprintf('%s%s', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))); + $messages[] = sprintf('%s%s', $title, str_repeat(' ', max(0, $len - Helper::strlen($title)))); foreach ($lines as $line) { $messages[] = sprintf(' %s %s', OutputFormatter::escape($line[0]), str_repeat(' ', $len - $line[1])); } @@ -842,13 +853,7 @@ class Application } if (null === $this->dispatcher) { - try { - return $command->run($input, $output); - } catch (\Exception $e) { - throw $e; - } catch (\Throwable $e) { - throw new FatalThrowableError($e); - } + return $command->run($input, $output); } // bind before the console.command event, so the listeners have access to input options/arguments @@ -860,37 +865,37 @@ class Application } $event = new ConsoleCommandEvent($command, $input, $output); - $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event); + $e = null; - if ($event->commandShouldRun()) { - try { - $e = null; + try { + $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event); + + if ($event->commandShouldRun()) { $exitCode = $command->run($input, $output); - } catch (\Exception $x) { - $e = $x; - } catch (\Throwable $x) { - $e = new FatalThrowableError($x); + } else { + $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED; } - if (null !== $e) { - $event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode()); - $this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event); - - if ($e !== $event->getException()) { - $x = $e = $event->getException(); - } - - $event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode()); - $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event); + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + if (null !== $e) { + $x = $e instanceof \Exception ? $e : new FatalThrowableError($e); + $event = new ConsoleExceptionEvent($command, $input, $output, $x, $x->getCode()); + $this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event); - throw $x; + if ($x !== $event->getException()) { + $e = $event->getException(); } - } else { - $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED; + $exitCode = $e->getCode(); } $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode); $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event); + if (null !== $e) { + throw $e; + } + return $event->getExitCode(); } @@ -1093,15 +1098,6 @@ class Application $this->defaultCommand = $commandName; } - private function stringWidth($string) - { - if (false === $encoding = mb_detect_encoding($string, null, true)) { - return strlen($string); - } - - return mb_strwidth($string, $encoding); - } - private function splitStringByWidth($string, $width) { // str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly. diff --git a/vendor/symfony/console/Command/Command.php b/vendor/symfony/console/Command/Command.php index 39a1f6e84..67297fc04 100644 --- a/vendor/symfony/console/Command/Command.php +++ b/vendor/symfony/console/Command/Command.php @@ -205,6 +205,8 @@ class Command * * @return int The command exit code * + * @throws \Exception When binding input fails. Bypass this by calling {@link ignoreValidationErrors()}. + * * @see setCode() * @see execute() */ diff --git a/vendor/symfony/console/Descriptor/TextDescriptor.php b/vendor/symfony/console/Descriptor/TextDescriptor.php index b49b64d5a..c0dd4830c 100644 --- a/vendor/symfony/console/Descriptor/TextDescriptor.php +++ b/vendor/symfony/console/Descriptor/TextDescriptor.php @@ -247,7 +247,7 @@ class TextDescriptor extends Descriptor } } - if (PHP_VERSION_ID < 50400) { + if (\PHP_VERSION_ID < 50400) { return str_replace(array('\/', '\\\\'), array('/', '\\'), json_encode($default)); } diff --git a/vendor/symfony/console/Formatter/OutputFormatter.php b/vendor/symfony/console/Formatter/OutputFormatter.php index dee696759..dd67ed267 100644 --- a/vendor/symfony/console/Formatter/OutputFormatter.php +++ b/vendor/symfony/console/Formatter/OutputFormatter.php @@ -81,9 +81,7 @@ class OutputFormatter implements OutputFormatterInterface } /** - * Sets the decorated flag. - * - * @param bool $decorated Whether to decorate the messages or not + * {@inheritdoc} */ public function setDecorated($decorated) { @@ -91,9 +89,7 @@ class OutputFormatter implements OutputFormatterInterface } /** - * Gets the decorated flag. - * - * @return bool true if the output will decorate messages, false otherwise + * {@inheritdoc} */ public function isDecorated() { @@ -101,10 +97,7 @@ class OutputFormatter implements OutputFormatterInterface } /** - * Sets a new style. - * - * @param string $name The style name - * @param OutputFormatterStyleInterface $style The style instance + * {@inheritdoc} */ public function setStyle($name, OutputFormatterStyleInterface $style) { @@ -112,11 +105,7 @@ class OutputFormatter implements OutputFormatterInterface } /** - * Checks if output formatter has style with specified name. - * - * @param string $name - * - * @return bool + * {@inheritdoc} */ public function hasStyle($name) { @@ -124,13 +113,7 @@ class OutputFormatter implements OutputFormatterInterface } /** - * Gets style options from style with specified name. - * - * @param string $name - * - * @return OutputFormatterStyleInterface - * - * @throws InvalidArgumentException When style isn't defined + * {@inheritdoc} */ public function getStyle($name) { @@ -142,11 +125,7 @@ class OutputFormatter implements OutputFormatterInterface } /** - * Formats a message according to the given styles. - * - * @param string $message The message to style - * - * @return string The styled message + * {@inheritdoc} */ public function format($message) { diff --git a/vendor/symfony/console/Formatter/OutputFormatterInterface.php b/vendor/symfony/console/Formatter/OutputFormatterInterface.php index 5a52ba096..281e240c5 100644 --- a/vendor/symfony/console/Formatter/OutputFormatterInterface.php +++ b/vendor/symfony/console/Formatter/OutputFormatterInterface.php @@ -55,6 +55,8 @@ interface OutputFormatterInterface * @param string $name * * @return OutputFormatterStyleInterface + * + * @throws \InvalidArgumentException When style isn't defined */ public function getStyle($name); diff --git a/vendor/symfony/console/Helper/Table.php b/vendor/symfony/console/Helper/Table.php index 0fe89f7ec..e5fc36f63 100644 --- a/vendor/symfony/console/Helper/Table.php +++ b/vendor/symfony/console/Helper/Table.php @@ -149,7 +149,7 @@ class Table */ public function setColumnStyle($columnIndex, $name) { - $columnIndex = intval($columnIndex); + $columnIndex = (int) $columnIndex; $this->columnStyles[$columnIndex] = $this->resolveStyle($name); diff --git a/vendor/symfony/console/Question/ChoiceQuestion.php b/vendor/symfony/console/Question/ChoiceQuestion.php index 522a81bb1..5815e2b04 100644 --- a/vendor/symfony/console/Question/ChoiceQuestion.php +++ b/vendor/symfony/console/Question/ChoiceQuestion.php @@ -34,6 +34,10 @@ class ChoiceQuestion extends Question */ public function __construct($question, array $choices, $default = null) { + if (!$choices) { + throw new \LogicException('Choice question must have at least 1 choice available.'); + } + parent::__construct($question, $default); $this->choices = $choices; @@ -137,7 +141,7 @@ class ChoiceQuestion extends Question if ($multiselect) { // Check for a separated comma values - if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) { + if (!preg_match('/^[^,]+(?:,[^,]+)*$/', $selectedChoices, $matches)) { throw new InvalidArgumentException(sprintf($errorMessage, $selected)); } $selectedChoices = explode(',', $selectedChoices); diff --git a/vendor/symfony/console/Tests/ApplicationTest.php b/vendor/symfony/console/Tests/ApplicationTest.php new file mode 100644 index 000000000..d8e1e7137 --- /dev/null +++ b/vendor/symfony/console/Tests/ApplicationTest.php @@ -0,0 +1,1295 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\StreamOutput; +use Symfony\Component\Console\Tester\ApplicationTester; +use Symfony\Component\Console\Event\ConsoleCommandEvent; +use Symfony\Component\Console\Event\ConsoleExceptionEvent; +use Symfony\Component\Console\Event\ConsoleTerminateEvent; +use Symfony\Component\EventDispatcher\EventDispatcher; + +class ApplicationTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/Fixtures/'); + require_once self::$fixturesPath.'/FooCommand.php'; + require_once self::$fixturesPath.'/Foo1Command.php'; + require_once self::$fixturesPath.'/Foo2Command.php'; + require_once self::$fixturesPath.'/Foo3Command.php'; + require_once self::$fixturesPath.'/Foo4Command.php'; + require_once self::$fixturesPath.'/Foo5Command.php'; + require_once self::$fixturesPath.'/FoobarCommand.php'; + require_once self::$fixturesPath.'/BarBucCommand.php'; + require_once self::$fixturesPath.'/FooSubnamespaced1Command.php'; + require_once self::$fixturesPath.'/FooSubnamespaced2Command.php'; + } + + protected function normalizeLineBreaks($text) + { + return str_replace(PHP_EOL, "\n", $text); + } + + /** + * Replaces the dynamic placeholders of the command help text with a static version. + * The placeholder %command.full_name% includes the script path that is not predictable + * and can not be tested against. + */ + protected function ensureStaticCommandHelp(Application $application) + { + foreach ($application->all() as $command) { + $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp())); + } + } + + public function testConstructor() + { + $application = new Application('foo', 'bar'); + $this->assertEquals('foo', $application->getName(), '__construct() takes the application name as its first argument'); + $this->assertEquals('bar', $application->getVersion(), '__construct() takes the application version as its second argument'); + $this->assertEquals(array('help', 'list'), array_keys($application->all()), '__construct() registered the help and list commands by default'); + } + + public function testSetGetName() + { + $application = new Application(); + $application->setName('foo'); + $this->assertEquals('foo', $application->getName(), '->setName() sets the name of the application'); + } + + public function testSetGetVersion() + { + $application = new Application(); + $application->setVersion('bar'); + $this->assertEquals('bar', $application->getVersion(), '->setVersion() sets the version of the application'); + } + + public function testGetLongVersion() + { + $application = new Application('foo', 'bar'); + $this->assertEquals('foo version bar', $application->getLongVersion(), '->getLongVersion() returns the long version of the application'); + } + + public function testHelp() + { + $application = new Application(); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_gethelp.txt', $this->normalizeLineBreaks($application->getHelp()), '->getHelp() returns a help message'); + } + + public function testAll() + { + $application = new Application(); + $commands = $application->all(); + $this->assertInstanceOf('Symfony\\Component\\Console\\Command\\HelpCommand', $commands['help'], '->all() returns the registered commands'); + + $application->add(new \FooCommand()); + $commands = $application->all('foo'); + $this->assertCount(1, $commands, '->all() takes a namespace as its first argument'); + } + + public function testRegister() + { + $application = new Application(); + $command = $application->register('foo'); + $this->assertEquals('foo', $command->getName(), '->register() registers a new command'); + } + + public function testAdd() + { + $application = new Application(); + $application->add($foo = new \FooCommand()); + $commands = $application->all(); + $this->assertEquals($foo, $commands['foo:bar'], '->add() registers a command'); + + $application = new Application(); + $application->addCommands(array($foo = new \FooCommand(), $foo1 = new \Foo1Command())); + $commands = $application->all(); + $this->assertEquals(array($foo, $foo1), array($commands['foo:bar'], $commands['foo:bar1']), '->addCommands() registers an array of commands'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Command class "Foo5Command" is not correctly initialized. You probably forgot to call the parent constructor. + */ + public function testAddCommandWithEmptyConstructor() + { + $application = new Application(); + $application->add(new \Foo5Command()); + } + + public function testHasGet() + { + $application = new Application(); + $this->assertTrue($application->has('list'), '->has() returns true if a named command is registered'); + $this->assertFalse($application->has('afoobar'), '->has() returns false if a named command is not registered'); + + $application->add($foo = new \FooCommand()); + $this->assertTrue($application->has('afoobar'), '->has() returns true if an alias is registered'); + $this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name'); + $this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias'); + + $application = new Application(); + $application->add($foo = new \FooCommand()); + // simulate --help + $r = new \ReflectionObject($application); + $p = $r->getProperty('wantHelps'); + $p->setAccessible(true); + $p->setValue($application, true); + $command = $application->get('foo:bar'); + $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $command, '->get() returns the help command if --help is provided as the input'); + } + + public function testSilentHelp() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $tester = new ApplicationTester($application); + $tester->run(array('-h' => true, '-q' => true), array('decorated' => false)); + + $this->assertEmpty($tester->getDisplay(true)); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage The command "foofoo" does not exist. + */ + public function testGetInvalidCommand() + { + $application = new Application(); + $application->get('foofoo'); + } + + public function testGetNamespaces() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $this->assertEquals(array('foo'), $application->getNamespaces(), '->getNamespaces() returns an array of unique used namespaces'); + } + + public function testFindNamespace() + { + $application = new Application(); + $application->add(new \FooCommand()); + $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists'); + $this->assertEquals('foo', $application->findNamespace('f'), '->findNamespace() finds a namespace given an abbreviation'); + $application->add(new \Foo2Command()); + $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists'); + } + + public function testFindNamespaceWithSubnamespaces() + { + $application = new Application(); + $application->add(new \FooSubnamespaced1Command()); + $application->add(new \FooSubnamespaced2Command()); + $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns commands even if the commands are only contained in subnamespaces'); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage The namespace "f" is ambiguous (foo, foo1). + */ + public function testFindAmbiguousNamespace() + { + $application = new Application(); + $application->add(new \BarBucCommand()); + $application->add(new \FooCommand()); + $application->add(new \Foo2Command()); + $application->findNamespace('f'); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage There are no commands defined in the "bar" namespace. + */ + public function testFindInvalidNamespace() + { + $application = new Application(); + $application->findNamespace('bar'); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage Command "foo1" is not defined + */ + public function testFindUniqueNameButNamespaceName() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + $application->find($commandName = 'foo1'); + } + + public function testFind() + { + $application = new Application(); + $application->add(new \FooCommand()); + + $this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists'); + $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists'); + $this->assertInstanceOf('FooCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation for the namespace exists'); + $this->assertInstanceOf('FooCommand', $application->find('f:b'), '->find() returns a command if the abbreviation for the namespace and the command name exist'); + $this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias'); + } + + /** + * @dataProvider provideAmbiguousAbbreviations + */ + public function testFindWithAmbiguousAbbreviations($abbreviation, $expectedExceptionMessage) + { + if (method_exists($this, 'expectException')) { + $this->expectException('Symfony\Component\Console\Exception\CommandNotFoundException'); + $this->expectExceptionMessage($expectedExceptionMessage); + } else { + $this->setExpectedException('Symfony\Component\Console\Exception\CommandNotFoundException', $expectedExceptionMessage); + } + + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + $application->find($abbreviation); + } + + public function provideAmbiguousAbbreviations() + { + return array( + array('f', 'Command "f" is not defined.'), + array('a', 'Command "a" is ambiguous (afoobar, afoobar1 and 1 more).'), + array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1 and 1 more).'), + ); + } + + public function testFindCommandEqualNamespace() + { + $application = new Application(); + $application->add(new \Foo3Command()); + $application->add(new \Foo4Command()); + + $this->assertInstanceOf('Foo3Command', $application->find('foo3:bar'), '->find() returns the good command even if a namespace has same name'); + $this->assertInstanceOf('Foo4Command', $application->find('foo3:bar:toh'), '->find() returns a command even if its namespace equals another command name'); + } + + public function testFindCommandWithAmbiguousNamespacesButUniqueName() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \FoobarCommand()); + + $this->assertInstanceOf('FoobarCommand', $application->find('f:f')); + } + + public function testFindCommandWithMissingNamespace() + { + $application = new Application(); + $application->add(new \Foo4Command()); + + $this->assertInstanceOf('Foo4Command', $application->find('f::t')); + } + + /** + * @dataProvider provideInvalidCommandNamesSingle + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage Did you mean this + */ + public function testFindAlternativeExceptionMessageSingle($name) + { + $application = new Application(); + $application->add(new \Foo3Command()); + $application->find($name); + } + + public function provideInvalidCommandNamesSingle() + { + return array( + array('foo3:baR'), + array('foO3:bar'), + ); + } + + public function testFindAlternativeExceptionMessageMultiple() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + // Command + plural + try { + $application->find('foo:baR'); + $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/foo1:bar/', $e->getMessage()); + $this->assertRegExp('/foo:bar/', $e->getMessage()); + } + + // Namespace + plural + try { + $application->find('foo2:bar'); + $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/foo1/', $e->getMessage()); + } + + $application->add(new \Foo3Command()); + $application->add(new \Foo4Command()); + + // Subnamespace + plural + try { + $a = $application->find('foo3:'); + $this->fail('->find() should throw an Symfony\Component\Console\Exception\CommandNotFoundException if a command is ambiguous because of a subnamespace, with alternatives'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e); + $this->assertRegExp('/foo3:bar/', $e->getMessage()); + $this->assertRegExp('/foo3:bar:toh/', $e->getMessage()); + } + } + + public function testFindAlternativeCommands() + { + $application = new Application(); + + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + try { + $application->find($commandName = 'Unknown command'); + $this->fail('->find() throws a CommandNotFoundException if command does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist'); + $this->assertSame(array(), $e->getAlternatives()); + $this->assertEquals(sprintf('Command "%s" is not defined.', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without alternatives'); + } + + // Test if "bar1" command throw a "CommandNotFoundException" and does not contain + // "foo:bar" as alternative because "bar1" is too far from "foo:bar" + try { + $application->find($commandName = 'bar1'); + $this->fail('->find() throws a CommandNotFoundException if command does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist'); + $this->assertSame(array('afoobar1', 'foo:bar1'), $e->getAlternatives()); + $this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/afoobar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "afoobar1"'); + $this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "foo:bar1"'); + $this->assertNotRegExp('/foo:bar(?>!1)/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without "foo:bar" alternative'); + } + } + + public function testFindAlternativeCommandsWithAnAlias() + { + $fooCommand = new \FooCommand(); + $fooCommand->setAliases(array('foo2')); + + $application = new Application(); + $application->add($fooCommand); + + $result = $application->find('foo'); + + $this->assertSame($fooCommand, $result); + } + + public function testFindAlternativeNamespace() + { + $application = new Application(); + + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + $application->add(new \Foo3Command()); + + try { + $application->find('Unknown-namespace:Unknown-command'); + $this->fail('->find() throws a CommandNotFoundException if namespace does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if namespace does not exist'); + $this->assertSame(array(), $e->getAlternatives()); + $this->assertEquals('There are no commands defined in the "Unknown-namespace" namespace.', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, without alternatives'); + } + + try { + $application->find('foo2:command'); + $this->fail('->find() throws a CommandNotFoundException if namespace does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if namespace does not exist'); + $this->assertCount(3, $e->getAlternatives()); + $this->assertContains('foo', $e->getAlternatives()); + $this->assertContains('foo1', $e->getAlternatives()); + $this->assertContains('foo3', $e->getAlternatives()); + $this->assertRegExp('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative'); + $this->assertRegExp('/foo/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo"'); + $this->assertRegExp('/foo1/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo1"'); + $this->assertRegExp('/foo3/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo3"'); + } + } + + public function testFindNamespaceDoesNotFailOnDeepSimilarNamespaces() + { + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getNamespaces'))->getMock(); + $application->expects($this->once()) + ->method('getNamespaces') + ->will($this->returnValue(array('foo:sublong', 'bar:sub'))); + + $this->assertEquals('foo:sublong', $application->findNamespace('f:sub')); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage Command "foo::bar" is not defined. + */ + public function testFindWithDoubleColonInNameThrowsException() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo4Command()); + $application->find('foo::bar'); + } + + public function testSetCatchExceptions() + { + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock(); + $application->setAutoExit(false); + $application->expects($this->any()) + ->method('getTerminalWidth') + ->will($this->returnValue(120)); + $tester = new ApplicationTester($application); + + $application->setCatchExceptions(true); + $tester->run(array('command' => 'foo'), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->setCatchExceptions() sets the catch exception flag'); + + $application->setCatchExceptions(false); + try { + $tester->run(array('command' => 'foo'), array('decorated' => false)); + $this->fail('->setCatchExceptions() sets the catch exception flag'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->setCatchExceptions() sets the catch exception flag'); + $this->assertEquals('Command "foo" is not defined.', $e->getMessage(), '->setCatchExceptions() sets the catch exception flag'); + } + } + + /** + * @group legacy + */ + public function testLegacyAsText() + { + $application = new Application(); + $application->add(new \FooCommand()); + $this->ensureStaticCommandHelp($application); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_astext1.txt', $this->normalizeLineBreaks($application->asText()), '->asText() returns a text representation of the application'); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_astext2.txt', $this->normalizeLineBreaks($application->asText('foo')), '->asText() returns a text representation of the application'); + } + + /** + * @group legacy + */ + public function testLegacyAsXml() + { + $application = new Application(); + $application->add(new \FooCommand()); + $this->ensureStaticCommandHelp($application); + $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml1.txt', $application->asXml(), '->asXml() returns an XML representation of the application'); + $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/application_asxml2.txt', $application->asXml('foo'), '->asXml() returns an XML representation of the application'); + } + + public function testRenderException() + { + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock(); + $application->setAutoExit(false); + $application->expects($this->any()) + ->method('getTerminalWidth') + ->will($this->returnValue(120)); + $tester = new ApplicationTester($application); + + $tester->run(array('command' => 'foo'), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->renderException() renders a pretty exception'); + + $tester->run(array('command' => 'foo'), array('decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE)); + $this->assertContains('Exception trace', $tester->getDisplay(), '->renderException() renders a pretty exception with a stack trace when verbosity is verbose'); + + $tester->run(array('command' => 'list', '--foo' => true), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception2.txt', $tester->getDisplay(true), '->renderException() renders the command synopsis when an exception occurs in the context of a command'); + + $application->add(new \Foo3Command()); + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'foo3:bar'), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions'); + + $tester->run(array('command' => 'foo3:bar'), array('decorated' => true)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions'); + + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock(); + $application->setAutoExit(false); + $application->expects($this->any()) + ->method('getTerminalWidth') + ->will($this->returnValue(32)); + $tester = new ApplicationTester($application); + + $tester->run(array('command' => 'foo'), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal'); + } + + public function testRenderExceptionWithDoubleWidthCharacters() + { + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock(); + $application->setAutoExit(false); + $application->expects($this->any()) + ->method('getTerminalWidth') + ->will($this->returnValue(120)); + $application->register('foo')->setCode(function () { + throw new \Exception('エラーメッセージ'); + }); + $tester = new ApplicationTester($application); + + $tester->run(array('command' => 'foo'), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions'); + + $tester->run(array('command' => 'foo'), array('decorated' => true)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions'); + + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock(); + $application->setAutoExit(false); + $application->expects($this->any()) + ->method('getTerminalWidth') + ->will($this->returnValue(32)); + $application->register('foo')->setCode(function () { + throw new \Exception('コマンドの実行中にエラーが発生しました。'); + }); + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'foo'), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal'); + } + + public function testRenderExceptionEscapesLines() + { + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('getTerminalWidth'))->getMock(); + $application->setAutoExit(false); + $application->expects($this->any()) + ->method('getTerminalWidth') + ->will($this->returnValue(22)); + $application->register('foo')->setCode(function () { + throw new \Exception('dont break here !'); + }); + $tester = new ApplicationTester($application); + + $tester->run(array('command' => 'foo'), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_escapeslines.txt', $tester->getDisplay(true), '->renderException() escapes lines containing formatting'); + } + + public function testRun() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->add($command = new \Foo1Command()); + $_SERVER['argv'] = array('cli.php', 'foo:bar1'); + + ob_start(); + $application->run(); + ob_end_clean(); + + $this->assertInstanceOf('Symfony\Component\Console\Input\ArgvInput', $command->input, '->run() creates an ArgvInput by default if none is given'); + $this->assertInstanceOf('Symfony\Component\Console\Output\ConsoleOutput', $command->output, '->run() creates a ConsoleOutput by default if none is given'); + + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $this->ensureStaticCommandHelp($application); + $tester = new ApplicationTester($application); + + $tester->run(array(), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run1.txt', $tester->getDisplay(true), '->run() runs the list command if no argument is passed'); + + $tester->run(array('--help' => true), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if --help is passed'); + + $tester->run(array('-h' => true), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if -h is passed'); + + $tester->run(array('command' => 'list', '--help' => true), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if --help is passed'); + + $tester->run(array('command' => 'list', '-h' => true), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if -h is passed'); + + $tester->run(array('--ansi' => true)); + $this->assertTrue($tester->getOutput()->isDecorated(), '->run() forces color output if --ansi is passed'); + + $tester->run(array('--no-ansi' => true)); + $this->assertFalse($tester->getOutput()->isDecorated(), '->run() forces color output to be disabled if --no-ansi is passed'); + + $tester->run(array('--version' => true), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if --version is passed'); + + $tester->run(array('-V' => true), array('decorated' => false)); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if -v is passed'); + + $tester->run(array('command' => 'list', '--quiet' => true)); + $this->assertSame('', $tester->getDisplay(), '->run() removes all output if --quiet is passed'); + $this->assertFalse($tester->getInput()->isInteractive(), '->run() sets off the interactive mode if --quiet is passed'); + + $tester->run(array('command' => 'list', '-q' => true)); + $this->assertSame('', $tester->getDisplay(), '->run() removes all output if -q is passed'); + $this->assertFalse($tester->getInput()->isInteractive(), '->run() sets off the interactive mode if -q is passed'); + + $tester->run(array('command' => 'list', '--verbose' => true)); + $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose is passed'); + + $tester->run(array('command' => 'list', '--verbose' => 1)); + $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose=1 is passed'); + + $tester->run(array('command' => 'list', '--verbose' => 2)); + $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to very verbose if --verbose=2 is passed'); + + $tester->run(array('command' => 'list', '--verbose' => 3)); + $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to debug if --verbose=3 is passed'); + + $tester->run(array('command' => 'list', '--verbose' => 4)); + $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if unknown --verbose level is passed'); + + $tester->run(array('command' => 'list', '-v' => true)); + $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed'); + + $tester->run(array('command' => 'list', '-vv' => true)); + $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed'); + + $tester->run(array('command' => 'list', '-vvv' => true)); + $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed'); + + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->add(new \FooCommand()); + $tester = new ApplicationTester($application); + + $tester->run(array('command' => 'foo:bar', '--no-interaction' => true), array('decorated' => false)); + $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if --no-interaction is passed'); + + $tester->run(array('command' => 'foo:bar', '-n' => true), array('decorated' => false)); + $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if -n is passed'); + } + + /** + * Issue #9285. + * + * If the "verbose" option is just before an argument in ArgvInput, + * an argument value should not be treated as verbosity value. + * This test will fail with "Not enough arguments." if broken + */ + public function testVerboseValueNotBreakArguments() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->add(new \FooCommand()); + + $output = new StreamOutput(fopen('php://memory', 'w', false)); + + $input = new ArgvInput(array('cli.php', '-v', 'foo:bar')); + $application->run($input, $output); + + $this->addToAssertionCount(1); + + $input = new ArgvInput(array('cli.php', '--verbose', 'foo:bar')); + $application->run($input, $output); + + $this->addToAssertionCount(1); + } + + public function testRunReturnsIntegerExitCode() + { + $exception = new \Exception('', 4); + + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('doRun'))->getMock(); + $application->setAutoExit(false); + $application->expects($this->once()) + ->method('doRun') + ->will($this->throwException($exception)); + + $exitCode = $application->run(new ArrayInput(array()), new NullOutput()); + + $this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception'); + } + + public function testRunReturnsExitCodeOneForExceptionCodeZero() + { + $exception = new \Exception('', 0); + + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(array('doRun'))->getMock(); + $application->setAutoExit(false); + $application->expects($this->once()) + ->method('doRun') + ->will($this->throwException($exception)); + + $exitCode = $application->run(new ArrayInput(array()), new NullOutput()); + + $this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage An option with shortcut "e" already exists. + */ + public function testAddingOptionWithDuplicateShortcut() + { + $dispatcher = new EventDispatcher(); + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->setDispatcher($dispatcher); + + $application->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'Environment')); + + $application + ->register('foo') + ->setAliases(array('f')) + ->setDefinition(array(new InputOption('survey', 'e', InputOption::VALUE_REQUIRED, 'My option with a shortcut.'))) + ->setCode(function (InputInterface $input, OutputInterface $output) {}) + ; + + $input = new ArrayInput(array('command' => 'foo')); + $output = new NullOutput(); + + $application->run($input, $output); + } + + /** + * @expectedException \LogicException + * @dataProvider getAddingAlreadySetDefinitionElementData + */ + public function testAddingAlreadySetDefinitionElementData($def) + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application + ->register('foo') + ->setDefinition(array($def)) + ->setCode(function (InputInterface $input, OutputInterface $output) {}) + ; + + $input = new ArrayInput(array('command' => 'foo')); + $output = new NullOutput(); + $application->run($input, $output); + } + + public function getAddingAlreadySetDefinitionElementData() + { + return array( + array(new InputArgument('command', InputArgument::REQUIRED)), + array(new InputOption('quiet', '', InputOption::VALUE_NONE)), + array(new InputOption('query', 'q', InputOption::VALUE_NONE)), + ); + } + + public function testGetDefaultHelperSetReturnsDefaultValues() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $helperSet = $application->getHelperSet(); + + $this->assertTrue($helperSet->has('formatter')); + $this->assertTrue($helperSet->has('dialog')); + $this->assertTrue($helperSet->has('progress')); + } + + public function testAddingSingleHelperSetOverwritesDefaultValues() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->setHelperSet(new HelperSet(array(new FormatterHelper()))); + + $helperSet = $application->getHelperSet(); + + $this->assertTrue($helperSet->has('formatter')); + + // no other default helper set should be returned + $this->assertFalse($helperSet->has('dialog')); + $this->assertFalse($helperSet->has('progress')); + } + + public function testOverwritingDefaultHelperSetOverwritesDefaultValues() + { + $application = new CustomApplication(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->setHelperSet(new HelperSet(array(new FormatterHelper()))); + + $helperSet = $application->getHelperSet(); + + $this->assertTrue($helperSet->has('formatter')); + + // no other default helper set should be returned + $this->assertFalse($helperSet->has('dialog')); + $this->assertFalse($helperSet->has('progress')); + } + + public function testGetDefaultInputDefinitionReturnsDefaultValues() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $inputDefinition = $application->getDefinition(); + + $this->assertTrue($inputDefinition->hasArgument('command')); + + $this->assertTrue($inputDefinition->hasOption('help')); + $this->assertTrue($inputDefinition->hasOption('quiet')); + $this->assertTrue($inputDefinition->hasOption('verbose')); + $this->assertTrue($inputDefinition->hasOption('version')); + $this->assertTrue($inputDefinition->hasOption('ansi')); + $this->assertTrue($inputDefinition->hasOption('no-ansi')); + $this->assertTrue($inputDefinition->hasOption('no-interaction')); + } + + public function testOverwritingDefaultInputDefinitionOverwritesDefaultValues() + { + $application = new CustomApplication(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $inputDefinition = $application->getDefinition(); + + // check whether the default arguments and options are not returned any more + $this->assertFalse($inputDefinition->hasArgument('command')); + + $this->assertFalse($inputDefinition->hasOption('help')); + $this->assertFalse($inputDefinition->hasOption('quiet')); + $this->assertFalse($inputDefinition->hasOption('verbose')); + $this->assertFalse($inputDefinition->hasOption('version')); + $this->assertFalse($inputDefinition->hasOption('ansi')); + $this->assertFalse($inputDefinition->hasOption('no-ansi')); + $this->assertFalse($inputDefinition->hasOption('no-interaction')); + + $this->assertTrue($inputDefinition->hasOption('custom')); + } + + public function testSettingCustomInputDefinitionOverwritesDefaultValues() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->setDefinition(new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.')))); + + $inputDefinition = $application->getDefinition(); + + // check whether the default arguments and options are not returned any more + $this->assertFalse($inputDefinition->hasArgument('command')); + + $this->assertFalse($inputDefinition->hasOption('help')); + $this->assertFalse($inputDefinition->hasOption('quiet')); + $this->assertFalse($inputDefinition->hasOption('verbose')); + $this->assertFalse($inputDefinition->hasOption('version')); + $this->assertFalse($inputDefinition->hasOption('ansi')); + $this->assertFalse($inputDefinition->hasOption('no-ansi')); + $this->assertFalse($inputDefinition->hasOption('no-interaction')); + + $this->assertTrue($inputDefinition->hasOption('custom')); + } + + public function testRunWithDispatcher() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setDispatcher($this->getDispatcher()); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'foo')); + $this->assertEquals('before.foo.after.'.PHP_EOL, $tester->getDisplay()); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage caught + */ + public function testRunWithExceptionAndDispatcher() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + throw new \RuntimeException('foo'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'foo')); + } + + public function testRunDispatchesAllEventsWithException() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + + throw new \RuntimeException('foo'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'foo')); + $this->assertContains('before.foo.caught.after.', $tester->getDisplay()); + } + + public function testRunDispatchesAllEventsWithExceptionInListener() + { + $dispatcher = $this->getDispatcher(); + $dispatcher->addListener('console.command', function () { + throw new \RuntimeException('foo'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'foo')); + $this->assertContains('before.caught.after.', $tester->getDisplay()); + } + + public function testRunWithError() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('dym.'); + + throw new \Error('dymerr'); + }); + + $tester = new ApplicationTester($application); + + try { + $tester->run(array('command' => 'dym')); + $this->fail('Error expected.'); + } catch (\Error $e) { + $this->assertSame('dymerr', $e->getMessage()); + } + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage caught + */ + public function testRunWithErrorAndDispatcher() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('dym.'); + + throw new \Error('dymerr'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'dym')); + $this->assertContains('before.dym.caught.after.', $tester->getDisplay(), 'The PHP Error did not dispached events'); + } + + public function testRunDispatchesAllEventsWithError() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('dym.'); + + throw new \Error('dymerr'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'dym')); + $this->assertContains('before.dym.caught.after.', $tester->getDisplay(), 'The PHP Error did not dispached events'); + } + + public function testRunWithErrorFailingStatusCode() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + + $application->register('dus')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('dus.'); + + throw new \Error('duserr'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'dus')); + $this->assertSame(1, $tester->getStatusCode(), 'Status code should be 1'); + } + + public function testRunWithDispatcherSkippingCommand() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher(true)); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $exitCode = $tester->run(array('command' => 'foo')); + $this->assertContains('before.after.', $tester->getDisplay()); + $this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode); + } + + public function testRunWithDispatcherAccessingInputOptions() + { + $noInteractionValue = null; + $quietValue = null; + + $dispatcher = $this->getDispatcher(); + $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$noInteractionValue, &$quietValue) { + $input = $event->getInput(); + + $noInteractionValue = $input->getOption('no-interaction'); + $quietValue = $input->getOption('quiet'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'foo', '--no-interaction' => true)); + + $this->assertTrue($noInteractionValue); + $this->assertFalse($quietValue); + } + + public function testRunWithDispatcherAddingInputOptions() + { + $extraValue = null; + + $dispatcher = $this->getDispatcher(); + $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$extraValue) { + $definition = $event->getCommand()->getDefinition(); + $input = $event->getInput(); + + $definition->addOption(new InputOption('extra', null, InputOption::VALUE_REQUIRED)); + $input->bind($definition); + + $extraValue = $input->getOption('extra'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'foo', '--extra' => 'some test value')); + + $this->assertEquals('some test value', $extraValue); + } + + public function testTerminalDimensions() + { + $application = new Application(); + $originalDimensions = $application->getTerminalDimensions(); + $this->assertCount(2, $originalDimensions); + + $width = 80; + if ($originalDimensions[0] == $width) { + $width = 100; + } + + $application->setTerminalDimensions($width, 80); + $this->assertSame(array($width, 80), $application->getTerminalDimensions()); + } + + public function testSetRunCustomDefaultCommand() + { + $command = new \FooCommand(); + + $application = new Application(); + $application->setAutoExit(false); + $application->add($command); + $application->setDefaultCommand($command->getName()); + + $tester = new ApplicationTester($application); + $tester->run(array()); + $this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command'); + + $application = new CustomDefaultCommandApplication(); + $application->setAutoExit(false); + + $tester = new ApplicationTester($application); + $tester->run(array()); + + $this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command'); + } + + /** + * @requires function posix_isatty + */ + public function testCanCheckIfTerminalIsInteractive() + { + $application = new CustomDefaultCommandApplication(); + $application->setAutoExit(false); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'help')); + + $this->assertFalse($tester->getInput()->hasParameterOption(array('--no-interaction', '-n'))); + + $inputStream = $application->getHelperSet()->get('question')->getInputStream(); + $this->assertEquals($tester->getInput()->isInteractive(), @posix_isatty($inputStream)); + } + + protected function getDispatcher($skipCommand = false) + { + $dispatcher = new EventDispatcher(); + $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use ($skipCommand) { + $event->getOutput()->write('before.'); + + if ($skipCommand) { + $event->disableCommand(); + } + }); + $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($skipCommand) { + $event->getOutput()->writeln('after.'); + + if (!$skipCommand) { + $event->setExitCode(ConsoleCommandEvent::RETURN_CODE_DISABLED); + } + }); + $dispatcher->addListener('console.exception', function (ConsoleExceptionEvent $event) { + $event->getOutput()->write('caught.'); + + $event->setException(new \LogicException('caught.', $event->getExitCode(), $event->getException())); + }); + + return $dispatcher; + } + + /** + * @requires PHP 7 + */ + public function testErrorIsRethrownIfNotHandledByConsoleErrorEventWithCatchingEnabled() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setDispatcher(new EventDispatcher()); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + new \UnknownClass(); + }); + + $tester = new ApplicationTester($application); + + try { + $tester->run(array('command' => 'dym')); + $this->fail('->run() should rethrow PHP errors if not handled via ConsoleErrorEvent.'); + } catch (\Error $e) { + $this->assertSame($e->getMessage(), 'Class \'UnknownClass\' not found'); + } + } +} + +class CustomApplication extends Application +{ + /** + * Overwrites the default input definition. + * + * @return InputDefinition An InputDefinition instance + */ + protected function getDefaultInputDefinition() + { + return new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.'))); + } + + /** + * Gets the default helper set with the helpers that should always be available. + * + * @return HelperSet A HelperSet instance + */ + protected function getDefaultHelperSet() + { + return new HelperSet(array(new FormatterHelper())); + } +} + +class CustomDefaultCommandApplication extends Application +{ + /** + * Overwrites the constructor in order to set a different default command. + */ + public function __construct() + { + parent::__construct(); + + $command = new \FooCommand(); + $this->add($command); + $this->setDefaultCommand($command->getName()); + } +} diff --git a/vendor/symfony/console/Tests/Command/CommandTest.php b/vendor/symfony/console/Tests/Command/CommandTest.php new file mode 100644 index 000000000..ac4aa22fb --- /dev/null +++ b/vendor/symfony/console/Tests/Command/CommandTest.php @@ -0,0 +1,462 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\StringInput; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\Console\Tester\CommandTester; + +class CommandTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = __DIR__.'/../Fixtures/'; + require_once self::$fixturesPath.'/TestCommand.php'; + } + + public function testConstructor() + { + $command = new Command('foo:bar'); + $this->assertEquals('foo:bar', $command->getName(), '__construct() takes the command name as its first argument'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage The command defined in "Symfony\Component\Console\Command\Command" cannot have an empty name. + */ + public function testCommandNameCannotBeEmpty() + { + new Command(); + } + + public function testSetApplication() + { + $application = new Application(); + $command = new \TestCommand(); + $command->setApplication($application); + $this->assertEquals($application, $command->getApplication(), '->setApplication() sets the current application'); + $this->assertEquals($application->getHelperSet(), $command->getHelperSet()); + } + + public function testSetApplicationNull() + { + $command = new \TestCommand(); + $command->setApplication(null); + $this->assertNull($command->getHelperSet()); + } + + public function testSetGetDefinition() + { + $command = new \TestCommand(); + $ret = $command->setDefinition($definition = new InputDefinition()); + $this->assertEquals($command, $ret, '->setDefinition() implements a fluent interface'); + $this->assertEquals($definition, $command->getDefinition(), '->setDefinition() sets the current InputDefinition instance'); + $command->setDefinition(array(new InputArgument('foo'), new InputOption('bar'))); + $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument'); + $this->assertTrue($command->getDefinition()->hasOption('bar'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument'); + $command->setDefinition(new InputDefinition()); + } + + public function testAddArgument() + { + $command = new \TestCommand(); + $ret = $command->addArgument('foo'); + $this->assertEquals($command, $ret, '->addArgument() implements a fluent interface'); + $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->addArgument() adds an argument to the command'); + } + + public function testAddOption() + { + $command = new \TestCommand(); + $ret = $command->addOption('foo'); + $this->assertEquals($command, $ret, '->addOption() implements a fluent interface'); + $this->assertTrue($command->getDefinition()->hasOption('foo'), '->addOption() adds an option to the command'); + } + + public function testGetNamespaceGetNameSetName() + { + $command = new \TestCommand(); + $this->assertEquals('namespace:name', $command->getName(), '->getName() returns the command name'); + $command->setName('foo'); + $this->assertEquals('foo', $command->getName(), '->setName() sets the command name'); + + $ret = $command->setName('foobar:bar'); + $this->assertEquals($command, $ret, '->setName() implements a fluent interface'); + $this->assertEquals('foobar:bar', $command->getName(), '->setName() sets the command name'); + } + + /** + * @dataProvider provideInvalidCommandNames + */ + public function testInvalidCommandNames($name) + { + if (method_exists($this, 'expectException')) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage(sprintf('Command name "%s" is invalid.', $name)); + } else { + $this->setExpectedException('InvalidArgumentException', sprintf('Command name "%s" is invalid.', $name)); + } + + $command = new \TestCommand(); + $command->setName($name); + } + + public function provideInvalidCommandNames() + { + return array( + array(''), + array('foo:'), + ); + } + + public function testGetSetDescription() + { + $command = new \TestCommand(); + $this->assertEquals('description', $command->getDescription(), '->getDescription() returns the description'); + $ret = $command->setDescription('description1'); + $this->assertEquals($command, $ret, '->setDescription() implements a fluent interface'); + $this->assertEquals('description1', $command->getDescription(), '->setDescription() sets the description'); + } + + public function testGetSetHelp() + { + $command = new \TestCommand(); + $this->assertEquals('help', $command->getHelp(), '->getHelp() returns the help'); + $ret = $command->setHelp('help1'); + $this->assertEquals($command, $ret, '->setHelp() implements a fluent interface'); + $this->assertEquals('help1', $command->getHelp(), '->setHelp() sets the help'); + $command->setHelp(''); + $this->assertEquals('', $command->getHelp(), '->getHelp() does not fall back to the description'); + } + + public function testGetProcessedHelp() + { + $command = new \TestCommand(); + $command->setHelp('The %command.name% command does... Example: php %command.full_name%.'); + $this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly'); + $this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name%'); + + $command = new \TestCommand(); + $command->setHelp(''); + $this->assertContains('description', $command->getProcessedHelp(), '->getProcessedHelp() falls back to the description'); + } + + public function testGetSetAliases() + { + $command = new \TestCommand(); + $this->assertEquals(array('name'), $command->getAliases(), '->getAliases() returns the aliases'); + $ret = $command->setAliases(array('name1')); + $this->assertEquals($command, $ret, '->setAliases() implements a fluent interface'); + $this->assertEquals(array('name1'), $command->getAliases(), '->setAliases() sets the aliases'); + } + + public function testSetAliasesNull() + { + $command = new \TestCommand(); + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException'); + $command->setAliases(null); + } + + public function testGetSynopsis() + { + $command = new \TestCommand(); + $command->addOption('foo'); + $command->addArgument('bar'); + $this->assertEquals('namespace:name [--foo] [--] []', $command->getSynopsis(), '->getSynopsis() returns the synopsis'); + } + + public function testAddGetUsages() + { + $command = new \TestCommand(); + $command->addUsage('foo1'); + $command->addUsage('foo2'); + $this->assertContains('namespace:name foo1', $command->getUsages()); + $this->assertContains('namespace:name foo2', $command->getUsages()); + } + + public function testGetHelper() + { + $application = new Application(); + $command = new \TestCommand(); + $command->setApplication($application); + $formatterHelper = new FormatterHelper(); + $this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->getHelper() returns the correct helper'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot retrieve helper "formatter" because there is no HelperSet defined. + */ + public function testGetHelperWithoutHelperSet() + { + $command = new \TestCommand(); + $command->getHelper('formatter'); + } + + public function testMergeApplicationDefinition() + { + $application1 = new Application(); + $application1->getDefinition()->addArguments(array(new InputArgument('foo'))); + $application1->getDefinition()->addOptions(array(new InputOption('bar'))); + $command = new \TestCommand(); + $command->setApplication($application1); + $command->setDefinition($definition = new InputDefinition(array(new InputArgument('bar'), new InputOption('foo')))); + + $r = new \ReflectionObject($command); + $m = $r->getMethod('mergeApplicationDefinition'); + $m->setAccessible(true); + $m->invoke($command); + $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition() merges the application arguments and the command arguments'); + $this->assertTrue($command->getDefinition()->hasArgument('bar'), '->mergeApplicationDefinition() merges the application arguments and the command arguments'); + $this->assertTrue($command->getDefinition()->hasOption('foo'), '->mergeApplicationDefinition() merges the application options and the command options'); + $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition() merges the application options and the command options'); + + $m->invoke($command); + $this->assertEquals(3, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments and options'); + } + + public function testMergeApplicationDefinitionWithoutArgsThenWithArgsAddsArgs() + { + $application1 = new Application(); + $application1->getDefinition()->addArguments(array(new InputArgument('foo'))); + $application1->getDefinition()->addOptions(array(new InputOption('bar'))); + $command = new \TestCommand(); + $command->setApplication($application1); + $command->setDefinition($definition = new InputDefinition(array())); + + $r = new \ReflectionObject($command); + $m = $r->getMethod('mergeApplicationDefinition'); + $m->setAccessible(true); + $m->invoke($command, false); + $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition(false) merges the application and the command options'); + $this->assertFalse($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(false) does not merge the application arguments'); + + $m->invoke($command, true); + $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(true) merges the application arguments and the command arguments'); + + $m->invoke($command); + $this->assertEquals(2, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments'); + } + + public function testRunInteractive() + { + $tester = new CommandTester(new \TestCommand()); + + $tester->execute(array(), array('interactive' => true)); + + $this->assertEquals('interact called'.PHP_EOL.'execute called'.PHP_EOL, $tester->getDisplay(), '->run() calls the interact() method if the input is interactive'); + } + + public function testRunNonInteractive() + { + $tester = new CommandTester(new \TestCommand()); + + $tester->execute(array(), array('interactive' => false)); + + $this->assertEquals('execute called'.PHP_EOL, $tester->getDisplay(), '->run() does not call the interact() method if the input is not interactive'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage You must override the execute() method in the concrete command class. + */ + public function testExecuteMethodNeedsToBeOverridden() + { + $command = new Command('foo'); + $command->run(new StringInput(''), new NullOutput()); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\InvalidOptionException + * @expectedExceptionMessage The "--bar" option does not exist. + */ + public function testRunWithInvalidOption() + { + $command = new \TestCommand(); + $tester = new CommandTester($command); + $tester->execute(array('--bar' => true)); + } + + public function testRunReturnsIntegerExitCode() + { + $command = new \TestCommand(); + $exitCode = $command->run(new StringInput(''), new NullOutput()); + $this->assertSame(0, $exitCode, '->run() returns integer exit code (treats null as 0)'); + + $command = $this->getMockBuilder('TestCommand')->setMethods(array('execute'))->getMock(); + $command->expects($this->once()) + ->method('execute') + ->will($this->returnValue('2.3')); + $exitCode = $command->run(new StringInput(''), new NullOutput()); + $this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)'); + } + + public function testRunWithApplication() + { + $command = new \TestCommand(); + $command->setApplication(new Application()); + $exitCode = $command->run(new StringInput(''), new NullOutput()); + + $this->assertSame(0, $exitCode, '->run() returns an integer exit code'); + } + + public function testRunReturnsAlwaysInteger() + { + $command = new \TestCommand(); + + $this->assertSame(0, $command->run(new StringInput(''), new NullOutput())); + } + + public function testRunWithProcessTitle() + { + $command = new \TestCommand(); + $command->setApplication(new Application()); + $command->setProcessTitle('foo'); + $this->assertSame(0, $command->run(new StringInput(''), new NullOutput())); + if (function_exists('cli_set_process_title')) { + if (null === @cli_get_process_title() && 'Darwin' === PHP_OS) { + $this->markTestSkipped('Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.'); + } + $this->assertEquals('foo', cli_get_process_title()); + } + } + + public function testSetCode() + { + $command = new \TestCommand(); + $ret = $command->setCode(function (InputInterface $input, OutputInterface $output) { + $output->writeln('from the code...'); + }); + $this->assertEquals($command, $ret, '->setCode() implements a fluent interface'); + $tester = new CommandTester($command); + $tester->execute(array()); + $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay()); + } + + public function getSetCodeBindToClosureTests() + { + return array( + array(true, 'not bound to the command'), + array(false, 'bound to the command'), + ); + } + + /** + * @dataProvider getSetCodeBindToClosureTests + * @requires PHP 5.4 + */ + public function testSetCodeBindToClosure($previouslyBound, $expected) + { + $code = createClosure(); + if ($previouslyBound) { + $code = $code->bindTo($this); + } + + $command = new \TestCommand(); + $command->setCode($code); + $tester = new CommandTester($command); + $tester->execute(array()); + $this->assertEquals('interact called'.PHP_EOL.$expected.PHP_EOL, $tester->getDisplay()); + } + + public function testSetCodeWithStaticClosure() + { + $command = new \TestCommand(); + $command->setCode(self::createClosure()); + $tester = new CommandTester($command); + $tester->execute(array()); + + if (\PHP_VERSION_ID < 70000) { + // Cannot bind static closures in PHP 5 + $this->assertEquals('interact called'.PHP_EOL.'not bound'.PHP_EOL, $tester->getDisplay()); + } else { + // Can bind static closures in PHP 7 + $this->assertEquals('interact called'.PHP_EOL.'bound'.PHP_EOL, $tester->getDisplay()); + } + } + + private static function createClosure() + { + return function (InputInterface $input, OutputInterface $output) { + $output->writeln(isset($this) ? 'bound' : 'not bound'); + }; + } + + public function testSetCodeWithNonClosureCallable() + { + $command = new \TestCommand(); + $ret = $command->setCode(array($this, 'callableMethodCommand')); + $this->assertEquals($command, $ret, '->setCode() implements a fluent interface'); + $tester = new CommandTester($command); + $tester->execute(array()); + $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay()); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid callable provided to Command::setCode. + */ + public function testSetCodeWithNonCallable() + { + $command = new \TestCommand(); + $command->setCode(array($this, 'nonExistentMethod')); + } + + public function callableMethodCommand(InputInterface $input, OutputInterface $output) + { + $output->writeln('from the code...'); + } + + /** + * @group legacy + */ + public function testLegacyAsText() + { + $command = new \TestCommand(); + $command->setApplication(new Application()); + $tester = new CommandTester($command); + $tester->execute(array('command' => $command->getName())); + $this->assertStringEqualsFile(self::$fixturesPath.'/command_astext.txt', $command->asText(), '->asText() returns a text representation of the command'); + } + + /** + * @group legacy + */ + public function testLegacyAsXml() + { + $command = new \TestCommand(); + $command->setApplication(new Application()); + $tester = new CommandTester($command); + $tester->execute(array('command' => $command->getName())); + $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/command_asxml.txt', $command->asXml(), '->asXml() returns an XML representation of the command'); + } +} + +// In order to get an unbound closure, we should create it outside a class +// scope. +function createClosure() +{ + return function (InputInterface $input, OutputInterface $output) { + $output->writeln($this instanceof Command ? 'bound to the command' : 'not bound to the command'); + }; +} diff --git a/vendor/symfony/console/Tests/Command/HelpCommandTest.php b/vendor/symfony/console/Tests/Command/HelpCommandTest.php new file mode 100644 index 000000000..a4e032a27 --- /dev/null +++ b/vendor/symfony/console/Tests/Command/HelpCommandTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\Console\Command\HelpCommand; +use Symfony\Component\Console\Command\ListCommand; +use Symfony\Component\Console\Application; + +class HelpCommandTest extends TestCase +{ + public function testExecuteForCommandAlias() + { + $command = new HelpCommand(); + $command->setApplication(new Application()); + $commandTester = new CommandTester($command); + $commandTester->execute(array('command_name' => 'li'), array('decorated' => false)); + $this->assertContains('list [options] [--] []', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias'); + $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias'); + $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias'); + } + + public function testExecuteForCommand() + { + $command = new HelpCommand(); + $commandTester = new CommandTester($command); + $command->setCommand(new ListCommand()); + $commandTester->execute(array(), array('decorated' => false)); + $this->assertContains('list [options] [--] []', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + } + + public function testExecuteForCommandWithXmlOption() + { + $command = new HelpCommand(); + $commandTester = new CommandTester($command); + $command->setCommand(new ListCommand()); + $commandTester->execute(array('--format' => 'xml')); + $this->assertContains('getDisplay(), '->execute() returns an XML help text if --xml is passed'); + } + + public function testExecuteForApplicationCommand() + { + $application = new Application(); + $commandTester = new CommandTester($application->get('help')); + $commandTester->execute(array('command_name' => 'list')); + $this->assertContains('list [options] [--] []', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + } + + public function testExecuteForApplicationCommandWithXmlOption() + { + $application = new Application(); + $commandTester = new CommandTester($application->get('help')); + $commandTester->execute(array('command_name' => 'list', '--format' => 'xml')); + $this->assertContains('list [--xml] [--raw] [--format FORMAT] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('getDisplay(), '->execute() returns an XML help text if --format=xml is passed'); + } +} diff --git a/vendor/symfony/console/Tests/Command/ListCommandTest.php b/vendor/symfony/console/Tests/Command/ListCommandTest.php new file mode 100644 index 000000000..fb6ee3bba --- /dev/null +++ b/vendor/symfony/console/Tests/Command/ListCommandTest.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\Console\Application; + +class ListCommandTest extends TestCase +{ + public function testExecuteListsCommands() + { + $application = new Application(); + $commandTester = new CommandTester($command = $application->get('list')); + $commandTester->execute(array('command' => $command->getName()), array('decorated' => false)); + + $this->assertRegExp('/help\s{2,}Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands'); + } + + public function testExecuteListsCommandsWithXmlOption() + { + $application = new Application(); + $commandTester = new CommandTester($command = $application->get('list')); + $commandTester->execute(array('command' => $command->getName(), '--format' => 'xml')); + $this->assertRegExp('//', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed'); + } + + public function testExecuteListsCommandsWithRawOption() + { + $application = new Application(); + $commandTester = new CommandTester($command = $application->get('list')); + $commandTester->execute(array('command' => $command->getName(), '--raw' => true)); + $output = <<<'EOF' +help Displays help for a command +list Lists commands + +EOF; + + $this->assertEquals($output, $commandTester->getDisplay(true)); + } + + public function testExecuteListsCommandsWithNamespaceArgument() + { + require_once realpath(__DIR__.'/../Fixtures/FooCommand.php'); + $application = new Application(); + $application->add(new \FooCommand()); + $commandTester = new CommandTester($command = $application->get('list')); + $commandTester->execute(array('command' => $command->getName(), 'namespace' => 'foo', '--raw' => true)); + $output = <<<'EOF' +foo:bar The foo:bar command + +EOF; + + $this->assertEquals($output, $commandTester->getDisplay(true)); + } + + public function testExecuteListsCommandsOrder() + { + require_once realpath(__DIR__.'/../Fixtures/Foo6Command.php'); + $application = new Application(); + $application->add(new \Foo6Command()); + $commandTester = new CommandTester($command = $application->get('list')); + $commandTester->execute(array('command' => $command->getName()), array('decorated' => false)); + $output = <<<'EOF' +Console Tool + +Usage: + command [options] [arguments] + +Options: + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Available commands: + help Displays help for a command + list Lists commands + 0foo + 0foo:bar 0foo:bar command +EOF; + + $this->assertEquals($output, trim($commandTester->getDisplay(true))); + } + + public function testExecuteListsCommandsOrderRaw() + { + require_once realpath(__DIR__.'/../Fixtures/Foo6Command.php'); + $application = new Application(); + $application->add(new \Foo6Command()); + $commandTester = new CommandTester($command = $application->get('list')); + $commandTester->execute(array('command' => $command->getName(), '--raw' => true)); + $output = <<<'EOF' +help Displays help for a command +list Lists commands +0foo:bar 0foo:bar command +EOF; + + $this->assertEquals($output, trim($commandTester->getDisplay(true))); + } +} diff --git a/vendor/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php b/vendor/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php new file mode 100644 index 000000000..fcbb719b6 --- /dev/null +++ b/vendor/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Descriptor; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\BufferedOutput; + +abstract class AbstractDescriptorTest extends TestCase +{ + /** @dataProvider getDescribeInputArgumentTestData */ + public function testDescribeInputArgument(InputArgument $argument, $expectedDescription) + { + $this->assertDescription($expectedDescription, $argument); + } + + /** @dataProvider getDescribeInputOptionTestData */ + public function testDescribeInputOption(InputOption $option, $expectedDescription) + { + $this->assertDescription($expectedDescription, $option); + } + + /** @dataProvider getDescribeInputDefinitionTestData */ + public function testDescribeInputDefinition(InputDefinition $definition, $expectedDescription) + { + $this->assertDescription($expectedDescription, $definition); + } + + /** @dataProvider getDescribeCommandTestData */ + public function testDescribeCommand(Command $command, $expectedDescription) + { + $this->assertDescription($expectedDescription, $command); + } + + /** @dataProvider getDescribeApplicationTestData */ + public function testDescribeApplication(Application $application, $expectedDescription) + { + // Replaces the dynamic placeholders of the command help text with a static version. + // The placeholder %command.full_name% includes the script path that is not predictable + // and can not be tested against. + foreach ($application->all() as $command) { + $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp())); + } + + $this->assertDescription($expectedDescription, $application); + } + + public function getDescribeInputArgumentTestData() + { + return $this->getDescriptionTestData(ObjectsProvider::getInputArguments()); + } + + public function getDescribeInputOptionTestData() + { + return $this->getDescriptionTestData(ObjectsProvider::getInputOptions()); + } + + public function getDescribeInputDefinitionTestData() + { + return $this->getDescriptionTestData(ObjectsProvider::getInputDefinitions()); + } + + public function getDescribeCommandTestData() + { + return $this->getDescriptionTestData(ObjectsProvider::getCommands()); + } + + public function getDescribeApplicationTestData() + { + return $this->getDescriptionTestData(ObjectsProvider::getApplications()); + } + + abstract protected function getDescriptor(); + + abstract protected function getFormat(); + + protected function getDescriptionTestData(array $objects) + { + $data = array(); + foreach ($objects as $name => $object) { + $description = file_get_contents(sprintf('%s/../Fixtures/%s.%s', __DIR__, $name, $this->getFormat())); + $data[] = array($object, $description); + } + + return $data; + } + + protected function assertDescription($expectedDescription, $describedObject) + { + $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true); + $this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true)); + $this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $output->fetch()))); + } +} diff --git a/vendor/symfony/console/Tests/Descriptor/JsonDescriptorTest.php b/vendor/symfony/console/Tests/Descriptor/JsonDescriptorTest.php new file mode 100644 index 000000000..f9a15612b --- /dev/null +++ b/vendor/symfony/console/Tests/Descriptor/JsonDescriptorTest.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Descriptor; + +use Symfony\Component\Console\Descriptor\JsonDescriptor; +use Symfony\Component\Console\Output\BufferedOutput; + +class JsonDescriptorTest extends AbstractDescriptorTest +{ + protected function getDescriptor() + { + return new JsonDescriptor(); + } + + protected function getFormat() + { + return 'json'; + } + + protected function assertDescription($expectedDescription, $describedObject) + { + $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true); + $this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true)); + $this->assertEquals(json_decode(trim($expectedDescription), true), json_decode(trim(str_replace(PHP_EOL, "\n", $output->fetch())), true)); + } +} diff --git a/vendor/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.php b/vendor/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.php new file mode 100644 index 000000000..eb80f58b1 --- /dev/null +++ b/vendor/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Descriptor; + +use Symfony\Component\Console\Descriptor\MarkdownDescriptor; +use Symfony\Component\Console\Tests\Fixtures\DescriptorApplicationMbString; +use Symfony\Component\Console\Tests\Fixtures\DescriptorCommandMbString; + +class MarkdownDescriptorTest extends AbstractDescriptorTest +{ + public function getDescribeCommandTestData() + { + return $this->getDescriptionTestData(array_merge( + ObjectsProvider::getCommands(), + array('command_mbstring' => new DescriptorCommandMbString()) + )); + } + + public function getDescribeApplicationTestData() + { + return $this->getDescriptionTestData(array_merge( + ObjectsProvider::getApplications(), + array('application_mbstring' => new DescriptorApplicationMbString()) + )); + } + + protected function getDescriptor() + { + return new MarkdownDescriptor(); + } + + protected function getFormat() + { + return 'md'; + } +} diff --git a/vendor/symfony/console/Tests/Descriptor/ObjectsProvider.php b/vendor/symfony/console/Tests/Descriptor/ObjectsProvider.php new file mode 100644 index 000000000..8f825ecb6 --- /dev/null +++ b/vendor/symfony/console/Tests/Descriptor/ObjectsProvider.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Descriptor; + +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication1; +use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication2; +use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand1; +use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand2; + +/** + * @author Jean-François Simon + */ +class ObjectsProvider +{ + public static function getInputArguments() + { + return array( + 'input_argument_1' => new InputArgument('argument_name', InputArgument::REQUIRED), + 'input_argument_2' => new InputArgument('argument_name', InputArgument::IS_ARRAY, 'argument description'), + 'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'), + 'input_argument_4' => new InputArgument('argument_name', InputArgument::REQUIRED, "multiline\nargument description"), + 'input_argument_with_style' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'style'), + ); + } + + public static function getInputOptions() + { + return array( + 'input_option_1' => new InputOption('option_name', 'o', InputOption::VALUE_NONE), + 'input_option_2' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', 'default_value'), + 'input_option_3' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description'), + 'input_option_4' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'option description', array()), + 'input_option_5' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, "multiline\noption description"), + 'input_option_6' => new InputOption('option_name', array('o', 'O'), InputOption::VALUE_REQUIRED, 'option with multiple shortcuts'), + 'input_option_with_style' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description', 'style'), + 'input_option_with_style_array' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'option description', array('Hello', 'world')), + ); + } + + public static function getInputDefinitions() + { + return array( + 'input_definition_1' => new InputDefinition(), + 'input_definition_2' => new InputDefinition(array(new InputArgument('argument_name', InputArgument::REQUIRED))), + 'input_definition_3' => new InputDefinition(array(new InputOption('option_name', 'o', InputOption::VALUE_NONE))), + 'input_definition_4' => new InputDefinition(array( + new InputArgument('argument_name', InputArgument::REQUIRED), + new InputOption('option_name', 'o', InputOption::VALUE_NONE), + )), + ); + } + + public static function getCommands() + { + return array( + 'command_1' => new DescriptorCommand1(), + 'command_2' => new DescriptorCommand2(), + ); + } + + public static function getApplications() + { + return array( + 'application_1' => new DescriptorApplication1(), + 'application_2' => new DescriptorApplication2(), + ); + } +} diff --git a/vendor/symfony/console/Tests/Descriptor/TextDescriptorTest.php b/vendor/symfony/console/Tests/Descriptor/TextDescriptorTest.php new file mode 100644 index 000000000..364e29c02 --- /dev/null +++ b/vendor/symfony/console/Tests/Descriptor/TextDescriptorTest.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Descriptor; + +use Symfony\Component\Console\Descriptor\TextDescriptor; +use Symfony\Component\Console\Tests\Fixtures\DescriptorApplicationMbString; +use Symfony\Component\Console\Tests\Fixtures\DescriptorCommandMbString; + +class TextDescriptorTest extends AbstractDescriptorTest +{ + public function getDescribeCommandTestData() + { + return $this->getDescriptionTestData(array_merge( + ObjectsProvider::getCommands(), + array('command_mbstring' => new DescriptorCommandMbString()) + )); + } + + public function getDescribeApplicationTestData() + { + return $this->getDescriptionTestData(array_merge( + ObjectsProvider::getApplications(), + array('application_mbstring' => new DescriptorApplicationMbString()) + )); + } + + protected function getDescriptor() + { + return new TextDescriptor(); + } + + protected function getFormat() + { + return 'txt'; + } +} diff --git a/vendor/symfony/console/Tests/Descriptor/XmlDescriptorTest.php b/vendor/symfony/console/Tests/Descriptor/XmlDescriptorTest.php new file mode 100644 index 000000000..59a5d1ed8 --- /dev/null +++ b/vendor/symfony/console/Tests/Descriptor/XmlDescriptorTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Descriptor; + +use Symfony\Component\Console\Descriptor\XmlDescriptor; + +class XmlDescriptorTest extends AbstractDescriptorTest +{ + protected function getDescriptor() + { + return new XmlDescriptor(); + } + + protected function getFormat() + { + return 'xml'; + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/BarBucCommand.php b/vendor/symfony/console/Tests/Fixtures/BarBucCommand.php new file mode 100644 index 000000000..52b619e82 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/BarBucCommand.php @@ -0,0 +1,11 @@ +setName('bar:buc'); + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/DescriptorApplication1.php b/vendor/symfony/console/Tests/Fixtures/DescriptorApplication1.php new file mode 100644 index 000000000..132b6d57d --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/DescriptorApplication1.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Fixtures; + +use Symfony\Component\Console\Application; + +class DescriptorApplication1 extends Application +{ +} diff --git a/vendor/symfony/console/Tests/Fixtures/DescriptorApplication2.php b/vendor/symfony/console/Tests/Fixtures/DescriptorApplication2.php new file mode 100644 index 000000000..ff5513580 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/DescriptorApplication2.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Fixtures; + +use Symfony\Component\Console\Application; + +class DescriptorApplication2 extends Application +{ + public function __construct() + { + parent::__construct('My Symfony application', 'v1.0'); + $this->add(new DescriptorCommand1()); + $this->add(new DescriptorCommand2()); + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/DescriptorApplicationMbString.php b/vendor/symfony/console/Tests/Fixtures/DescriptorApplicationMbString.php new file mode 100644 index 000000000..bf170c449 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/DescriptorApplicationMbString.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Fixtures; + +use Symfony\Component\Console\Application; + +class DescriptorApplicationMbString extends Application +{ + public function __construct() + { + parent::__construct('MbString åpplicätion'); + + $this->add(new DescriptorCommandMbString()); + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/DescriptorCommand1.php b/vendor/symfony/console/Tests/Fixtures/DescriptorCommand1.php new file mode 100644 index 000000000..ede05d7a7 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/DescriptorCommand1.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Fixtures; + +use Symfony\Component\Console\Command\Command; + +class DescriptorCommand1 extends Command +{ + protected function configure() + { + $this + ->setName('descriptor:command1') + ->setAliases(array('alias1', 'alias2')) + ->setDescription('command 1 description') + ->setHelp('command 1 help') + ; + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/DescriptorCommand2.php b/vendor/symfony/console/Tests/Fixtures/DescriptorCommand2.php new file mode 100644 index 000000000..51106b961 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/DescriptorCommand2.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Fixtures; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; + +class DescriptorCommand2 extends Command +{ + protected function configure() + { + $this + ->setName('descriptor:command2') + ->setDescription('command 2 description') + ->setHelp('command 2 help') + ->addUsage('-o|--option_name ') + ->addUsage('') + ->addArgument('argument_name', InputArgument::REQUIRED) + ->addOption('option_name', 'o', InputOption::VALUE_NONE) + ; + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/DescriptorCommandMbString.php b/vendor/symfony/console/Tests/Fixtures/DescriptorCommandMbString.php new file mode 100644 index 000000000..66de917e2 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/DescriptorCommandMbString.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Fixtures; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; + +class DescriptorCommandMbString extends Command +{ + protected function configure() + { + $this + ->setName('descriptor:åèä') + ->setDescription('command åèä description') + ->setHelp('command åèä help') + ->addUsage('-o|--option_name ') + ->addUsage('') + ->addArgument('argument_åèä', InputArgument::REQUIRED) + ->addOption('option_åèä', 'o', InputOption::VALUE_NONE) + ; + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/DummyOutput.php b/vendor/symfony/console/Tests/Fixtures/DummyOutput.php new file mode 100644 index 000000000..866e21437 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/DummyOutput.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Fixtures; + +use Symfony\Component\Console\Output\BufferedOutput; + +/** + * Dummy output. + * + * @author Kévin Dunglas + */ +class DummyOutput extends BufferedOutput +{ + /** + * @return array + */ + public function getLogs() + { + $logs = array(); + foreach (explode(PHP_EOL, trim($this->fetch())) as $message) { + preg_match('/^\[(.*)\] (.*)/', $message, $matches); + $logs[] = sprintf('%s %s', $matches[1], $matches[2]); + } + + return $logs; + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/Foo1Command.php b/vendor/symfony/console/Tests/Fixtures/Foo1Command.php new file mode 100644 index 000000000..254162f32 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Foo1Command.php @@ -0,0 +1,26 @@ +setName('foo:bar1') + ->setDescription('The foo:bar1 command') + ->setAliases(array('afoobar1')) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->output = $output; + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/Foo2Command.php b/vendor/symfony/console/Tests/Fixtures/Foo2Command.php new file mode 100644 index 000000000..8071dc8fb --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Foo2Command.php @@ -0,0 +1,21 @@ +setName('foo1:bar') + ->setDescription('The foo1:bar command') + ->setAliases(array('afoobar2')) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/Foo3Command.php b/vendor/symfony/console/Tests/Fixtures/Foo3Command.php new file mode 100644 index 000000000..6c890faff --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Foo3Command.php @@ -0,0 +1,29 @@ +setName('foo3:bar') + ->setDescription('The foo3:bar command') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + try { + throw new \Exception('First exception

this is html

'); + } catch (\Exception $e) { + throw new \Exception('Second exception comment', 0, $e); + } + } catch (\Exception $e) { + throw new \Exception('Third exception comment', 0, $e); + } + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/Foo4Command.php b/vendor/symfony/console/Tests/Fixtures/Foo4Command.php new file mode 100644 index 000000000..1c5463995 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Foo4Command.php @@ -0,0 +1,11 @@ +setName('foo3:bar:toh'); + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/Foo5Command.php b/vendor/symfony/console/Tests/Fixtures/Foo5Command.php new file mode 100644 index 000000000..a1c60827a --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Foo5Command.php @@ -0,0 +1,10 @@ +setName('0foo:bar')->setDescription('0foo:bar command'); + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/FooCommand.php b/vendor/symfony/console/Tests/Fixtures/FooCommand.php new file mode 100644 index 000000000..355e0ad6d --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/FooCommand.php @@ -0,0 +1,33 @@ +setName('foo:bar') + ->setDescription('The foo:bar command') + ->setAliases(array('afoobar')) + ; + } + + protected function interact(InputInterface $input, OutputInterface $output) + { + $output->writeln('interact called'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->output = $output; + + $output->writeln('called'); + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced1Command.php b/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced1Command.php new file mode 100644 index 000000000..fc50c72bf --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced1Command.php @@ -0,0 +1,26 @@ +setName('foo:bar:baz') + ->setDescription('The foo:bar:baz command') + ->setAliases(array('foobarbaz')) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->output = $output; + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced2Command.php b/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced2Command.php new file mode 100644 index 000000000..1cf31ff11 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced2Command.php @@ -0,0 +1,26 @@ +setName('foo:go:bret') + ->setDescription('The foo:bar:go command') + ->setAliases(array('foobargo')) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->output = $output; + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/FoobarCommand.php b/vendor/symfony/console/Tests/Fixtures/FoobarCommand.php new file mode 100644 index 000000000..968162804 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/FoobarCommand.php @@ -0,0 +1,25 @@ +setName('foobar:foo') + ->setDescription('The foobar:foo command') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->output = $output; + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.php new file mode 100644 index 000000000..996fafb98 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.php @@ -0,0 +1,11 @@ +caution('Lorem ipsum dolor sit amet'); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php new file mode 100644 index 000000000..6634cd569 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php @@ -0,0 +1,13 @@ +title('Title'); + $output->warning('Lorem ipsum dolor sit amet'); + $output->title('Title'); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php new file mode 100644 index 000000000..4120df9cb --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php @@ -0,0 +1,17 @@ +block( + 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum', + 'CUSTOM', + 'fg=white;bg=green', + 'X ', + true + ); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.php new file mode 100644 index 000000000..678afea5d --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.php @@ -0,0 +1,12 @@ +block($word, 'CUSTOM', 'fg=white;bg=blue', ' § ', false); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_12.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_12.php new file mode 100644 index 000000000..4386e56de --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_12.php @@ -0,0 +1,13 @@ +comment( + 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum' + ); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_13.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_13.php new file mode 100644 index 000000000..fe084365f --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_13.php @@ -0,0 +1,15 @@ +setDecorated(true); + $output = new SymfonyStyle($input, $output); + $output->comment( + 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum' + ); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_14.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_14.php new file mode 100644 index 000000000..e719f7181 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_14.php @@ -0,0 +1,17 @@ +block( + 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum', + null, + null, + '$ ', + true + ); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_15.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_15.php new file mode 100644 index 000000000..29e555b04 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_15.php @@ -0,0 +1,14 @@ +block( + 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum', + 'TEST' + ); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_16.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_16.php new file mode 100644 index 000000000..f21fc10d9 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_16.php @@ -0,0 +1,15 @@ +setDecorated(true); + $output = new SymfonyStyleWithForcedLineLength($input, $output); + $output->success( + 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum', + 'TEST' + ); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_17.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_17.php new file mode 100644 index 000000000..e6a13558d --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_17.php @@ -0,0 +1,13 @@ +title('Title ending with \\'); + $output->section('Section ending with \\'); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php new file mode 100644 index 000000000..6004e3d6c --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php @@ -0,0 +1,16 @@ +warning('Warning'); + $output->caution('Caution'); + $output->error('Error'); + $output->success('Success'); + $output->note('Note'); + $output->block('Custom block', 'CUSTOM', 'fg=white;bg=green', 'X ', true); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php new file mode 100644 index 000000000..c7a08f138 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php @@ -0,0 +1,12 @@ +title('First title'); + $output->title('Second title'); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php new file mode 100644 index 000000000..afea70c7a --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php @@ -0,0 +1,34 @@ +write('Lorem ipsum dolor sit amet'); + $output->title('First title'); + + $output->writeln('Lorem ipsum dolor sit amet'); + $output->title('Second title'); + + $output->write('Lorem ipsum dolor sit amet'); + $output->write(''); + $output->title('Third title'); + + //Ensure edge case by appending empty strings to history: + $output->write('Lorem ipsum dolor sit amet'); + $output->write(array('', '', '')); + $output->title('Fourth title'); + + //Ensure have manual control over number of blank lines: + $output->writeln('Lorem ipsum dolor sit amet'); + $output->writeln(array('', '')); //Should append an extra blank line + $output->title('Fifth title'); + + $output->writeln('Lorem ipsum dolor sit amet'); + $output->newLine(2); //Should append an extra blank line + $output->title('Fifth title'); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php new file mode 100644 index 000000000..b1c42b0d7 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php @@ -0,0 +1,37 @@ +writeln('Lorem ipsum dolor sit amet'); + $output->listing(array( + 'Lorem ipsum dolor sit amet', + 'consectetur adipiscing elit', + )); + + //Even using write: + $output->write('Lorem ipsum dolor sit amet'); + $output->listing(array( + 'Lorem ipsum dolor sit amet', + 'consectetur adipiscing elit', + )); + + $output->write('Lorem ipsum dolor sit amet'); + $output->text(array( + 'Lorem ipsum dolor sit amet', + 'consectetur adipiscing elit', + )); + + $output->newLine(); + + $output->write('Lorem ipsum dolor sit amet'); + $output->comment(array( + 'Lorem ipsum dolor sit amet', + 'consectetur adipiscing elit', + )); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.php new file mode 100644 index 000000000..f1d799054 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.php @@ -0,0 +1,16 @@ +listing(array( + 'Lorem ipsum dolor sit amet', + 'consectetur adipiscing elit', + )); + $output->success('Lorem ipsum dolor sit amet'); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.php new file mode 100644 index 000000000..cbfea734b --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.php @@ -0,0 +1,15 @@ +title('Title'); + $output->askHidden('Hidden question'); + $output->choice('Choice question with default', array('choice1', 'choice2'), 'choice1'); + $output->confirm('Confirmation with yes default', true); + $output->text('Duis aute irure dolor in reprehenderit in voluptate velit esse'); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.php new file mode 100644 index 000000000..0244fd272 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.php @@ -0,0 +1,26 @@ + 3))), + array('ISBN', 'Title', 'Author'), + ); + + $rows = array( + array( + '978-0521567817', + 'De Monarchia', + new TableCell("Dante Alighieri\nspans multiple rows", array('rowspan' => 2)), + ), + array('978-0804169127', 'Divine Comedy'), + ); + + $output = new SymfonyStyleWithForcedLineLength($input, $output); + $output->table($headers, $rows); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php new file mode 100644 index 000000000..6420730fd --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php @@ -0,0 +1,11 @@ +block(array('Custom block', 'Second custom block line'), 'CUSTOM', 'fg=white;bg=green', 'X ', true); +}; diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txt new file mode 100644 index 000000000..a42e0f792 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txt @@ -0,0 +1,3 @@ + + ! [CAUTION] Lorem ipsum dolor sit amet + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txt new file mode 100644 index 000000000..334875f78 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txt @@ -0,0 +1,9 @@ + +Title +===== + + [WARNING] Lorem ipsum dolor sit amet + +Title +===== + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt new file mode 100644 index 000000000..385c6a283 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt @@ -0,0 +1,7 @@ + +X [CUSTOM] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et +X dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea +X commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat +X nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit +X anim id est laborum + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_11.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_11.txt new file mode 100644 index 000000000..190d78403 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_11.txt @@ -0,0 +1,4 @@ + + § [CUSTOM] Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophatto + § peristeralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_12.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_12.txt new file mode 100644 index 000000000..9983af832 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_12.txt @@ -0,0 +1,6 @@ + + // Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna + // aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + // Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur + // sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt new file mode 100644 index 000000000..0f3704b74 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt @@ -0,0 +1,7 @@ + + // Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et  + // dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea  + // commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla  + // pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim + // id est laborum + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_14.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_14.txt new file mode 100644 index 000000000..1d0d37e7f --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_14.txt @@ -0,0 +1,6 @@ + +$ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna +$ aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +$ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint +$ occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_15.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_15.txt new file mode 100644 index 000000000..66404b815 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_15.txt @@ -0,0 +1,7 @@ + + [TEST] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_16.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_16.txt new file mode 100644 index 000000000..a0d180165 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_16.txt @@ -0,0 +1,8 @@ + +  + [OK] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore  + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo  + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.  + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum  +  + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_17.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_17.txt new file mode 100644 index 000000000..59d00e04a --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_17.txt @@ -0,0 +1,7 @@ + +Title ending with \ +=================== + +Section ending with \ +--------------------- + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txt new file mode 100644 index 000000000..ca609760c --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txt @@ -0,0 +1,13 @@ + + [WARNING] Warning + + ! [CAUTION] Caution + + [ERROR] Error + + [OK] Success + + ! [NOTE] Note + +X [CUSTOM] Custom block + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txt new file mode 100644 index 000000000..f4b6d5827 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txt @@ -0,0 +1,7 @@ + +First title +=========== + +Second title +============ + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txt new file mode 100644 index 000000000..2646d858e --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txt @@ -0,0 +1,32 @@ +Lorem ipsum dolor sit amet + +First title +=========== + +Lorem ipsum dolor sit amet + +Second title +============ + +Lorem ipsum dolor sit amet + +Third title +=========== + +Lorem ipsum dolor sit amet + +Fourth title +============ + +Lorem ipsum dolor sit amet + + +Fifth title +=========== + +Lorem ipsum dolor sit amet + + +Fifth title +=========== + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txt new file mode 100644 index 000000000..be4a2db60 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txt @@ -0,0 +1,18 @@ +Lorem ipsum dolor sit amet + * Lorem ipsum dolor sit amet + * consectetur adipiscing elit + +Lorem ipsum dolor sit amet + * Lorem ipsum dolor sit amet + * consectetur adipiscing elit + +Lorem ipsum dolor sit amet + Lorem ipsum dolor sit amet + consectetur adipiscing elit + +Lorem ipsum dolor sit amet + + // Lorem ipsum dolor sit amet + // + // consectetur adipiscing elit + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txt new file mode 100644 index 000000000..5f2d33c14 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txt @@ -0,0 +1,6 @@ + + * Lorem ipsum dolor sit amet + * consectetur adipiscing elit + + [OK] Lorem ipsum dolor sit amet + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txt new file mode 100644 index 000000000..ecea9778b --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txt @@ -0,0 +1,5 @@ + +Title +===== + + Duis aute irure dolor in reprehenderit in voluptate velit esse diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_8.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_8.txt new file mode 100644 index 000000000..005b846ea --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_8.txt @@ -0,0 +1,9 @@ + ---------------- --------------- --------------------- + Main table title + ---------------- --------------- --------------------- + ISBN Title Author + ---------------- --------------- --------------------- + 978-0521567817 De Monarchia Dante Alighieri + 978-0804169127 Divine Comedy spans multiple rows + ---------------- --------------- --------------------- + diff --git a/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt new file mode 100644 index 000000000..069c0d511 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt @@ -0,0 +1,5 @@ + +X [CUSTOM] Custom block +X +X Second custom block line + diff --git a/vendor/symfony/console/Tests/Fixtures/TestCommand.php b/vendor/symfony/console/Tests/Fixtures/TestCommand.php new file mode 100644 index 000000000..dcd32739c --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/TestCommand.php @@ -0,0 +1,28 @@ +setName('namespace:name') + ->setAliases(array('name')) + ->setDescription('description') + ->setHelp('help') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $output->writeln('execute called'); + } + + protected function interact(InputInterface $input, OutputInterface $output) + { + $output->writeln('interact called'); + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/application_1.json b/vendor/symfony/console/Tests/Fixtures/application_1.json new file mode 100644 index 000000000..ea695a7de --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_1.json @@ -0,0 +1,172 @@ +{ + "commands": [ + { + "name": "help", + "usage": [ + "help [--xml] [--format FORMAT] [--raw] [--] []" + ], + "description": "Displays help for a command", + "help": "The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.", + "definition": { + "arguments": { + "command_name": { + "name": "command_name", + "is_required": false, + "is_array": false, + "description": "The command name", + "default": "help" + } + }, + "options": { + "xml": { + "name": "--xml", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "To output help as XML", + "default": false + }, + "format": { + "name": "--format", + "shortcut": "", + "accept_value": true, + "is_value_required": true, + "is_multiple": false, + "description": "The output format (txt, xml, json, or md)", + "default": "txt" + }, + "raw": { + "name": "--raw", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "To output raw command help", + "default": false + }, + "help": { + "name": "--help", + "shortcut": "-h", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Display this help message", + "default": false + }, + "quiet": { + "name": "--quiet", + "shortcut": "-q", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Do not output any message", + "default": false + }, + "verbose": { + "name": "--verbose", + "shortcut": "-v|-vv|-vvv", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug", + "default": false + }, + "version": { + "name": "--version", + "shortcut": "-V", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Display this application version", + "default": false + }, + "ansi": { + "name": "--ansi", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Force ANSI output", + "default": false + }, + "no-ansi": { + "name": "--no-ansi", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Disable ANSI output", + "default": false + }, + "no-interaction": { + "name": "--no-interaction", + "shortcut": "-n", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Do not ask any interactive question", + "default": false + } + } + } + }, + { + "name": "list", + "usage": [ + "list [--xml] [--raw] [--format FORMAT] [--] []" + ], + "description": "Lists commands", + "help": "The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>", + "definition": { + "arguments": { + "namespace": { + "name": "namespace", + "is_required": false, + "is_array": false, + "description": "The namespace name", + "default": null + } + }, + "options": { + "xml": { + "name": "--xml", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "To output list as XML", + "default": false + }, + "raw": { + "name": "--raw", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "To output raw command list", + "default": false + }, + "format": { + "name": "--format", + "shortcut": "", + "accept_value": true, + "is_value_required": true, + "is_multiple": false, + "description": "The output format (txt, xml, json, or md)", + "default": "txt" + } + } + } + } + ], + "namespaces": [ + { + "id": "_global", + "commands": [ + "help", + "list" + ] + } + ] +} diff --git a/vendor/symfony/console/Tests/Fixtures/application_1.md b/vendor/symfony/console/Tests/Fixtures/application_1.md new file mode 100644 index 000000000..82a605da6 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_1.md @@ -0,0 +1,201 @@ +UNKNOWN +======= + +* help +* list + +help +---- + +* Description: Displays help for a command +* Usage: + + * `help [--xml] [--format FORMAT] [--raw] [--] []` + +The help command displays help for a given command: + + php app/console help list + +You can also output the help in other formats by using the --format option: + + php app/console help --format=xml list + +To display the list of available commands, please use the list command. + +### Arguments: + +**command_name:** + +* Name: command_name +* Is required: no +* Is array: no +* Description: The command name +* Default: `'help'` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output help as XML +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: The output format (txt, xml, json, or md) +* Default: `'txt'` + +**raw:** + +* Name: `--raw` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output raw command help +* Default: `false` + +**help:** + +* Name: `--help` +* Shortcut: `-h` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this help message +* Default: `false` + +**quiet:** + +* Name: `--quiet` +* Shortcut: `-q` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not output any message +* Default: `false` + +**verbose:** + +* Name: `--verbose` +* Shortcut: `-v|-vv|-vvv` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug +* Default: `false` + +**version:** + +* Name: `--version` +* Shortcut: `-V` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this application version +* Default: `false` + +**ansi:** + +* Name: `--ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Disable ANSI output +* Default: `false` + +**no-interaction:** + +* Name: `--no-interaction` +* Shortcut: `-n` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not ask any interactive question +* Default: `false` + +list +---- + +* Description: Lists commands +* Usage: + + * `list [--xml] [--raw] [--format FORMAT] [--] []` + +The list command lists all commands: + + php app/console list + +You can also display the commands for a specific namespace: + + php app/console list test + +You can also output the information in other formats by using the --format option: + + php app/console list --format=xml + +It's also possible to get raw list of commands (useful for embedding command runner): + + php app/console list --raw + +### Arguments: + +**namespace:** + +* Name: namespace +* Is required: no +* Is array: no +* Description: The namespace name +* Default: `NULL` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output list as XML +* Default: `false` + +**raw:** + +* Name: `--raw` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output raw command list +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: The output format (txt, xml, json, or md) +* Default: `'txt'` diff --git a/vendor/symfony/console/Tests/Fixtures/application_1.txt b/vendor/symfony/console/Tests/Fixtures/application_1.txt new file mode 100644 index 000000000..c4cf8f216 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_1.txt @@ -0,0 +1,17 @@ +Console Tool + +Usage: + command [options] [arguments] + +Options: + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Available commands: + help Displays help for a command + list Lists commands diff --git a/vendor/symfony/console/Tests/Fixtures/application_1.xml b/vendor/symfony/console/Tests/Fixtures/application_1.xml new file mode 100644 index 000000000..35d1db4dc --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_1.xml @@ -0,0 +1,110 @@ + + + + + + help [--xml] [--format FORMAT] [--raw] [--] [<command_name>] + + Displays help for a command + The <info>help</info> command displays help for a given command: + + <info>php app/console help list</info> + + You can also output the help in other formats by using the <comment>--format</comment> option: + + <info>php app/console help --format=xml list</info> + + To display the list of available commands, please use the <info>list</info> command. + + + The command name + + help + + + + + + + + + + + + + + + + + + + list [--xml] [--raw] [--format FORMAT] [--] [<namespace>] + + Lists commands + The <info>list</info> command lists all commands: + + <info>php app/console list</info> + + You can also display the commands for a specific namespace: + + <info>php app/console list test</info> + + You can also output the information in other formats by using the <comment>--format</comment> option: + + <info>php app/console list --format=xml</info> + + It's also possible to get raw list of commands (useful for embedding command runner): + + <info>php app/console list --raw</info> + + + The namespace name + + + + + + + + + + + + + help + list + + + diff --git a/vendor/symfony/console/Tests/Fixtures/application_2.json b/vendor/symfony/console/Tests/Fixtures/application_2.json new file mode 100644 index 000000000..8ffa222ee --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_2.json @@ -0,0 +1,354 @@ +{ + "commands": [ + { + "name": "help", + "usage": [ + "help [--xml] [--format FORMAT] [--raw] [--] []" + ], + "description": "Displays help for a command", + "help": "The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.", + "definition": { + "arguments": { + "command_name": { + "name": "command_name", + "is_required": false, + "is_array": false, + "description": "The command name", + "default": "help" + } + }, + "options": { + "xml": { + "name": "--xml", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "To output help as XML", + "default": false + }, + "format": { + "name": "--format", + "shortcut": "", + "accept_value": true, + "is_value_required": true, + "is_multiple": false, + "description": "The output format (txt, xml, json, or md)", + "default": "txt" + }, + "raw": { + "name": "--raw", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "To output raw command help", + "default": false + }, + "help": { + "name": "--help", + "shortcut": "-h", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Display this help message", + "default": false + }, + "quiet": { + "name": "--quiet", + "shortcut": "-q", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Do not output any message", + "default": false + }, + "verbose": { + "name": "--verbose", + "shortcut": "-v|-vv|-vvv", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug", + "default": false + }, + "version": { + "name": "--version", + "shortcut": "-V", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Display this application version", + "default": false + }, + "ansi": { + "name": "--ansi", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Force ANSI output", + "default": false + }, + "no-ansi": { + "name": "--no-ansi", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Disable ANSI output", + "default": false + }, + "no-interaction": { + "name": "--no-interaction", + "shortcut": "-n", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Do not ask any interactive question", + "default": false + } + } + } + }, + { + "name": "list", + "usage": [ + "list [--xml] [--raw] [--format FORMAT] [--] []" + ], + "description": "Lists commands", + "help": "The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>", + "definition": { + "arguments": { + "namespace": { + "name": "namespace", + "is_required": false, + "is_array": false, + "description": "The namespace name", + "default": null + } + }, + "options": { + "xml": { + "name": "--xml", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "To output list as XML", + "default": false + }, + "raw": { + "name": "--raw", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "To output raw command list", + "default": false + }, + "format": { + "name": "--format", + "shortcut": "", + "accept_value": true, + "is_value_required": true, + "is_multiple": false, + "description": "The output format (txt, xml, json, or md)", + "default": "txt" + } + } + } + }, + { + "name": "descriptor:command1", + "usage": [ + "descriptor:command1", + "alias1", + "alias2" + ], + "description": "command 1 description", + "help": "command 1 help", + "definition": { + "arguments": [], + "options": { + "help": { + "name": "--help", + "shortcut": "-h", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Display this help message", + "default": false + }, + "quiet": { + "name": "--quiet", + "shortcut": "-q", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Do not output any message", + "default": false + }, + "verbose": { + "name": "--verbose", + "shortcut": "-v|-vv|-vvv", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug", + "default": false + }, + "version": { + "name": "--version", + "shortcut": "-V", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Display this application version", + "default": false + }, + "ansi": { + "name": "--ansi", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Force ANSI output", + "default": false + }, + "no-ansi": { + "name": "--no-ansi", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Disable ANSI output", + "default": false + }, + "no-interaction": { + "name": "--no-interaction", + "shortcut": "-n", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Do not ask any interactive question", + "default": false + } + } + } + }, + { + "name": "descriptor:command2", + "usage": [ + "descriptor:command2 [-o|--option_name] [--] ", + "descriptor:command2 -o|--option_name ", + "descriptor:command2 " + ], + "description": "command 2 description", + "help": "command 2 help", + "definition": { + "arguments": { + "argument_name": { + "name": "argument_name", + "is_required": true, + "is_array": false, + "description": "", + "default": null + } + }, + "options": { + "option_name": { + "name": "--option_name", + "shortcut": "-o", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "", + "default": false + }, + "help": { + "name": "--help", + "shortcut": "-h", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Display this help message", + "default": false + }, + "quiet": { + "name": "--quiet", + "shortcut": "-q", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Do not output any message", + "default": false + }, + "verbose": { + "name": "--verbose", + "shortcut": "-v|-vv|-vvv", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug", + "default": false + }, + "version": { + "name": "--version", + "shortcut": "-V", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Display this application version", + "default": false + }, + "ansi": { + "name": "--ansi", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Force ANSI output", + "default": false + }, + "no-ansi": { + "name": "--no-ansi", + "shortcut": "", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Disable ANSI output", + "default": false + }, + "no-interaction": { + "name": "--no-interaction", + "shortcut": "-n", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "Do not ask any interactive question", + "default": false + } + } + } + } + ], + "namespaces": [ + { + "id": "_global", + "commands": [ + "alias1", + "alias2", + "help", + "list" + ] + }, + { + "id": "descriptor", + "commands": [ + "descriptor:command1", + "descriptor:command2" + ] + } + ] +} diff --git a/vendor/symfony/console/Tests/Fixtures/application_2.md b/vendor/symfony/console/Tests/Fixtures/application_2.md new file mode 100644 index 000000000..f031c9e5c --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_2.md @@ -0,0 +1,396 @@ +My Symfony application +====================== + +* alias1 +* alias2 +* help +* list + +**descriptor:** + +* descriptor:command1 +* descriptor:command2 + +help +---- + +* Description: Displays help for a command +* Usage: + + * `help [--xml] [--format FORMAT] [--raw] [--] []` + +The help command displays help for a given command: + + php app/console help list + +You can also output the help in other formats by using the --format option: + + php app/console help --format=xml list + +To display the list of available commands, please use the list command. + +### Arguments: + +**command_name:** + +* Name: command_name +* Is required: no +* Is array: no +* Description: The command name +* Default: `'help'` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output help as XML +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: The output format (txt, xml, json, or md) +* Default: `'txt'` + +**raw:** + +* Name: `--raw` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output raw command help +* Default: `false` + +**help:** + +* Name: `--help` +* Shortcut: `-h` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this help message +* Default: `false` + +**quiet:** + +* Name: `--quiet` +* Shortcut: `-q` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not output any message +* Default: `false` + +**verbose:** + +* Name: `--verbose` +* Shortcut: `-v|-vv|-vvv` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug +* Default: `false` + +**version:** + +* Name: `--version` +* Shortcut: `-V` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this application version +* Default: `false` + +**ansi:** + +* Name: `--ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Disable ANSI output +* Default: `false` + +**no-interaction:** + +* Name: `--no-interaction` +* Shortcut: `-n` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not ask any interactive question +* Default: `false` + +list +---- + +* Description: Lists commands +* Usage: + + * `list [--xml] [--raw] [--format FORMAT] [--] []` + +The list command lists all commands: + + php app/console list + +You can also display the commands for a specific namespace: + + php app/console list test + +You can also output the information in other formats by using the --format option: + + php app/console list --format=xml + +It's also possible to get raw list of commands (useful for embedding command runner): + + php app/console list --raw + +### Arguments: + +**namespace:** + +* Name: namespace +* Is required: no +* Is array: no +* Description: The namespace name +* Default: `NULL` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output list as XML +* Default: `false` + +**raw:** + +* Name: `--raw` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output raw command list +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: The output format (txt, xml, json, or md) +* Default: `'txt'` + +descriptor:command1 +------------------- + +* Description: command 1 description +* Usage: + + * `descriptor:command1` + * `alias1` + * `alias2` + +command 1 help + +### Options: + +**help:** + +* Name: `--help` +* Shortcut: `-h` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this help message +* Default: `false` + +**quiet:** + +* Name: `--quiet` +* Shortcut: `-q` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not output any message +* Default: `false` + +**verbose:** + +* Name: `--verbose` +* Shortcut: `-v|-vv|-vvv` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug +* Default: `false` + +**version:** + +* Name: `--version` +* Shortcut: `-V` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this application version +* Default: `false` + +**ansi:** + +* Name: `--ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Disable ANSI output +* Default: `false` + +**no-interaction:** + +* Name: `--no-interaction` +* Shortcut: `-n` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not ask any interactive question +* Default: `false` + +descriptor:command2 +------------------- + +* Description: command 2 description +* Usage: + + * `descriptor:command2 [-o|--option_name] [--] ` + * `descriptor:command2 -o|--option_name ` + * `descriptor:command2 ` + +command 2 help + +### Arguments: + +**argument_name:** + +* Name: argument_name +* Is required: yes +* Is array: no +* Description: +* Default: `NULL` + +### Options: + +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* Default: `false` + +**help:** + +* Name: `--help` +* Shortcut: `-h` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this help message +* Default: `false` + +**quiet:** + +* Name: `--quiet` +* Shortcut: `-q` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not output any message +* Default: `false` + +**verbose:** + +* Name: `--verbose` +* Shortcut: `-v|-vv|-vvv` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug +* Default: `false` + +**version:** + +* Name: `--version` +* Shortcut: `-V` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this application version +* Default: `false` + +**ansi:** + +* Name: `--ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Disable ANSI output +* Default: `false` + +**no-interaction:** + +* Name: `--no-interaction` +* Shortcut: `-n` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not ask any interactive question +* Default: `false` diff --git a/vendor/symfony/console/Tests/Fixtures/application_2.txt b/vendor/symfony/console/Tests/Fixtures/application_2.txt new file mode 100644 index 000000000..292aa829d --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_2.txt @@ -0,0 +1,22 @@ +My Symfony application version v1.0 + +Usage: + command [options] [arguments] + +Options: + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Available commands: + alias1 command 1 description + alias2 command 1 description + help Displays help for a command + list Lists commands + descriptor + descriptor:command1 command 1 description + descriptor:command2 command 2 description diff --git a/vendor/symfony/console/Tests/Fixtures/application_2.xml b/vendor/symfony/console/Tests/Fixtures/application_2.xml new file mode 100644 index 000000000..bc8ab219d --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_2.xml @@ -0,0 +1,190 @@ + + + + + + help [--xml] [--format FORMAT] [--raw] [--] [<command_name>] + + Displays help for a command + The <info>help</info> command displays help for a given command: + + <info>php app/console help list</info> + + You can also output the help in other formats by using the <comment>--format</comment> option: + + <info>php app/console help --format=xml list</info> + + To display the list of available commands, please use the <info>list</info> command. + + + The command name + + help + + + + + + + + + + + + + + + + + + + list [--xml] [--raw] [--format FORMAT] [--] [<namespace>] + + Lists commands + The <info>list</info> command lists all commands: + + <info>php app/console list</info> + + You can also display the commands for a specific namespace: + + <info>php app/console list test</info> + + You can also output the information in other formats by using the <comment>--format</comment> option: + + <info>php app/console list --format=xml</info> + + It's also possible to get raw list of commands (useful for embedding command runner): + + <info>php app/console list --raw</info> + + + The namespace name + + + + + + + + + + + + descriptor:command1 + alias1 + alias2 + + command 1 description + command 1 help + + + + + + + + + + + + + + descriptor:command2 [-o|--option_name] [--] <argument_name> + descriptor:command2 -o|--option_name <argument_name> + descriptor:command2 <argument_name> + + command 2 description + command 2 help + + + + + + + + + + + + + + + + + + + + + alias1 + alias2 + help + list + + + descriptor:command1 + descriptor:command2 + + + diff --git a/vendor/symfony/console/Tests/Fixtures/application_astext1.txt b/vendor/symfony/console/Tests/Fixtures/application_astext1.txt new file mode 100644 index 000000000..19dacb23b --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_astext1.txt @@ -0,0 +1,20 @@ +Console Tool + +Usage: + command [options] [arguments] + +Options: + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Available commands: + afoobar The foo:bar command + help Displays help for a command + list Lists commands + foo + foo:bar The foo:bar command diff --git a/vendor/symfony/console/Tests/Fixtures/application_astext2.txt b/vendor/symfony/console/Tests/Fixtures/application_astext2.txt new file mode 100644 index 000000000..c99ccdda7 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_astext2.txt @@ -0,0 +1,16 @@ +Console Tool + +Usage: + command [options] [arguments] + +Options: + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Available commands for the "foo" namespace: + foo:bar The foo:bar command diff --git a/vendor/symfony/console/Tests/Fixtures/application_asxml1.txt b/vendor/symfony/console/Tests/Fixtures/application_asxml1.txt new file mode 100644 index 000000000..8277d9e66 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_asxml1.txt @@ -0,0 +1,146 @@ + + + + + + help [--xml] [--format FORMAT] [--raw] [--] [<command_name>] + + Displays help for a command + The <info>help</info> command displays help for a given command: + + <info>php app/console help list</info> + + You can also output the help in other formats by using the <comment>--format</comment> option: + + <info>php app/console help --format=xml list</info> + + To display the list of available commands, please use the <info>list</info> command. + + + The command name + + help + + + + + + + + + + + + + + + + + + + list [--xml] [--raw] [--format FORMAT] [--] [<namespace>] + + Lists commands + The <info>list</info> command lists all commands: + + <info>php app/console list</info> + + You can also display the commands for a specific namespace: + + <info>php app/console list test</info> + + You can also output the information in other formats by using the <comment>--format</comment> option: + + <info>php app/console list --format=xml</info> + + It's also possible to get raw list of commands (useful for embedding command runner): + + <info>php app/console list --raw</info> + + + The namespace name + + + + + + + + + + + + foo:bar + afoobar + + The foo:bar command + The foo:bar command + + + + + + + + + + + + + + + afoobar + help + list + + + foo:bar + + + diff --git a/vendor/symfony/console/Tests/Fixtures/application_asxml2.txt b/vendor/symfony/console/Tests/Fixtures/application_asxml2.txt new file mode 100644 index 000000000..93d6d4e99 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_asxml2.txt @@ -0,0 +1,37 @@ + + + + + + foo:bar + afoobar + + The foo:bar command + The foo:bar command + + + + + + + + + + + + + diff --git a/vendor/symfony/console/Tests/Fixtures/application_gethelp.txt b/vendor/symfony/console/Tests/Fixtures/application_gethelp.txt new file mode 100644 index 000000000..0c16e3c84 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_gethelp.txt @@ -0,0 +1 @@ +Console Tool \ No newline at end of file diff --git a/vendor/symfony/console/Tests/Fixtures/application_mbstring.md b/vendor/symfony/console/Tests/Fixtures/application_mbstring.md new file mode 100644 index 000000000..ef81f8697 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_mbstring.md @@ -0,0 +1,309 @@ +MbString åpplicätion +==================== + +* help +* list + +**descriptor:** + +* descriptor:åèä + +help +---- + +* Description: Displays help for a command +* Usage: + + * `help [--xml] [--format FORMAT] [--raw] [--] []` + +The help command displays help for a given command: + + php app/console help list + +You can also output the help in other formats by using the --format option: + + php app/console help --format=xml list + +To display the list of available commands, please use the list command. + +### Arguments: + +**command_name:** + +* Name: command_name +* Is required: no +* Is array: no +* Description: The command name +* Default: `'help'` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output help as XML +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: The output format (txt, xml, json, or md) +* Default: `'txt'` + +**raw:** + +* Name: `--raw` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output raw command help +* Default: `false` + +**help:** + +* Name: `--help` +* Shortcut: `-h` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this help message +* Default: `false` + +**quiet:** + +* Name: `--quiet` +* Shortcut: `-q` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not output any message +* Default: `false` + +**verbose:** + +* Name: `--verbose` +* Shortcut: `-v|-vv|-vvv` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug +* Default: `false` + +**version:** + +* Name: `--version` +* Shortcut: `-V` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this application version +* Default: `false` + +**ansi:** + +* Name: `--ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Disable ANSI output +* Default: `false` + +**no-interaction:** + +* Name: `--no-interaction` +* Shortcut: `-n` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not ask any interactive question +* Default: `false` + +list +---- + +* Description: Lists commands +* Usage: + + * `list [--xml] [--raw] [--format FORMAT] [--] []` + +The list command lists all commands: + + php app/console list + +You can also display the commands for a specific namespace: + + php app/console list test + +You can also output the information in other formats by using the --format option: + + php app/console list --format=xml + +It's also possible to get raw list of commands (useful for embedding command runner): + + php app/console list --raw + +### Arguments: + +**namespace:** + +* Name: namespace +* Is required: no +* Is array: no +* Description: The namespace name +* Default: `NULL` + +### Options: + +**xml:** + +* Name: `--xml` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output list as XML +* Default: `false` + +**raw:** + +* Name: `--raw` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: To output raw command list +* Default: `false` + +**format:** + +* Name: `--format` +* Shortcut: +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: The output format (txt, xml, json, or md) +* Default: `'txt'` + +descriptor:åèä +-------------- + +* Description: command åèä description +* Usage: + + * `descriptor:åèä [-o|--option_åèä] [--] ` + * `descriptor:åèä -o|--option_name ` + * `descriptor:åèä ` + +command åèä help + +### Arguments: + +**argument_åèä:** + +* Name: argument_åèä +* Is required: yes +* Is array: no +* Description: +* Default: `NULL` + +### Options: + +**option_åèä:** + +* Name: `--option_åèä` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* Default: `false` + +**help:** + +* Name: `--help` +* Shortcut: `-h` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this help message +* Default: `false` + +**quiet:** + +* Name: `--quiet` +* Shortcut: `-q` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not output any message +* Default: `false` + +**verbose:** + +* Name: `--verbose` +* Shortcut: `-v|-vv|-vvv` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug +* Default: `false` + +**version:** + +* Name: `--version` +* Shortcut: `-V` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Display this application version +* Default: `false` + +**ansi:** + +* Name: `--ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Force ANSI output +* Default: `false` + +**no-ansi:** + +* Name: `--no-ansi` +* Shortcut: +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Disable ANSI output +* Default: `false` + +**no-interaction:** + +* Name: `--no-interaction` +* Shortcut: `-n` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: Do not ask any interactive question +* Default: `false` diff --git a/vendor/symfony/console/Tests/Fixtures/application_mbstring.txt b/vendor/symfony/console/Tests/Fixtures/application_mbstring.txt new file mode 100644 index 000000000..9d21f829d --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_mbstring.txt @@ -0,0 +1,19 @@ +MbString åpplicätion + +Usage: + command [options] [arguments] + +Options: + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Available commands: + help Displays help for a command + list Lists commands + descriptor + descriptor:åèä command åèä description diff --git a/vendor/symfony/console/Tests/Fixtures/application_renderexception1.txt b/vendor/symfony/console/Tests/Fixtures/application_renderexception1.txt new file mode 100644 index 000000000..919cec421 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_renderexception1.txt @@ -0,0 +1,6 @@ + + + [Symfony\Component\Console\Exception\CommandNotFoundException] + Command "foo" is not defined. + + diff --git a/vendor/symfony/console/Tests/Fixtures/application_renderexception2.txt b/vendor/symfony/console/Tests/Fixtures/application_renderexception2.txt new file mode 100644 index 000000000..d9e93da45 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_renderexception2.txt @@ -0,0 +1,8 @@ + + + [Symfony\Component\Console\Exception\InvalidOptionException] + The "--foo" option does not exist. + + +list [--xml] [--raw] [--format FORMAT] [--] [] + diff --git a/vendor/symfony/console/Tests/Fixtures/application_renderexception3.txt b/vendor/symfony/console/Tests/Fixtures/application_renderexception3.txt new file mode 100644 index 000000000..f41925f52 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_renderexception3.txt @@ -0,0 +1,18 @@ + + + [Exception] + Third exception comment + + + + [Exception] + Second exception comment + + + + [Exception] + First exception

this is html

+ + +foo3:bar + diff --git a/vendor/symfony/console/Tests/Fixtures/application_renderexception3decorated.txt b/vendor/symfony/console/Tests/Fixtures/application_renderexception3decorated.txt new file mode 100644 index 000000000..5adccdd70 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_renderexception3decorated.txt @@ -0,0 +1,18 @@ + +  + [Exception]  + Third exception comment  +  + +  + [Exception]  + Second exception comment  +  + +  + [Exception]  + First exception

this is html

 +  + +foo3:bar + diff --git a/vendor/symfony/console/Tests/Fixtures/application_renderexception4.txt b/vendor/symfony/console/Tests/Fixtures/application_renderexception4.txt new file mode 100644 index 000000000..cb080e9cb --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_renderexception4.txt @@ -0,0 +1,7 @@ + + + [Symfony\Component\Console\Exception\CommandNotFoundException] + Command "foo" is not define + d. + + diff --git a/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1.txt b/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1.txt new file mode 100644 index 000000000..1ba5f8fdd --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1.txt @@ -0,0 +1,8 @@ + + + [Exception] + エラーメッセージ + + +foo + diff --git a/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt b/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt new file mode 100644 index 000000000..20644251c --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth1decorated.txt @@ -0,0 +1,8 @@ + +  + [Exception]  + エラーメッセージ  +  + +foo + diff --git a/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth2.txt b/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth2.txt new file mode 100644 index 000000000..e41fcfcf6 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_renderexception_doublewidth2.txt @@ -0,0 +1,9 @@ + + + [Exception] + コマンドの実行中にエラーが + 発生しました。 + + +foo + diff --git a/vendor/symfony/console/Tests/Fixtures/application_renderexception_escapeslines.txt b/vendor/symfony/console/Tests/Fixtures/application_renderexception_escapeslines.txt new file mode 100644 index 000000000..cf79b37a9 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_renderexception_escapeslines.txt @@ -0,0 +1,9 @@ + + + [Exception] + dont break here < + info>!
+ + +foo + diff --git a/vendor/symfony/console/Tests/Fixtures/application_run1.txt b/vendor/symfony/console/Tests/Fixtures/application_run1.txt new file mode 100644 index 000000000..0dc273098 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_run1.txt @@ -0,0 +1,17 @@ +Console Tool + +Usage: + command [options] [arguments] + +Options: + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Available commands: + help Displays help for a command + list Lists commands diff --git a/vendor/symfony/console/Tests/Fixtures/application_run2.txt b/vendor/symfony/console/Tests/Fixtures/application_run2.txt new file mode 100644 index 000000000..9a42503c6 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_run2.txt @@ -0,0 +1,29 @@ +Usage: + help [options] [--] [] + +Arguments: + command The command to execute + command_name The command name [default: "help"] + +Options: + --xml To output help as XML + --format=FORMAT The output format (txt, xml, json, or md) [default: "txt"] + --raw To output raw command help + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Help: + The help command displays help for a given command: + + php app/console help list + + You can also output the help in other formats by using the --format option: + + php app/console help --format=xml list + + To display the list of available commands, please use the list command. diff --git a/vendor/symfony/console/Tests/Fixtures/application_run3.txt b/vendor/symfony/console/Tests/Fixtures/application_run3.txt new file mode 100644 index 000000000..2e8d92e19 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_run3.txt @@ -0,0 +1,27 @@ +Usage: + list [options] [--] [] + +Arguments: + namespace The namespace name + +Options: + --xml To output list as XML + --raw To output raw command list + --format=FORMAT The output format (txt, xml, json, or md) [default: "txt"] + +Help: + The list command lists all commands: + + php app/console list + + You can also display the commands for a specific namespace: + + php app/console list test + + You can also output the information in other formats by using the --format option: + + php app/console list --format=xml + + It's also possible to get raw list of commands (useful for embedding command runner): + + php app/console list --raw diff --git a/vendor/symfony/console/Tests/Fixtures/application_run4.txt b/vendor/symfony/console/Tests/Fixtures/application_run4.txt new file mode 100644 index 000000000..47187fc26 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/application_run4.txt @@ -0,0 +1 @@ +Console Tool diff --git a/vendor/symfony/console/Tests/Fixtures/command_1.json b/vendor/symfony/console/Tests/Fixtures/command_1.json new file mode 100644 index 000000000..4cd37eeb4 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_1.json @@ -0,0 +1,14 @@ +{ + "name": "descriptor:command1", + "usage": [ + "descriptor:command1", + "alias1", + "alias2" + ], + "description": "command 1 description", + "help": "command 1 help", + "definition": { + "arguments": [], + "options": [] + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/command_1.md b/vendor/symfony/console/Tests/Fixtures/command_1.md new file mode 100644 index 000000000..34ed3ea77 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_1.md @@ -0,0 +1,11 @@ +descriptor:command1 +------------------- + +* Description: command 1 description +* Usage: + + * `descriptor:command1` + * `alias1` + * `alias2` + +command 1 help diff --git a/vendor/symfony/console/Tests/Fixtures/command_1.txt b/vendor/symfony/console/Tests/Fixtures/command_1.txt new file mode 100644 index 000000000..e5e93ee09 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_1.txt @@ -0,0 +1,7 @@ +Usage: + descriptor:command1 + alias1 + alias2 + +Help: + command 1 help diff --git a/vendor/symfony/console/Tests/Fixtures/command_1.xml b/vendor/symfony/console/Tests/Fixtures/command_1.xml new file mode 100644 index 000000000..838b9bd91 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_1.xml @@ -0,0 +1,12 @@ + + + + descriptor:command1 + alias1 + alias2 + + command 1 description + command 1 help + + + diff --git a/vendor/symfony/console/Tests/Fixtures/command_2.json b/vendor/symfony/console/Tests/Fixtures/command_2.json new file mode 100644 index 000000000..74c1f1260 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_2.json @@ -0,0 +1,32 @@ +{ + "name": "descriptor:command2", + "usage": [ + "descriptor:command2 [-o|--option_name] [--] ", + "descriptor:command2 -o|--option_name ", + "descriptor:command2 " + ], + "description": "command 2 description", + "help": "command 2 help", + "definition": { + "arguments": { + "argument_name": { + "name": "argument_name", + "is_required": true, + "is_array": false, + "description": "", + "default": null + } + }, + "options": { + "option_name": { + "name": "--option_name", + "shortcut": "-o", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "", + "default": false + } + } + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/command_2.md b/vendor/symfony/console/Tests/Fixtures/command_2.md new file mode 100644 index 000000000..6f538b640 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_2.md @@ -0,0 +1,33 @@ +descriptor:command2 +------------------- + +* Description: command 2 description +* Usage: + + * `descriptor:command2 [-o|--option_name] [--] ` + * `descriptor:command2 -o|--option_name ` + * `descriptor:command2 ` + +command 2 help + +### Arguments: + +**argument_name:** + +* Name: argument_name +* Is required: yes +* Is array: no +* Description: +* Default: `NULL` + +### Options: + +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* Default: `false` diff --git a/vendor/symfony/console/Tests/Fixtures/command_2.txt b/vendor/symfony/console/Tests/Fixtures/command_2.txt new file mode 100644 index 000000000..cad9cb45f --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_2.txt @@ -0,0 +1,13 @@ +Usage: + descriptor:command2 [options] [--] + descriptor:command2 -o|--option_name + descriptor:command2 + +Arguments: + argument_name + +Options: + -o, --option_name + +Help: + command 2 help diff --git a/vendor/symfony/console/Tests/Fixtures/command_2.xml b/vendor/symfony/console/Tests/Fixtures/command_2.xml new file mode 100644 index 000000000..67364caa4 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_2.xml @@ -0,0 +1,21 @@ + + + + descriptor:command2 [-o|--option_name] [--] <argument_name> + descriptor:command2 -o|--option_name <argument_name> + descriptor:command2 <argument_name> + + command 2 description + command 2 help + + + + + + + + + + diff --git a/vendor/symfony/console/Tests/Fixtures/command_astext.txt b/vendor/symfony/console/Tests/Fixtures/command_astext.txt new file mode 100644 index 000000000..4d9055d30 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_astext.txt @@ -0,0 +1,18 @@ +Usage: + namespace:name + name + +Arguments: + command The command to execute + +Options: + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Help: + help diff --git a/vendor/symfony/console/Tests/Fixtures/command_asxml.txt b/vendor/symfony/console/Tests/Fixtures/command_asxml.txt new file mode 100644 index 000000000..5e776238a --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_asxml.txt @@ -0,0 +1,38 @@ + + + + namespace:name + name + + description + help + + + The command to execute + + + + + + + + + + + + + diff --git a/vendor/symfony/console/Tests/Fixtures/command_mbstring.md b/vendor/symfony/console/Tests/Fixtures/command_mbstring.md new file mode 100644 index 000000000..2adac53f0 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_mbstring.md @@ -0,0 +1,33 @@ +descriptor:åèä +-------------- + +* Description: command åèä description +* Usage: + + * `descriptor:åèä [-o|--option_åèä] [--] ` + * `descriptor:åèä -o|--option_name ` + * `descriptor:åèä ` + +command åèä help + +### Arguments: + +**argument_åèä:** + +* Name: argument_åèä +* Is required: yes +* Is array: no +* Description: +* Default: `NULL` + +### Options: + +**option_åèä:** + +* Name: `--option_åèä` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* Default: `false` diff --git a/vendor/symfony/console/Tests/Fixtures/command_mbstring.txt b/vendor/symfony/console/Tests/Fixtures/command_mbstring.txt new file mode 100644 index 000000000..969a06524 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/command_mbstring.txt @@ -0,0 +1,13 @@ +Usage: + descriptor:åèä [options] [--] + descriptor:åèä -o|--option_name + descriptor:åèä + +Arguments: + argument_åèä + +Options: + -o, --option_åèä + +Help: + command åèä help diff --git a/vendor/symfony/console/Tests/Fixtures/definition_astext.txt b/vendor/symfony/console/Tests/Fixtures/definition_astext.txt new file mode 100644 index 000000000..0431c072a --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/definition_astext.txt @@ -0,0 +1,11 @@ +Arguments: + foo The foo argument + baz The baz argument [default: true] + bar The bar argument [default: ["http://foo.com/"]] + +Options: + -f, --foo=FOO The foo option + --baz[=BAZ] The baz option [default: false] + -b, --bar[=BAR] The bar option [default: "bar"] + --qux[=QUX] The qux option [default: ["http://foo.com/","bar"]] (multiple values allowed) + --qux2[=QUX2] The qux2 option [default: {"foo":"bar"}] (multiple values allowed) \ No newline at end of file diff --git a/vendor/symfony/console/Tests/Fixtures/definition_asxml.txt b/vendor/symfony/console/Tests/Fixtures/definition_asxml.txt new file mode 100644 index 000000000..eec8c079e --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/definition_asxml.txt @@ -0,0 +1,39 @@ + + + + + The foo argument + + + + The baz argument + + true + + + + The bar argument + + bar + + + + + + + + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_1.json b/vendor/symfony/console/Tests/Fixtures/input_argument_1.json new file mode 100644 index 000000000..0ab932960 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_1.json @@ -0,0 +1,7 @@ +{ + "name": "argument_name", + "is_required": true, + "is_array": false, + "description": "", + "default": null +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_1.md b/vendor/symfony/console/Tests/Fixtures/input_argument_1.md new file mode 100644 index 000000000..88f311ab5 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_1.md @@ -0,0 +1,7 @@ +**argument_name:** + +* Name: argument_name +* Is required: yes +* Is array: no +* Description: +* Default: `NULL` diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_1.txt b/vendor/symfony/console/Tests/Fixtures/input_argument_1.txt new file mode 100644 index 000000000..55035183f --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_1.txt @@ -0,0 +1 @@ + argument_name diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_1.xml b/vendor/symfony/console/Tests/Fixtures/input_argument_1.xml new file mode 100644 index 000000000..cb37f812c --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_1.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_2.json b/vendor/symfony/console/Tests/Fixtures/input_argument_2.json new file mode 100644 index 000000000..7450016ff --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_2.json @@ -0,0 +1,7 @@ +{ + "name": "argument_name", + "is_required": false, + "is_array": true, + "description": "argument description", + "default": [] +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_2.md b/vendor/symfony/console/Tests/Fixtures/input_argument_2.md new file mode 100644 index 000000000..3cdb00cc8 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_2.md @@ -0,0 +1,7 @@ +**argument_name:** + +* Name: argument_name +* Is required: no +* Is array: yes +* Description: argument description +* Default: `array ()` diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_2.txt b/vendor/symfony/console/Tests/Fixtures/input_argument_2.txt new file mode 100644 index 000000000..e71366074 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_2.txt @@ -0,0 +1 @@ + argument_name argument description diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_2.xml b/vendor/symfony/console/Tests/Fixtures/input_argument_2.xml new file mode 100644 index 000000000..629da5a98 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_2.xml @@ -0,0 +1,5 @@ + + + argument description + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_3.json b/vendor/symfony/console/Tests/Fixtures/input_argument_3.json new file mode 100644 index 000000000..9a83c5a54 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_3.json @@ -0,0 +1,7 @@ +{ + "name": "argument_name", + "is_required": false, + "is_array": false, + "description": "argument description", + "default": "default_value" +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_3.md b/vendor/symfony/console/Tests/Fixtures/input_argument_3.md new file mode 100644 index 000000000..be1c443ae --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_3.md @@ -0,0 +1,7 @@ +**argument_name:** + +* Name: argument_name +* Is required: no +* Is array: no +* Description: argument description +* Default: `'default_value'` diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_3.txt b/vendor/symfony/console/Tests/Fixtures/input_argument_3.txt new file mode 100644 index 000000000..6b76639e0 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_3.txt @@ -0,0 +1 @@ + argument_name argument description [default: "default_value"] diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_3.xml b/vendor/symfony/console/Tests/Fixtures/input_argument_3.xml new file mode 100644 index 000000000..399a5c864 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_3.xml @@ -0,0 +1,7 @@ + + + argument description + + default_value + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_4.json b/vendor/symfony/console/Tests/Fixtures/input_argument_4.json new file mode 100644 index 000000000..cbcb19b39 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_4.json @@ -0,0 +1,7 @@ +{ + "name": "argument_name", + "is_required": true, + "is_array": false, + "description": "multiline argument description", + "default": null +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_4.md b/vendor/symfony/console/Tests/Fixtures/input_argument_4.md new file mode 100644 index 000000000..f026ab376 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_4.md @@ -0,0 +1,8 @@ +**argument_name:** + +* Name: argument_name +* Is required: yes +* Is array: no +* Description: multiline + argument description +* Default: `NULL` diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_4.txt b/vendor/symfony/console/Tests/Fixtures/input_argument_4.txt new file mode 100644 index 000000000..fc7d669a1 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_4.txt @@ -0,0 +1,2 @@ + argument_name multiline + argument description diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_4.xml b/vendor/symfony/console/Tests/Fixtures/input_argument_4.xml new file mode 100644 index 000000000..5ca135ec2 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_4.xml @@ -0,0 +1,6 @@ + + + multiline +argument description + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.json b/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.json new file mode 100644 index 000000000..933423510 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.json @@ -0,0 +1,7 @@ +{ + "name": "argument_name", + "is_required": false, + "is_array": false, + "description": "argument description", + "default": "style" +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.md b/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.md new file mode 100644 index 000000000..45adf2f48 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.md @@ -0,0 +1,7 @@ +**argument_name:** + +* Name: argument_name +* Is required: no +* Is array: no +* Description: argument description +* Default: `'style'` diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.txt b/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.txt new file mode 100644 index 000000000..35384a6be --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.txt @@ -0,0 +1 @@ + argument_name argument description [default: "\style\"] diff --git a/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.xml b/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.xml new file mode 100644 index 000000000..73332c796 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_argument_with_style.xml @@ -0,0 +1,7 @@ + + + argument description + + <comment>style</> + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_1.json b/vendor/symfony/console/Tests/Fixtures/input_definition_1.json new file mode 100644 index 000000000..44aa2c2e1 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_1.json @@ -0,0 +1,4 @@ +{ + "arguments": [], + "options": [] +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_1.md b/vendor/symfony/console/Tests/Fixtures/input_definition_1.md new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_1.txt b/vendor/symfony/console/Tests/Fixtures/input_definition_1.txt new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_1.xml b/vendor/symfony/console/Tests/Fixtures/input_definition_1.xml new file mode 100644 index 000000000..b5481ce12 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_1.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_2.json b/vendor/symfony/console/Tests/Fixtures/input_definition_2.json new file mode 100644 index 000000000..7cfd57e56 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_2.json @@ -0,0 +1,12 @@ +{ + "arguments": { + "argument_name": { + "name": "argument_name", + "is_required": true, + "is_array": false, + "description": "", + "default": null + } + }, + "options": [] +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_2.md b/vendor/symfony/console/Tests/Fixtures/input_definition_2.md new file mode 100644 index 000000000..923191cdc --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_2.md @@ -0,0 +1,9 @@ +### Arguments: + +**argument_name:** + +* Name: argument_name +* Is required: yes +* Is array: no +* Description: +* Default: `NULL` diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_2.txt b/vendor/symfony/console/Tests/Fixtures/input_definition_2.txt new file mode 100644 index 000000000..73b0f308a --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_2.txt @@ -0,0 +1,2 @@ +Arguments: + argument_name diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_2.xml b/vendor/symfony/console/Tests/Fixtures/input_definition_2.xml new file mode 100644 index 000000000..102efc148 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_2.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_3.json b/vendor/symfony/console/Tests/Fixtures/input_definition_3.json new file mode 100644 index 000000000..3b3cf73c5 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_3.json @@ -0,0 +1,14 @@ +{ + "arguments": [], + "options": { + "option_name": { + "name": "--option_name", + "shortcut": "-o", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "", + "default": false + } + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_3.md b/vendor/symfony/console/Tests/Fixtures/input_definition_3.md new file mode 100644 index 000000000..40fd7b0a9 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_3.md @@ -0,0 +1,11 @@ +### Options: + +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* Default: `false` diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_3.txt b/vendor/symfony/console/Tests/Fixtures/input_definition_3.txt new file mode 100644 index 000000000..c02766fd3 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_3.txt @@ -0,0 +1,2 @@ +Options: + -o, --option_name diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_3.xml b/vendor/symfony/console/Tests/Fixtures/input_definition_3.xml new file mode 100644 index 000000000..bc9515154 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_3.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_4.json b/vendor/symfony/console/Tests/Fixtures/input_definition_4.json new file mode 100644 index 000000000..d4a51e82e --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_4.json @@ -0,0 +1,22 @@ +{ + "arguments": { + "argument_name": { + "name": "argument_name", + "is_required": true, + "is_array": false, + "description": "", + "default": null + } + }, + "options": { + "option_name": { + "name": "--option_name", + "shortcut": "-o", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "", + "default": false + } + } +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_4.md b/vendor/symfony/console/Tests/Fixtures/input_definition_4.md new file mode 100644 index 000000000..a31feea47 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_4.md @@ -0,0 +1,21 @@ +### Arguments: + +**argument_name:** + +* Name: argument_name +* Is required: yes +* Is array: no +* Description: +* Default: `NULL` + +### Options: + +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* Default: `false` diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_4.txt b/vendor/symfony/console/Tests/Fixtures/input_definition_4.txt new file mode 100644 index 000000000..63aa81d2d --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_4.txt @@ -0,0 +1,5 @@ +Arguments: + argument_name + +Options: + -o, --option_name diff --git a/vendor/symfony/console/Tests/Fixtures/input_definition_4.xml b/vendor/symfony/console/Tests/Fixtures/input_definition_4.xml new file mode 100644 index 000000000..cffceecef --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_definition_4.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_1.json b/vendor/symfony/console/Tests/Fixtures/input_option_1.json new file mode 100644 index 000000000..f86bf9671 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_1.json @@ -0,0 +1,9 @@ +{ + "name": "--option_name", + "shortcut": "-o", + "accept_value": false, + "is_value_required": false, + "is_multiple": false, + "description": "", + "default": false +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_1.md b/vendor/symfony/console/Tests/Fixtures/input_option_1.md new file mode 100644 index 000000000..6f9e9a7e0 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_1.md @@ -0,0 +1,9 @@ +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: no +* Is value required: no +* Is multiple: no +* Description: +* Default: `false` diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_1.txt b/vendor/symfony/console/Tests/Fixtures/input_option_1.txt new file mode 100644 index 000000000..3a5e4eede --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_1.txt @@ -0,0 +1 @@ + -o, --option_name diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_1.xml b/vendor/symfony/console/Tests/Fixtures/input_option_1.xml new file mode 100644 index 000000000..8a64ea652 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_1.xml @@ -0,0 +1,4 @@ + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_2.json b/vendor/symfony/console/Tests/Fixtures/input_option_2.json new file mode 100644 index 000000000..32dbab21a --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_2.json @@ -0,0 +1,9 @@ +{ + "name": "--option_name", + "shortcut": "-o", + "accept_value": true, + "is_value_required": false, + "is_multiple": false, + "description": "option description", + "default": "default_value" +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_2.md b/vendor/symfony/console/Tests/Fixtures/input_option_2.md new file mode 100644 index 000000000..634ac0b03 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_2.md @@ -0,0 +1,9 @@ +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: yes +* Is value required: no +* Is multiple: no +* Description: option description +* Default: `'default_value'` diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_2.txt b/vendor/symfony/console/Tests/Fixtures/input_option_2.txt new file mode 100644 index 000000000..1009eff16 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_2.txt @@ -0,0 +1 @@ + -o, --option_name[=OPTION_NAME] option description [default: "default_value"] diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_2.xml b/vendor/symfony/console/Tests/Fixtures/input_option_2.xml new file mode 100644 index 000000000..4afac5b04 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_2.xml @@ -0,0 +1,7 @@ + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_3.json b/vendor/symfony/console/Tests/Fixtures/input_option_3.json new file mode 100644 index 000000000..6d55a6efe --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_3.json @@ -0,0 +1,9 @@ +{ + "name": "--option_name", + "shortcut": "-o", + "accept_value": true, + "is_value_required": true, + "is_multiple": false, + "description": "option description", + "default": null +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_3.md b/vendor/symfony/console/Tests/Fixtures/input_option_3.md new file mode 100644 index 000000000..34282896b --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_3.md @@ -0,0 +1,9 @@ +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: option description +* Default: `NULL` diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_3.txt b/vendor/symfony/console/Tests/Fixtures/input_option_3.txt new file mode 100644 index 000000000..947bb6527 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_3.txt @@ -0,0 +1 @@ + -o, --option_name=OPTION_NAME option description diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_3.xml b/vendor/symfony/console/Tests/Fixtures/input_option_3.xml new file mode 100644 index 000000000..dcc0631cf --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_3.xml @@ -0,0 +1,5 @@ + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_4.json b/vendor/symfony/console/Tests/Fixtures/input_option_4.json new file mode 100644 index 000000000..788a8ed43 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_4.json @@ -0,0 +1,9 @@ +{ + "name": "--option_name", + "shortcut": "-o", + "accept_value": true, + "is_value_required": false, + "is_multiple": true, + "description": "option description", + "default": [] +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_4.md b/vendor/symfony/console/Tests/Fixtures/input_option_4.md new file mode 100644 index 000000000..8ffba56e7 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_4.md @@ -0,0 +1,9 @@ +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: yes +* Is value required: no +* Is multiple: yes +* Description: option description +* Default: `array ()` diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_4.txt b/vendor/symfony/console/Tests/Fixtures/input_option_4.txt new file mode 100644 index 000000000..27edf77b4 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_4.txt @@ -0,0 +1 @@ + -o, --option_name[=OPTION_NAME] option description (multiple values allowed) diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_4.xml b/vendor/symfony/console/Tests/Fixtures/input_option_4.xml new file mode 100644 index 000000000..5e2418b14 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_4.xml @@ -0,0 +1,5 @@ + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_5.json b/vendor/symfony/console/Tests/Fixtures/input_option_5.json new file mode 100644 index 000000000..9f34d8321 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_5.json @@ -0,0 +1,9 @@ +{ + "name": "--option_name", + "shortcut": "-o", + "accept_value": true, + "is_value_required": true, + "is_multiple": false, + "description": "multiline option description", + "default": null +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_5.md b/vendor/symfony/console/Tests/Fixtures/input_option_5.md new file mode 100644 index 000000000..82f51cad3 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_5.md @@ -0,0 +1,10 @@ +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: multiline + option description +* Default: `NULL` diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_5.txt b/vendor/symfony/console/Tests/Fixtures/input_option_5.txt new file mode 100644 index 000000000..9563b4cab --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_5.txt @@ -0,0 +1,2 @@ + -o, --option_name=OPTION_NAME multiline + option description diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_5.xml b/vendor/symfony/console/Tests/Fixtures/input_option_5.xml new file mode 100644 index 000000000..90040ccd0 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_5.xml @@ -0,0 +1,6 @@ + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_6.json b/vendor/symfony/console/Tests/Fixtures/input_option_6.json new file mode 100644 index 000000000..0638de03e --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_6.json @@ -0,0 +1,9 @@ +{ + "name": "--option_name", + "shortcut": "-o|-O", + "accept_value": true, + "is_value_required": true, + "is_multiple": false, + "description": "option with multiple shortcuts", + "default": null +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_6.md b/vendor/symfony/console/Tests/Fixtures/input_option_6.md new file mode 100644 index 000000000..ed1ea1c84 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_6.md @@ -0,0 +1,9 @@ +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o|-O` +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: option with multiple shortcuts +* Default: `NULL` diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_6.txt b/vendor/symfony/console/Tests/Fixtures/input_option_6.txt new file mode 100644 index 000000000..0e6c9759b --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_6.txt @@ -0,0 +1 @@ + -o|O, --option_name=OPTION_NAME option with multiple shortcuts diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_6.xml b/vendor/symfony/console/Tests/Fixtures/input_option_6.xml new file mode 100644 index 000000000..06126a2f5 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_6.xml @@ -0,0 +1,5 @@ + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_with_style.json b/vendor/symfony/console/Tests/Fixtures/input_option_with_style.json new file mode 100644 index 000000000..df328bf82 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_with_style.json @@ -0,0 +1,9 @@ +{ + "name": "--option_name", + "shortcut": "-o", + "accept_value": true, + "is_value_required": true, + "is_multiple": false, + "description": "option description", + "default": "style" +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_with_style.md b/vendor/symfony/console/Tests/Fixtures/input_option_with_style.md new file mode 100644 index 000000000..3f6dd2369 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_with_style.md @@ -0,0 +1,9 @@ +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: yes +* Is value required: yes +* Is multiple: no +* Description: option description +* Default: `'style'` diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_with_style.txt b/vendor/symfony/console/Tests/Fixtures/input_option_with_style.txt new file mode 100644 index 000000000..880a53518 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_with_style.txt @@ -0,0 +1 @@ + -o, --option_name=OPTION_NAME option description [default: "\style\"] diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_with_style.xml b/vendor/symfony/console/Tests/Fixtures/input_option_with_style.xml new file mode 100644 index 000000000..764b9e652 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_with_style.xml @@ -0,0 +1,7 @@ + + diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.json b/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.json new file mode 100644 index 000000000..b1754550b --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.json @@ -0,0 +1,12 @@ +{ + "name": "--option_name", + "shortcut": "-o", + "accept_value": true, + "is_value_required": true, + "is_multiple": true, + "description": "option description", + "default": [ + "Hello", + "world" + ] +} diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.md b/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.md new file mode 100644 index 000000000..24e58b530 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.md @@ -0,0 +1,9 @@ +**option_name:** + +* Name: `--option_name` +* Shortcut: `-o` +* Accept value: yes +* Is value required: yes +* Is multiple: yes +* Description: option description +* Default: `array ( 0 => 'Hello', 1 => 'world',)` diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.txt b/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.txt new file mode 100644 index 000000000..265c18c5a --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.txt @@ -0,0 +1 @@ + -o, --option_name=OPTION_NAME option description [default: ["\Hello\","\world\"]] (multiple values allowed) diff --git a/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.xml b/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.xml new file mode 100644 index 000000000..09dc86583 --- /dev/null +++ b/vendor/symfony/console/Tests/Fixtures/input_option_with_style_array.xml @@ -0,0 +1,8 @@ + + diff --git a/vendor/symfony/console/Tests/Formatter/OutputFormatterStyleStackTest.php b/vendor/symfony/console/Tests/Formatter/OutputFormatterStyleStackTest.php new file mode 100644 index 000000000..6cd7c82b4 --- /dev/null +++ b/vendor/symfony/console/Tests/Formatter/OutputFormatterStyleStackTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Formatter; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Formatter\OutputFormatterStyleStack; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; + +class OutputFormatterStyleStackTest extends TestCase +{ + public function testPush() + { + $stack = new OutputFormatterStyleStack(); + $stack->push($s1 = new OutputFormatterStyle('white', 'black')); + $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue')); + + $this->assertEquals($s2, $stack->getCurrent()); + + $stack->push($s3 = new OutputFormatterStyle('green', 'red')); + + $this->assertEquals($s3, $stack->getCurrent()); + } + + public function testPop() + { + $stack = new OutputFormatterStyleStack(); + $stack->push($s1 = new OutputFormatterStyle('white', 'black')); + $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue')); + + $this->assertEquals($s2, $stack->pop()); + $this->assertEquals($s1, $stack->pop()); + } + + public function testPopEmpty() + { + $stack = new OutputFormatterStyleStack(); + $style = new OutputFormatterStyle(); + + $this->assertEquals($style, $stack->pop()); + } + + public function testPopNotLast() + { + $stack = new OutputFormatterStyleStack(); + $stack->push($s1 = new OutputFormatterStyle('white', 'black')); + $stack->push($s2 = new OutputFormatterStyle('yellow', 'blue')); + $stack->push($s3 = new OutputFormatterStyle('green', 'red')); + + $this->assertEquals($s2, $stack->pop($s2)); + $this->assertEquals($s1, $stack->pop()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInvalidPop() + { + $stack = new OutputFormatterStyleStack(); + $stack->push(new OutputFormatterStyle('white', 'black')); + $stack->pop(new OutputFormatterStyle('yellow', 'blue')); + } +} diff --git a/vendor/symfony/console/Tests/Formatter/OutputFormatterStyleTest.php b/vendor/symfony/console/Tests/Formatter/OutputFormatterStyleTest.php new file mode 100644 index 000000000..ddf77902c --- /dev/null +++ b/vendor/symfony/console/Tests/Formatter/OutputFormatterStyleTest.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Formatter; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; + +class OutputFormatterStyleTest extends TestCase +{ + public function testConstructor() + { + $style = new OutputFormatterStyle('green', 'black', array('bold', 'underscore')); + $this->assertEquals("\033[32;40;1;4mfoo\033[39;49;22;24m", $style->apply('foo')); + + $style = new OutputFormatterStyle('red', null, array('blink')); + $this->assertEquals("\033[31;5mfoo\033[39;25m", $style->apply('foo')); + + $style = new OutputFormatterStyle(null, 'white'); + $this->assertEquals("\033[47mfoo\033[49m", $style->apply('foo')); + } + + public function testForeground() + { + $style = new OutputFormatterStyle(); + + $style->setForeground('black'); + $this->assertEquals("\033[30mfoo\033[39m", $style->apply('foo')); + + $style->setForeground('blue'); + $this->assertEquals("\033[34mfoo\033[39m", $style->apply('foo')); + + $style->setForeground('default'); + $this->assertEquals("\033[39mfoo\033[39m", $style->apply('foo')); + + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException'); + $style->setForeground('undefined-color'); + } + + public function testBackground() + { + $style = new OutputFormatterStyle(); + + $style->setBackground('black'); + $this->assertEquals("\033[40mfoo\033[49m", $style->apply('foo')); + + $style->setBackground('yellow'); + $this->assertEquals("\033[43mfoo\033[49m", $style->apply('foo')); + + $style->setBackground('default'); + $this->assertEquals("\033[49mfoo\033[49m", $style->apply('foo')); + + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException'); + $style->setBackground('undefined-color'); + } + + public function testOptions() + { + $style = new OutputFormatterStyle(); + + $style->setOptions(array('reverse', 'conceal')); + $this->assertEquals("\033[7;8mfoo\033[27;28m", $style->apply('foo')); + + $style->setOption('bold'); + $this->assertEquals("\033[7;8;1mfoo\033[27;28;22m", $style->apply('foo')); + + $style->unsetOption('reverse'); + $this->assertEquals("\033[8;1mfoo\033[28;22m", $style->apply('foo')); + + $style->setOption('bold'); + $this->assertEquals("\033[8;1mfoo\033[28;22m", $style->apply('foo')); + + $style->setOptions(array('bold')); + $this->assertEquals("\033[1mfoo\033[22m", $style->apply('foo')); + + try { + $style->setOption('foo'); + $this->fail('->setOption() throws an \InvalidArgumentException when the option does not exist in the available options'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options'); + $this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->setOption() throws an \InvalidArgumentException when the option does not exist in the available options'); + } + + try { + $style->unsetOption('foo'); + $this->fail('->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options'); + $this->assertContains('Invalid option specified: "foo"', $e->getMessage(), '->unsetOption() throws an \InvalidArgumentException when the option does not exist in the available options'); + } + } +} diff --git a/vendor/symfony/console/Tests/Formatter/OutputFormatterTest.php b/vendor/symfony/console/Tests/Formatter/OutputFormatterTest.php new file mode 100644 index 000000000..866c31a44 --- /dev/null +++ b/vendor/symfony/console/Tests/Formatter/OutputFormatterTest.php @@ -0,0 +1,280 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Formatter; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; + +class OutputFormatterTest extends TestCase +{ + public function testEmptyTag() + { + $formatter = new OutputFormatter(true); + $this->assertEquals('foo<>bar', $formatter->format('foo<>bar')); + } + + public function testLGCharEscaping() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals('fooformat('foo\\assertEquals('some info', $formatter->format('\\some info\\')); + $this->assertEquals('\\some info\\', OutputFormatter::escape('some info')); + + $this->assertEquals( + "\033[33mSymfony\\Component\\Console does work very well!\033[39m", + $formatter->format('Symfony\Component\Console does work very well!') + ); + } + + public function testBundledStyles() + { + $formatter = new OutputFormatter(true); + + $this->assertTrue($formatter->hasStyle('error')); + $this->assertTrue($formatter->hasStyle('info')); + $this->assertTrue($formatter->hasStyle('comment')); + $this->assertTrue($formatter->hasStyle('question')); + + $this->assertEquals( + "\033[37;41msome error\033[39;49m", + $formatter->format('some error') + ); + $this->assertEquals( + "\033[32msome info\033[39m", + $formatter->format('some info') + ); + $this->assertEquals( + "\033[33msome comment\033[39m", + $formatter->format('some comment') + ); + $this->assertEquals( + "\033[30;46msome question\033[39;49m", + $formatter->format('some question') + ); + } + + public function testNestedStyles() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "\033[37;41msome \033[39;49m\033[32msome info\033[39m\033[37;41m error\033[39;49m", + $formatter->format('some some info error') + ); + } + + public function testAdjacentStyles() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "\033[37;41msome error\033[39;49m\033[32msome info\033[39m", + $formatter->format('some errorsome info') + ); + } + + public function testStyleMatchingNotGreedy() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "(\033[32m>=2.0,<2.3\033[39m)", + $formatter->format('(>=2.0,<2.3)') + ); + } + + public function testStyleEscaping() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "(\033[32mz>=2.0,<<format('('.$formatter->escape('z>=2.0,<\\<)') + ); + + $this->assertEquals( + "\033[32msome error\033[39m", + $formatter->format(''.$formatter->escape('some error').'') + ); + } + + public function testDeepNestedStyles() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals( + "\033[37;41merror\033[39;49m\033[32minfo\033[39m\033[33mcomment\033[39m\033[37;41merror\033[39;49m", + $formatter->format('errorinfocommenterror') + ); + } + + public function testNewStyle() + { + $formatter = new OutputFormatter(true); + + $style = new OutputFormatterStyle('blue', 'white'); + $formatter->setStyle('test', $style); + + $this->assertEquals($style, $formatter->getStyle('test')); + $this->assertNotEquals($style, $formatter->getStyle('info')); + + $style = new OutputFormatterStyle('blue', 'white'); + $formatter->setStyle('b', $style); + + $this->assertEquals("\033[34;47msome \033[39;49m\033[34;47mcustom\033[39;49m\033[34;47m msg\033[39;49m", $formatter->format('some custom msg')); + } + + public function testRedefineStyle() + { + $formatter = new OutputFormatter(true); + + $style = new OutputFormatterStyle('blue', 'white'); + $formatter->setStyle('info', $style); + + $this->assertEquals("\033[34;47msome custom msg\033[39;49m", $formatter->format('some custom msg')); + } + + public function testInlineStyle() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('some text')); + $this->assertEquals("\033[34;41msome text\033[39;49m", $formatter->format('some text')); + } + + public function testNonStyleTag() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals("\033[32msome \033[39m\033[32m\033[39m\033[32m \033[39m\033[32m\033[39m\033[32m styled \033[39m\033[32m

\033[39m\033[32msingle-char tag\033[39m\033[32m

\033[39m", $formatter->format('some styled

single-char tag

')); + } + + public function testFormatLongString() + { + $formatter = new OutputFormatter(true); + $long = str_repeat('\\', 14000); + $this->assertEquals("\033[37;41msome error\033[39;49m".$long, $formatter->format('some error'.$long)); + } + + public function testFormatToStringObject() + { + $formatter = new OutputFormatter(false); + $this->assertEquals( + 'some info', $formatter->format(new TableCell()) + ); + } + + public function testNotDecoratedFormatter() + { + $formatter = new OutputFormatter(false); + + $this->assertTrue($formatter->hasStyle('error')); + $this->assertTrue($formatter->hasStyle('info')); + $this->assertTrue($formatter->hasStyle('comment')); + $this->assertTrue($formatter->hasStyle('question')); + + $this->assertEquals( + 'some error', $formatter->format('some error') + ); + $this->assertEquals( + 'some info', $formatter->format('some info') + ); + $this->assertEquals( + 'some comment', $formatter->format('some comment') + ); + $this->assertEquals( + 'some question', $formatter->format('some question') + ); + $this->assertEquals( + 'some text with inline style', $formatter->format('some text with inline style') + ); + + $formatter->setDecorated(true); + + $this->assertEquals( + "\033[37;41msome error\033[39;49m", $formatter->format('some error') + ); + $this->assertEquals( + "\033[32msome info\033[39m", $formatter->format('some info') + ); + $this->assertEquals( + "\033[33msome comment\033[39m", $formatter->format('some comment') + ); + $this->assertEquals( + "\033[30;46msome question\033[39;49m", $formatter->format('some question') + ); + $this->assertEquals( + "\033[31msome text with inline style\033[39m", $formatter->format('some text with inline style') + ); + } + + public function testContentWithLineBreaks() + { + $formatter = new OutputFormatter(true); + + $this->assertEquals(<<format(<<<'EOF' + +some text +EOF + )); + + $this->assertEquals(<<format(<<<'EOF' +some text + +EOF + )); + + $this->assertEquals(<<format(<<<'EOF' + +some text + +EOF + )); + + $this->assertEquals(<<format(<<<'EOF' + +some text +more text + +EOF + )); + } +} + +class TableCell +{ + public function __toString() + { + return 'some info'; + } +} diff --git a/vendor/symfony/console/Tests/Helper/FormatterHelperTest.php b/vendor/symfony/console/Tests/Helper/FormatterHelperTest.php new file mode 100644 index 000000000..998865f2c --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/FormatterHelperTest.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Helper\FormatterHelper; + +class FormatterHelperTest extends TestCase +{ + public function testFormatSection() + { + $formatter = new FormatterHelper(); + + $this->assertEquals( + '[cli] Some text to display', + $formatter->formatSection('cli', 'Some text to display'), + '::formatSection() formats a message in a section' + ); + } + + public function testFormatBlock() + { + $formatter = new FormatterHelper(); + + $this->assertEquals( + ' Some text to display ', + $formatter->formatBlock('Some text to display', 'error'), + '::formatBlock() formats a message in a block' + ); + + $this->assertEquals( + ' Some text to display '."\n". + ' foo bar ', + $formatter->formatBlock(array('Some text to display', 'foo bar'), 'error'), + '::formatBlock() formats a message in a block' + ); + + $this->assertEquals( + ' '."\n". + ' Some text to display '."\n". + ' ', + $formatter->formatBlock('Some text to display', 'error', true), + '::formatBlock() formats a message in a block' + ); + } + + public function testFormatBlockWithDiacriticLetters() + { + $formatter = new FormatterHelper(); + + $this->assertEquals( + ' '."\n". + ' Du texte à afficher '."\n". + ' ', + $formatter->formatBlock('Du texte à afficher', 'error', true), + '::formatBlock() formats a message in a block' + ); + } + + public function testFormatBlockWithDoubleWidthDiacriticLetters() + { + $formatter = new FormatterHelper(); + $this->assertEquals( + ' '."\n". + ' 表示するテキスト '."\n". + ' ', + $formatter->formatBlock('表示するテキスト', 'error', true), + '::formatBlock() formats a message in a block' + ); + } + + public function testFormatBlockLGEscaping() + { + $formatter = new FormatterHelper(); + + $this->assertEquals( + ' '."\n". + ' \some info\ '."\n". + ' ', + $formatter->formatBlock('some info', 'error', true), + '::formatBlock() escapes \'<\' chars' + ); + } +} diff --git a/vendor/symfony/console/Tests/Helper/HelperSetTest.php b/vendor/symfony/console/Tests/Helper/HelperSetTest.php new file mode 100644 index 000000000..aceef7041 --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/HelperSetTest.php @@ -0,0 +1,127 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Command\Command; + +class HelperSetTest extends TestCase +{ + public function testConstructor() + { + $mock_helper = $this->getGenericMockHelper('fake_helper'); + $helperset = new HelperSet(array('fake_helper_alias' => $mock_helper)); + + $this->assertEquals($mock_helper, $helperset->get('fake_helper_alias'), '__construct sets given helper to helpers'); + $this->assertTrue($helperset->has('fake_helper_alias'), '__construct sets helper alias for given helper'); + } + + public function testSet() + { + $helperset = new HelperSet(); + $helperset->set($this->getGenericMockHelper('fake_helper', $helperset)); + $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper to helpers'); + + $helperset = new HelperSet(); + $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset)); + $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset)); + $this->assertTrue($helperset->has('fake_helper_01'), '->set() will set multiple helpers on consecutive calls'); + $this->assertTrue($helperset->has('fake_helper_02'), '->set() will set multiple helpers on consecutive calls'); + + $helperset = new HelperSet(); + $helperset->set($this->getGenericMockHelper('fake_helper', $helperset), 'fake_helper_alias'); + $this->assertTrue($helperset->has('fake_helper'), '->set() adds helper alias when set'); + $this->assertTrue($helperset->has('fake_helper_alias'), '->set() adds helper alias when set'); + } + + public function testHas() + { + $helperset = new HelperSet(array('fake_helper_alias' => $this->getGenericMockHelper('fake_helper'))); + $this->assertTrue($helperset->has('fake_helper'), '->has() finds set helper'); + $this->assertTrue($helperset->has('fake_helper_alias'), '->has() finds set helper by alias'); + } + + public function testGet() + { + $helper_01 = $this->getGenericMockHelper('fake_helper_01'); + $helper_02 = $this->getGenericMockHelper('fake_helper_02'); + $helperset = new HelperSet(array('fake_helper_01_alias' => $helper_01, 'fake_helper_02_alias' => $helper_02)); + $this->assertEquals($helper_01, $helperset->get('fake_helper_01'), '->get() returns correct helper by name'); + $this->assertEquals($helper_01, $helperset->get('fake_helper_01_alias'), '->get() returns correct helper by alias'); + $this->assertEquals($helper_02, $helperset->get('fake_helper_02'), '->get() returns correct helper by name'); + $this->assertEquals($helper_02, $helperset->get('fake_helper_02_alias'), '->get() returns correct helper by alias'); + + $helperset = new HelperSet(); + try { + $helperset->get('foo'); + $this->fail('->get() throws InvalidArgumentException when helper not found'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws InvalidArgumentException when helper not found'); + $this->assertInstanceOf('Symfony\Component\Console\Exception\ExceptionInterface', $e, '->get() throws domain specific exception when helper not found'); + $this->assertContains('The helper "foo" is not defined.', $e->getMessage(), '->get() throws InvalidArgumentException when helper not found'); + } + } + + public function testSetCommand() + { + $cmd_01 = new Command('foo'); + $cmd_02 = new Command('bar'); + + $helperset = new HelperSet(); + $helperset->setCommand($cmd_01); + $this->assertEquals($cmd_01, $helperset->getCommand(), '->setCommand() stores given command'); + + $helperset = new HelperSet(); + $helperset->setCommand($cmd_01); + $helperset->setCommand($cmd_02); + $this->assertEquals($cmd_02, $helperset->getCommand(), '->setCommand() overwrites stored command with consecutive calls'); + } + + public function testGetCommand() + { + $cmd = new Command('foo'); + $helperset = new HelperSet(); + $helperset->setCommand($cmd); + $this->assertEquals($cmd, $helperset->getCommand(), '->getCommand() retrieves stored command'); + } + + public function testIteration() + { + $helperset = new HelperSet(); + $helperset->set($this->getGenericMockHelper('fake_helper_01', $helperset)); + $helperset->set($this->getGenericMockHelper('fake_helper_02', $helperset)); + + $helpers = array('fake_helper_01', 'fake_helper_02'); + $i = 0; + + foreach ($helperset as $helper) { + $this->assertEquals($helpers[$i++], $helper->getName()); + } + } + + private function getGenericMockHelper($name, HelperSet $helperset = null) + { + $mock_helper = $this->getMockBuilder('\Symfony\Component\Console\Helper\HelperInterface')->getMock(); + $mock_helper->expects($this->any()) + ->method('getName') + ->will($this->returnValue($name)); + + if ($helperset) { + $mock_helper->expects($this->any()) + ->method('setHelperSet') + ->with($this->equalTo($helperset)); + } + + return $mock_helper; + } +} diff --git a/vendor/symfony/console/Tests/Helper/HelperTest.php b/vendor/symfony/console/Tests/Helper/HelperTest.php new file mode 100644 index 000000000..184758244 --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/HelperTest.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Helper\Helper; + +class HelperTest extends TestCase +{ + public function formatTimeProvider() + { + return array( + array(0, '< 1 sec'), + array(1, '1 sec'), + array(2, '2 secs'), + array(59, '59 secs'), + array(60, '1 min'), + array(61, '1 min'), + array(119, '1 min'), + array(120, '2 mins'), + array(121, '2 mins'), + array(3599, '59 mins'), + array(3600, '1 hr'), + array(7199, '1 hr'), + array(7200, '2 hrs'), + array(7201, '2 hrs'), + array(86399, '23 hrs'), + array(86400, '1 day'), + array(86401, '1 day'), + array(172799, '1 day'), + array(172800, '2 days'), + array(172801, '2 days'), + ); + } + + /** + * @dataProvider formatTimeProvider + * + * @param int $secs + * @param string $expectedFormat + */ + public function testFormatTime($secs, $expectedFormat) + { + $this->assertEquals($expectedFormat, Helper::formatTime($secs)); + } +} diff --git a/vendor/symfony/console/Tests/Helper/LegacyDialogHelperTest.php b/vendor/symfony/console/Tests/Helper/LegacyDialogHelperTest.php new file mode 100644 index 000000000..95da978e8 --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/LegacyDialogHelperTest.php @@ -0,0 +1,259 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Helper\DialogHelper; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Output\ConsoleOutput; +use Symfony\Component\Console\Output\StreamOutput; +use Symfony\Component\Console\Exception\InvalidArgumentException; + +/** + * @group legacy + */ +class LegacyDialogHelperTest extends TestCase +{ + public function testSelect() + { + $dialog = new DialogHelper(); + + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $heroes = array('Superman', 'Batman', 'Spiderman'); + + $dialog->setInputStream($this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n")); + $this->assertEquals('2', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '2')); + $this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes)); + $this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes)); + $this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', false)); + + rewind($output->getStream()); + $this->assertContains('Input "Fabien" is not a superhero!', stream_get_contents($output->getStream())); + + try { + $this->assertEquals('1', $dialog->select($output = $this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, 1)); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('Value "Fabien" is invalid', $e->getMessage()); + } + + $this->assertEquals(array('1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true)); + $this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true)); + $this->assertEquals(array('0', '2'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', true)); + $this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, '0,1', false, 'Input "%s" is not a superhero!', true)); + $this->assertEquals(array('0', '1'), $dialog->select($this->getOutputStream(), 'What is your favorite superhero?', $heroes, ' 0 , 1 ', false, 'Input "%s" is not a superhero!', true)); + } + + public function testSelectOnErrorOutput() + { + $dialog = new DialogHelper(); + + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $heroes = array('Superman', 'Batman', 'Spiderman'); + + $dialog->setInputStream($this->getInputStream("Stdout\n1\n")); + $this->assertEquals('1', $dialog->select($output = $this->getConsoleOutput($this->getOutputStream()), 'What is your favorite superhero?', $heroes, null, false, 'Input "%s" is not a superhero!', false)); + + rewind($output->getErrorOutput()->getStream()); + $this->assertContains('Input "Stdout" is not a superhero!', stream_get_contents($output->getErrorOutput()->getStream())); + } + + public function testAsk() + { + $dialog = new DialogHelper(); + + $dialog->setInputStream($this->getInputStream("\n8AM\n")); + + $this->assertEquals('2PM', $dialog->ask($this->getOutputStream(), 'What time is it?', '2PM')); + $this->assertEquals('8AM', $dialog->ask($output = $this->getOutputStream(), 'What time is it?', '2PM')); + + rewind($output->getStream()); + $this->assertEquals('What time is it?', stream_get_contents($output->getStream())); + } + + public function testAskOnErrorOutput() + { + if (!$this->hasSttyAvailable()) { + $this->markTestSkipped('`stderr` is required to test stderr output functionality'); + } + + $dialog = new DialogHelper(); + + $dialog->setInputStream($this->getInputStream("not stdout\n")); + + $this->assertEquals('not stdout', $dialog->ask($output = $this->getConsoleOutput($this->getOutputStream()), 'Where should output go?', 'stderr')); + + rewind($output->getErrorOutput()->getStream()); + $this->assertEquals('Where should output go?', stream_get_contents($output->getErrorOutput()->getStream())); + } + + public function testAskWithAutocomplete() + { + if (!$this->hasSttyAvailable()) { + $this->markTestSkipped('`stty` is required to test autocomplete functionality'); + } + + // Acm + // AcsTest + // + // + // Test + // + // S + // F00oo + $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n"); + + $dialog = new DialogHelper(); + $dialog->setInputStream($inputStream); + + $bundles = array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle'); + + $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles)); + $this->assertEquals('AsseticBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles)); + $this->assertEquals('FrameworkBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles)); + $this->assertEquals('SecurityBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles)); + $this->assertEquals('FooBundleTest', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles)); + $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles)); + $this->assertEquals('AsseticBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles)); + $this->assertEquals('FooBundle', $dialog->ask($this->getOutputStream(), 'Please select a bundle', 'FrameworkBundle', $bundles)); + } + + /** + * @group tty + */ + public function testAskHiddenResponse() + { + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test is not supported on Windows'); + } + + $dialog = new DialogHelper(); + + $dialog->setInputStream($this->getInputStream("8AM\n")); + + $this->assertEquals('8AM', $dialog->askHiddenResponse($this->getOutputStream(), 'What time is it?')); + } + + /** + * @group tty + */ + public function testAskHiddenResponseOnErrorOutput() + { + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test is not supported on Windows'); + } + + $dialog = new DialogHelper(); + + $dialog->setInputStream($this->getInputStream("8AM\n")); + + $this->assertEquals('8AM', $dialog->askHiddenResponse($output = $this->getConsoleOutput($this->getOutputStream()), 'What time is it?')); + + rewind($output->getErrorOutput()->getStream()); + $this->assertContains('What time is it?', stream_get_contents($output->getErrorOutput()->getStream())); + } + + public function testAskConfirmation() + { + $dialog = new DialogHelper(); + + $dialog->setInputStream($this->getInputStream("\n\n")); + $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?')); + $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false)); + + $dialog->setInputStream($this->getInputStream("y\nyes\n")); + $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false)); + $this->assertTrue($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', false)); + + $dialog->setInputStream($this->getInputStream("n\nno\n")); + $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true)); + $this->assertFalse($dialog->askConfirmation($this->getOutputStream(), 'Do you like French fries?', true)); + } + + public function testAskAndValidate() + { + $dialog = new DialogHelper(); + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $question = 'What color was the white horse of Henry IV?'; + $error = 'This is not a color!'; + $validator = function ($color) use ($error) { + if (!in_array($color, array('white', 'black'))) { + throw new InvalidArgumentException($error); + } + + return $color; + }; + + $dialog->setInputStream($this->getInputStream("\nblack\n")); + $this->assertEquals('white', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white')); + $this->assertEquals('black', $dialog->askAndValidate($this->getOutputStream(), $question, $validator, 2, 'white')); + + $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n")); + try { + $this->assertEquals('white', $dialog->askAndValidate($output = $this->getConsoleOutput($this->getOutputStream()), $question, $validator, 2, 'white')); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertEquals($error, $e->getMessage()); + rewind($output->getErrorOutput()->getStream()); + $this->assertContains('What color was the white horse of Henry IV?', stream_get_contents($output->getErrorOutput()->getStream())); + } + } + + public function testNoInteraction() + { + $dialog = new DialogHelper(); + + $input = new ArrayInput(array()); + $input->setInteractive(false); + + $dialog->setInput($input); + + $this->assertEquals('not yet', $dialog->ask($this->getOutputStream(), 'Do you have a job?', 'not yet')); + } + + protected function getInputStream($input) + { + $stream = fopen('php://memory', 'r+', false); + fwrite($stream, $input); + rewind($stream); + + return $stream; + } + + protected function getOutputStream() + { + return new StreamOutput(fopen('php://memory', 'r+', false)); + } + + protected function getConsoleOutput($stderr) + { + $output = new ConsoleOutput(); + $output->setErrorOutput($stderr); + + return $output; + } + + private function hasSttyAvailable() + { + exec('stty 2>&1', $output, $exitcode); + + return $exitcode === 0; + } +} diff --git a/vendor/symfony/console/Tests/Helper/LegacyProgressHelperTest.php b/vendor/symfony/console/Tests/Helper/LegacyProgressHelperTest.php new file mode 100644 index 000000000..b0bc83cfd --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/LegacyProgressHelperTest.php @@ -0,0 +1,225 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Helper\ProgressHelper; +use Symfony\Component\Console\Output\StreamOutput; + +/** + * @group legacy + * @group time-sensitive + */ +class LegacyProgressHelperTest extends TestCase +{ + public function testAdvance() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream()); + $progress->advance(); + + rewind($output->getStream()); + $this->assertEquals($this->generateOutput(' 1 [->--------------------------]'), stream_get_contents($output->getStream())); + } + + public function testAdvanceWithStep() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream()); + $progress->advance(5); + + rewind($output->getStream()); + $this->assertEquals($this->generateOutput(' 5 [----->----------------------]'), stream_get_contents($output->getStream())); + } + + public function testAdvanceMultipleTimes() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream()); + $progress->advance(3); + $progress->advance(2); + + rewind($output->getStream()); + $this->assertEquals($this->generateOutput(' 3 [--->------------------------]').$this->generateOutput(' 5 [----->----------------------]'), stream_get_contents($output->getStream())); + } + + public function testCustomizations() + { + $progress = new ProgressHelper(); + $progress->setBarWidth(10); + $progress->setBarCharacter('_'); + $progress->setEmptyBarCharacter(' '); + $progress->setProgressCharacter('/'); + $progress->setFormat(' %current%/%max% [%bar%] %percent%%'); + $progress->start($output = $this->getOutputStream(), 10); + $progress->advance(); + + rewind($output->getStream()); + $this->assertEquals($this->generateOutput(' 1/10 [_/ ] 10%'), stream_get_contents($output->getStream())); + } + + public function testPercent() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream(), 50); + $progress->display(); + $progress->advance(); + $progress->advance(); + + rewind($output->getStream()); + $this->assertEquals($this->generateOutput(' 0/50 [>---------------------------] 0%').$this->generateOutput(' 1/50 [>---------------------------] 2%').$this->generateOutput(' 2/50 [=>--------------------------] 4%'), stream_get_contents($output->getStream())); + } + + public function testOverwriteWithShorterLine() + { + $progress = new ProgressHelper(); + $progress->setFormat(' %current%/%max% [%bar%] %percent%%'); + $progress->start($output = $this->getOutputStream(), 50); + $progress->display(); + $progress->advance(); + + // set shorter format + $progress->setFormat(' %current%/%max% [%bar%]'); + $progress->advance(); + + rewind($output->getStream()); + $this->assertEquals( + $this->generateOutput(' 0/50 [>---------------------------] 0%'). + $this->generateOutput(' 1/50 [>---------------------------] 2%'). + $this->generateOutput(' 2/50 [=>--------------------------] '), + stream_get_contents($output->getStream()) + ); + } + + public function testSetCurrentProgress() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream(), 50); + $progress->display(); + $progress->advance(); + $progress->setCurrent(15); + $progress->setCurrent(25); + + rewind($output->getStream()); + $this->assertEquals( + $this->generateOutput(' 0/50 [>---------------------------] 0%'). + $this->generateOutput(' 1/50 [>---------------------------] 2%'). + $this->generateOutput(' 15/50 [========>-------------------] 30%'). + $this->generateOutput(' 25/50 [==============>-------------] 50%'), + stream_get_contents($output->getStream()) + ); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage You must start the progress bar + */ + public function testSetCurrentBeforeStarting() + { + $progress = new ProgressHelper(); + $progress->setCurrent(15); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage You can't regress the progress bar + */ + public function testRegressProgress() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream(), 50); + $progress->setCurrent(15); + $progress->setCurrent(10); + } + + public function testRedrawFrequency() + { + $progress = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressHelper')->setMethods(array('display'))->getMock(); + $progress->expects($this->exactly(4)) + ->method('display'); + + $progress->setRedrawFrequency(2); + + $progress->start($output = $this->getOutputStream(), 6); + $progress->setCurrent(1); + $progress->advance(2); + $progress->advance(2); + $progress->advance(1); + } + + public function testMultiByteSupport() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream()); + $progress->setBarCharacter('■'); + $progress->advance(3); + + rewind($output->getStream()); + $this->assertEquals($this->generateOutput(' 3 [■■■>------------------------]'), stream_get_contents($output->getStream())); + } + + public function testClear() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream(), 50); + $progress->setCurrent(25); + $progress->clear(); + + rewind($output->getStream()); + $this->assertEquals( + $this->generateOutput(' 25/50 [==============>-------------] 50%').$this->generateOutput(''), + stream_get_contents($output->getStream()) + ); + } + + public function testPercentNotHundredBeforeComplete() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream(), 200); + $progress->display(); + $progress->advance(199); + $progress->advance(); + + rewind($output->getStream()); + $this->assertEquals($this->generateOutput(' 0/200 [>---------------------------] 0%').$this->generateOutput(' 199/200 [===========================>] 99%').$this->generateOutput(' 200/200 [============================] 100%'), stream_get_contents($output->getStream())); + } + + public function testNonDecoratedOutput() + { + $progress = new ProgressHelper(); + $progress->start($output = $this->getOutputStream(false)); + $progress->advance(); + + rewind($output->getStream()); + $this->assertEquals('', stream_get_contents($output->getStream())); + } + + protected function getOutputStream($decorated = true) + { + return new StreamOutput(fopen('php://memory', 'r+', false), StreamOutput::VERBOSITY_NORMAL, $decorated); + } + + protected $lastMessagesLength; + + protected function generateOutput($expected) + { + $expectedout = $expected; + + if ($this->lastMessagesLength !== null) { + $expectedout = str_pad($expected, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT); + } + + $this->lastMessagesLength = strlen($expectedout); + + return "\x0D".$expectedout; + } +} diff --git a/vendor/symfony/console/Tests/Helper/LegacyTableHelperTest.php b/vendor/symfony/console/Tests/Helper/LegacyTableHelperTest.php new file mode 100644 index 000000000..758701115 --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/LegacyTableHelperTest.php @@ -0,0 +1,317 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Helper\TableHelper; +use Symfony\Component\Console\Output\StreamOutput; + +/** + * @group legacy + */ +class LegacyTableHelperTest extends TestCase +{ + protected $stream; + + protected function setUp() + { + $this->stream = fopen('php://memory', 'r+'); + } + + protected function tearDown() + { + fclose($this->stream); + $this->stream = null; + } + + /** + * @dataProvider renderProvider + */ + public function testRender($headers, $rows, $layout, $expected) + { + $table = new TableHelper(); + $table + ->setHeaders($headers) + ->setRows($rows) + ->setLayout($layout) + ; + $table->render($output = $this->getOutputStream()); + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + /** + * @dataProvider renderProvider + */ + public function testRenderAddRows($headers, $rows, $layout, $expected) + { + $table = new TableHelper(); + $table + ->setHeaders($headers) + ->addRows($rows) + ->setLayout($layout) + ; + $table->render($output = $this->getOutputStream()); + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + /** + * @dataProvider renderProvider + */ + public function testRenderAddRowsOneByOne($headers, $rows, $layout, $expected) + { + $table = new TableHelper(); + $table + ->setHeaders($headers) + ->setLayout($layout) + ; + foreach ($rows as $row) { + $table->addRow($row); + } + $table->render($output = $this->getOutputStream()); + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + public function renderProvider() + { + $books = array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), + array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), + ); + + return array( + array( + array('ISBN', 'Title', 'Author'), + $books, + TableHelper::LAYOUT_DEFAULT, +<<<'TABLE' ++---------------+--------------------------+------------------+ +| ISBN | Title | Author | ++---------------+--------------------------+------------------+ +| 99921-58-10-7 | Divine Comedy | Dante Alighieri | +| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | +| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | +| 80-902734-1-6 | And Then There Were None | Agatha Christie | ++---------------+--------------------------+------------------+ + +TABLE + ), + array( + array('ISBN', 'Title', 'Author'), + $books, + TableHelper::LAYOUT_COMPACT, +<<<'TABLE' + ISBN Title Author + 99921-58-10-7 Divine Comedy Dante Alighieri + 9971-5-0210-0 A Tale of Two Cities Charles Dickens + 960-425-059-0 The Lord of the Rings J. R. R. Tolkien + 80-902734-1-6 And Then There Were None Agatha Christie + +TABLE + ), + array( + array('ISBN', 'Title', 'Author'), + $books, + TableHelper::LAYOUT_BORDERLESS, +<<<'TABLE' + =============== ========================== ================== + ISBN Title Author + =============== ========================== ================== + 99921-58-10-7 Divine Comedy Dante Alighieri + 9971-5-0210-0 A Tale of Two Cities Charles Dickens + 960-425-059-0 The Lord of the Rings J. R. R. Tolkien + 80-902734-1-6 And Then There Were None Agatha Christie + =============== ========================== ================== + +TABLE + ), + array( + array('ISBN', 'Title'), + array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0'), + array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), + array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), + ), + TableHelper::LAYOUT_DEFAULT, +<<<'TABLE' ++---------------+--------------------------+------------------+ +| ISBN | Title | | ++---------------+--------------------------+------------------+ +| 99921-58-10-7 | Divine Comedy | Dante Alighieri | +| 9971-5-0210-0 | | | +| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | +| 80-902734-1-6 | And Then There Were None | Agatha Christie | ++---------------+--------------------------+------------------+ + +TABLE + ), + array( + array(), + array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0'), + array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), + array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), + ), + TableHelper::LAYOUT_DEFAULT, +<<<'TABLE' ++---------------+--------------------------+------------------+ +| 99921-58-10-7 | Divine Comedy | Dante Alighieri | +| 9971-5-0210-0 | | | +| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | +| 80-902734-1-6 | And Then There Were None | Agatha Christie | ++---------------+--------------------------+------------------+ + +TABLE + ), + array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-7', "Divine\nComedy", 'Dante Alighieri'), + array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."), + array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."), + array('960-425-059-0', 'The Lord of the Rings', "J. R. R.\nTolkien"), + ), + TableHelper::LAYOUT_DEFAULT, +<<<'TABLE' ++---------------+----------------------------+-----------------+ +| ISBN | Title | Author | ++---------------+----------------------------+-----------------+ +| 99921-58-10-7 | Divine | Dante Alighieri | +| | Comedy | | +| 9971-5-0210-2 | Harry Potter | Rowling | +| | and the Chamber of Secrets | Joanne K. | +| 9971-5-0210-2 | Harry Potter | Rowling | +| | and the Chamber of Secrets | Joanne K. | +| 960-425-059-0 | The Lord of the Rings | J. R. R. | +| | | Tolkien | ++---------------+----------------------------+-----------------+ + +TABLE + ), + array( + array('ISBN', 'Title'), + array(), + TableHelper::LAYOUT_DEFAULT, +<<<'TABLE' ++------+-------+ +| ISBN | Title | ++------+-------+ + +TABLE + ), + array( + array(), + array(), + TableHelper::LAYOUT_DEFAULT, + '', + ), + 'Cell text with tags used for Output styling' => array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + ), + TableHelper::LAYOUT_DEFAULT, +<<<'TABLE' ++---------------+----------------------+-----------------+ +| ISBN | Title | Author | ++---------------+----------------------+-----------------+ +| 99921-58-10-7 | Divine Comedy | Dante Alighieri | +| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | ++---------------+----------------------+-----------------+ + +TABLE + ), + 'Cell text with tags not used for Output styling' => array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-700', 'Divine Com', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + ), + TableHelper::LAYOUT_DEFAULT, +<<<'TABLE' ++----------------------------------+----------------------+-----------------+ +| ISBN | Title | Author | ++----------------------------------+----------------------+-----------------+ +| 99921-58-10-700 | Divine Com | Dante Alighieri | +| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | ++----------------------------------+----------------------+-----------------+ + +TABLE + ), + ); + } + + public function testRenderMultiByte() + { + $table = new TableHelper(); + $table + ->setHeaders(array('■■')) + ->setRows(array(array(1234))) + ->setLayout(TableHelper::LAYOUT_DEFAULT) + ; + $table->render($output = $this->getOutputStream()); + + $expected = +<<<'TABLE' ++------+ +| ■■ | ++------+ +| 1234 | ++------+ + +TABLE; + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + public function testRenderFullWidthCharacters() + { + $table = new TableHelper(); + $table + ->setHeaders(array('あいうえお')) + ->setRows(array(array(1234567890))) + ->setLayout(TableHelper::LAYOUT_DEFAULT) + ; + $table->render($output = $this->getOutputStream()); + + $expected = + <<<'TABLE' ++------------+ +| あいうえお | ++------------+ +| 1234567890 | ++------------+ + +TABLE; + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + protected function getOutputStream() + { + return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false); + } + + protected function getOutputContent(StreamOutput $output) + { + rewind($output->getStream()); + + return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream())); + } +} diff --git a/vendor/symfony/console/Tests/Helper/ProcessHelperTest.php b/vendor/symfony/console/Tests/Helper/ProcessHelperTest.php new file mode 100644 index 000000000..8069bcccc --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/ProcessHelperTest.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Helper\DebugFormatterHelper; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Output\StreamOutput; +use Symfony\Component\Console\Helper\ProcessHelper; +use Symfony\Component\Process\Process; +use Symfony\Component\Process\ProcessBuilder; + +class ProcessHelperTest extends TestCase +{ + /** + * @dataProvider provideCommandsAndOutput + */ + public function testVariousProcessRuns($expected, $cmd, $verbosity, $error) + { + $helper = new ProcessHelper(); + $helper->setHelperSet(new HelperSet(array(new DebugFormatterHelper()))); + $output = $this->getOutputStream($verbosity); + $helper->run($output, $cmd, $error); + $this->assertEquals($expected, $this->getOutput($output)); + } + + public function testPassedCallbackIsExecuted() + { + $helper = new ProcessHelper(); + $helper->setHelperSet(new HelperSet(array(new DebugFormatterHelper()))); + $output = $this->getOutputStream(StreamOutput::VERBOSITY_NORMAL); + + $executed = false; + $callback = function () use (&$executed) { $executed = true; }; + + $helper->run($output, 'php -r "echo 42;"', null, $callback); + $this->assertTrue($executed); + } + + public function provideCommandsAndOutput() + { + $successOutputVerbose = <<<'EOT' + RUN php -r "echo 42;" + RES Command ran successfully + +EOT; + $successOutputDebug = <<<'EOT' + RUN php -r "echo 42;" + OUT 42 + RES Command ran successfully + +EOT; + $successOutputDebugWithTags = <<<'EOT' + RUN php -r "echo '42';" + OUT 42 + RES Command ran successfully + +EOT; + $successOutputProcessDebug = <<<'EOT' + RUN 'php' '-r' 'echo 42;' + OUT 42 + RES Command ran successfully + +EOT; + $syntaxErrorOutputVerbose = <<<'EOT' + RUN php -r "fwrite(STDERR, 'error message');usleep(50000);fwrite(STDOUT, 'out message');exit(252);" + RES 252 Command did not run successfully + +EOT; + $syntaxErrorOutputDebug = <<<'EOT' + RUN php -r "fwrite(STDERR, 'error message');usleep(500000);fwrite(STDOUT, 'out message');exit(252);" + ERR error message + OUT out message + RES 252 Command did not run successfully + +EOT; + + $errorMessage = 'An error occurred'; + $args = new ProcessBuilder(array('php', '-r', 'echo 42;')); + $args = $args->getProcess()->getCommandLine(); + $successOutputProcessDebug = str_replace("'php' '-r' 'echo 42;'", $args, $successOutputProcessDebug); + + return array( + array('', 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERBOSE, null), + array($successOutputVerbose, 'php -r "echo 42;"', StreamOutput::VERBOSITY_VERY_VERBOSE, null), + array($successOutputDebug, 'php -r "echo 42;"', StreamOutput::VERBOSITY_DEBUG, null), + array($successOutputDebugWithTags, 'php -r "echo \'42\';"', StreamOutput::VERBOSITY_DEBUG, null), + array('', 'php -r "syntax error"', StreamOutput::VERBOSITY_VERBOSE, null), + array($syntaxErrorOutputVerbose, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, null), + array($syntaxErrorOutputDebug, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, null), + array($errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERBOSE, $errorMessage), + array($syntaxErrorOutputVerbose.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(50000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_VERY_VERBOSE, $errorMessage), + array($syntaxErrorOutputDebug.$errorMessage.PHP_EOL, 'php -r "fwrite(STDERR, \'error message\');usleep(500000);fwrite(STDOUT, \'out message\');exit(252);"', StreamOutput::VERBOSITY_DEBUG, $errorMessage), + array($successOutputProcessDebug, array('php', '-r', 'echo 42;'), StreamOutput::VERBOSITY_DEBUG, null), + array($successOutputDebug, new Process('php -r "echo 42;"'), StreamOutput::VERBOSITY_DEBUG, null), + ); + } + + private function getOutputStream($verbosity) + { + return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, false); + } + + private function getOutput(StreamOutput $output) + { + rewind($output->getStream()); + + return stream_get_contents($output->getStream()); + } +} diff --git a/vendor/symfony/console/Tests/Helper/ProgressBarTest.php b/vendor/symfony/console/Tests/Helper/ProgressBarTest.php new file mode 100644 index 000000000..401033c9b --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/ProgressBarTest.php @@ -0,0 +1,662 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Helper\Helper; +use Symfony\Component\Console\Output\StreamOutput; + +/** + * @group time-sensitive + */ +class ProgressBarTest extends TestCase +{ + public function testMultipleStart() + { + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->start(); + $bar->advance(); + $bar->start(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0 [>---------------------------]'. + $this->generateOutput(' 1 [->--------------------------]'). + $this->generateOutput(' 0 [>---------------------------]'), + stream_get_contents($output->getStream()) + ); + } + + public function testAdvance() + { + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->start(); + $bar->advance(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0 [>---------------------------]'. + $this->generateOutput(' 1 [->--------------------------]'), + stream_get_contents($output->getStream()) + ); + } + + public function testAdvanceWithStep() + { + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->start(); + $bar->advance(5); + + rewind($output->getStream()); + $this->assertEquals( + ' 0 [>---------------------------]'. + $this->generateOutput(' 5 [----->----------------------]'), + stream_get_contents($output->getStream()) + ); + } + + public function testAdvanceMultipleTimes() + { + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->start(); + $bar->advance(3); + $bar->advance(2); + + rewind($output->getStream()); + $this->assertEquals( + ' 0 [>---------------------------]'. + $this->generateOutput(' 3 [--->------------------------]'). + $this->generateOutput(' 5 [----->----------------------]'), + stream_get_contents($output->getStream()) + ); + } + + public function testAdvanceOverMax() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 10); + $bar->setProgress(9); + $bar->advance(); + $bar->advance(); + + rewind($output->getStream()); + $this->assertEquals( + ' 9/10 [=========================>--] 90%'. + $this->generateOutput(' 10/10 [============================] 100%'). + $this->generateOutput(' 11/11 [============================] 100%'), + stream_get_contents($output->getStream()) + ); + } + + public function testFormat() + { + $expected = + ' 0/10 [>---------------------------] 0%'. + $this->generateOutput(' 10/10 [============================] 100%'). + $this->generateOutput(' 10/10 [============================] 100%') + ; + + // max in construct, no format + $bar = new ProgressBar($output = $this->getOutputStream(), 10); + $bar->start(); + $bar->advance(10); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals($expected, stream_get_contents($output->getStream())); + + // max in start, no format + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->start(10); + $bar->advance(10); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals($expected, stream_get_contents($output->getStream())); + + // max in construct, explicit format before + $bar = new ProgressBar($output = $this->getOutputStream(), 10); + $bar->setFormat('normal'); + $bar->start(); + $bar->advance(10); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals($expected, stream_get_contents($output->getStream())); + + // max in start, explicit format before + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->setFormat('normal'); + $bar->start(10); + $bar->advance(10); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals($expected, stream_get_contents($output->getStream())); + } + + public function testCustomizations() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 10); + $bar->setBarWidth(10); + $bar->setBarCharacter('_'); + $bar->setEmptyBarCharacter(' '); + $bar->setProgressCharacter('/'); + $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%'); + $bar->start(); + $bar->advance(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/10 [/ ] 0%'. + $this->generateOutput(' 1/10 [_/ ] 10%'), + stream_get_contents($output->getStream()) + ); + } + + public function testDisplayWithoutStart() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 50); + $bar->display(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/50 [>---------------------------] 0%', + stream_get_contents($output->getStream()) + ); + } + + public function testDisplayWithQuietVerbosity() + { + $bar = new ProgressBar($output = $this->getOutputStream(true, StreamOutput::VERBOSITY_QUIET), 50); + $bar->display(); + + rewind($output->getStream()); + $this->assertEquals( + '', + stream_get_contents($output->getStream()) + ); + } + + public function testFinishWithoutStart() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 50); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals( + ' 50/50 [============================] 100%', + stream_get_contents($output->getStream()) + ); + } + + public function testPercent() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 50); + $bar->start(); + $bar->display(); + $bar->advance(); + $bar->advance(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/50 [>---------------------------] 0%'. + $this->generateOutput(' 0/50 [>---------------------------] 0%'). + $this->generateOutput(' 1/50 [>---------------------------] 2%'). + $this->generateOutput(' 2/50 [=>--------------------------] 4%'), + stream_get_contents($output->getStream()) + ); + } + + public function testOverwriteWithShorterLine() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 50); + $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%%'); + $bar->start(); + $bar->display(); + $bar->advance(); + + // set shorter format + $bar->setFormat(' %current%/%max% [%bar%]'); + $bar->advance(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/50 [>---------------------------] 0%'. + $this->generateOutput(' 0/50 [>---------------------------] 0%'). + $this->generateOutput(' 1/50 [>---------------------------] 2%'). + $this->generateOutput(' 2/50 [=>--------------------------]'), + stream_get_contents($output->getStream()) + ); + } + + public function testStartWithMax() + { + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->setFormat('%current%/%max% [%bar%]'); + $bar->start(50); + $bar->advance(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/50 [>---------------------------]'. + $this->generateOutput(' 1/50 [>---------------------------]'), + stream_get_contents($output->getStream()) + ); + } + + public function testSetCurrentProgress() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 50); + $bar->start(); + $bar->display(); + $bar->advance(); + $bar->setProgress(15); + $bar->setProgress(25); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/50 [>---------------------------] 0%'. + $this->generateOutput(' 0/50 [>---------------------------] 0%'). + $this->generateOutput(' 1/50 [>---------------------------] 2%'). + $this->generateOutput(' 15/50 [========>-------------------] 30%'). + $this->generateOutput(' 25/50 [==============>-------------] 50%'), + stream_get_contents($output->getStream()) + ); + } + + public function testSetCurrentBeforeStarting() + { + $bar = new ProgressBar($this->getOutputStream()); + $bar->setProgress(15); + $this->assertNotNull($bar->getStartTime()); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage You can't regress the progress bar + */ + public function testRegressProgress() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 50); + $bar->start(); + $bar->setProgress(15); + $bar->setProgress(10); + } + + public function testRedrawFrequency() + { + $bar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar')->setMethods(array('display'))->setConstructorArgs(array($this->getOutputStream(), 6))->getMock(); + $bar->expects($this->exactly(4))->method('display'); + + $bar->setRedrawFrequency(2); + $bar->start(); + $bar->setProgress(1); + $bar->advance(2); + $bar->advance(2); + $bar->advance(1); + } + + public function testRedrawFrequencyIsAtLeastOneIfZeroGiven() + { + $bar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar')->setMethods(array('display'))->setConstructorArgs(array($this->getOutputStream()))->getMock(); + + $bar->expects($this->exactly(2))->method('display'); + $bar->setRedrawFrequency(0); + $bar->start(); + $bar->advance(); + } + + public function testRedrawFrequencyIsAtLeastOneIfSmallerOneGiven() + { + $bar = $this->getMockBuilder('Symfony\Component\Console\Helper\ProgressBar')->setMethods(array('display'))->setConstructorArgs(array($this->getOutputStream()))->getMock(); + + $bar->expects($this->exactly(2))->method('display'); + $bar->setRedrawFrequency(0.9); + $bar->start(); + $bar->advance(); + } + + public function testMultiByteSupport() + { + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->start(); + $bar->setBarCharacter('■'); + $bar->advance(3); + + rewind($output->getStream()); + $this->assertEquals( + ' 0 [>---------------------------]'. + $this->generateOutput(' 3 [■■■>------------------------]'), + stream_get_contents($output->getStream()) + ); + } + + public function testClear() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 50); + $bar->start(); + $bar->setProgress(25); + $bar->clear(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/50 [>---------------------------] 0%'. + $this->generateOutput(' 25/50 [==============>-------------] 50%'). + $this->generateOutput(''), + stream_get_contents($output->getStream()) + ); + } + + public function testPercentNotHundredBeforeComplete() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 200); + $bar->start(); + $bar->display(); + $bar->advance(199); + $bar->advance(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/200 [>---------------------------] 0%'. + $this->generateOutput(' 0/200 [>---------------------------] 0%'). + $this->generateOutput(' 199/200 [===========================>] 99%'). + $this->generateOutput(' 200/200 [============================] 100%'), + stream_get_contents($output->getStream()) + ); + } + + public function testNonDecoratedOutput() + { + $bar = new ProgressBar($output = $this->getOutputStream(false), 200); + $bar->start(); + + for ($i = 0; $i < 200; ++$i) { + $bar->advance(); + } + + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/200 [>---------------------------] 0%'.PHP_EOL. + ' 20/200 [==>-------------------------] 10%'.PHP_EOL. + ' 40/200 [=====>----------------------] 20%'.PHP_EOL. + ' 60/200 [========>-------------------] 30%'.PHP_EOL. + ' 80/200 [===========>----------------] 40%'.PHP_EOL. + ' 100/200 [==============>-------------] 50%'.PHP_EOL. + ' 120/200 [================>-----------] 60%'.PHP_EOL. + ' 140/200 [===================>--------] 70%'.PHP_EOL. + ' 160/200 [======================>-----] 80%'.PHP_EOL. + ' 180/200 [=========================>--] 90%'.PHP_EOL. + ' 200/200 [============================] 100%', + stream_get_contents($output->getStream()) + ); + } + + public function testNonDecoratedOutputWithClear() + { + $bar = new ProgressBar($output = $this->getOutputStream(false), 50); + $bar->start(); + $bar->setProgress(25); + $bar->clear(); + $bar->setProgress(50); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/50 [>---------------------------] 0%'.PHP_EOL. + ' 25/50 [==============>-------------] 50%'.PHP_EOL. + ' 50/50 [============================] 100%', + stream_get_contents($output->getStream()) + ); + } + + public function testNonDecoratedOutputWithoutMax() + { + $bar = new ProgressBar($output = $this->getOutputStream(false)); + $bar->start(); + $bar->advance(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0 [>---------------------------]'.PHP_EOL. + ' 1 [->--------------------------]', + stream_get_contents($output->getStream()) + ); + } + + public function testParallelBars() + { + $output = $this->getOutputStream(); + $bar1 = new ProgressBar($output, 2); + $bar2 = new ProgressBar($output, 3); + $bar2->setProgressCharacter('#'); + $bar3 = new ProgressBar($output); + + $bar1->start(); + $output->write("\n"); + $bar2->start(); + $output->write("\n"); + $bar3->start(); + + for ($i = 1; $i <= 3; ++$i) { + // up two lines + $output->write("\033[2A"); + if ($i <= 2) { + $bar1->advance(); + } + $output->write("\n"); + $bar2->advance(); + $output->write("\n"); + $bar3->advance(); + } + $output->write("\033[2A"); + $output->write("\n"); + $output->write("\n"); + $bar3->finish(); + + rewind($output->getStream()); + $this->assertEquals( + ' 0/2 [>---------------------------] 0%'."\n". + ' 0/3 [#---------------------------] 0%'."\n". + rtrim(' 0 [>---------------------------]'). + + "\033[2A". + $this->generateOutput(' 1/2 [==============>-------------] 50%')."\n". + $this->generateOutput(' 1/3 [=========#------------------] 33%')."\n". + rtrim($this->generateOutput(' 1 [->--------------------------]')). + + "\033[2A". + $this->generateOutput(' 2/2 [============================] 100%')."\n". + $this->generateOutput(' 2/3 [==================#---------] 66%')."\n". + rtrim($this->generateOutput(' 2 [-->-------------------------]')). + + "\033[2A". + "\n". + $this->generateOutput(' 3/3 [============================] 100%')."\n". + rtrim($this->generateOutput(' 3 [--->------------------------]')). + + "\033[2A". + "\n". + "\n". + rtrim($this->generateOutput(' 3 [============================]')), + stream_get_contents($output->getStream()) + ); + } + + public function testWithoutMax() + { + $output = $this->getOutputStream(); + + $bar = new ProgressBar($output); + $bar->start(); + $bar->advance(); + $bar->advance(); + $bar->advance(); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals( + rtrim(' 0 [>---------------------------]'). + rtrim($this->generateOutput(' 1 [->--------------------------]')). + rtrim($this->generateOutput(' 2 [-->-------------------------]')). + rtrim($this->generateOutput(' 3 [--->------------------------]')). + rtrim($this->generateOutput(' 3 [============================]')), + stream_get_contents($output->getStream()) + ); + } + + public function testAddingPlaceholderFormatter() + { + ProgressBar::setPlaceholderFormatterDefinition('remaining_steps', function (ProgressBar $bar) { + return $bar->getMaxSteps() - $bar->getProgress(); + }); + $bar = new ProgressBar($output = $this->getOutputStream(), 3); + $bar->setFormat(' %remaining_steps% [%bar%]'); + + $bar->start(); + $bar->advance(); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals( + ' 3 [>---------------------------]'. + $this->generateOutput(' 2 [=========>------------------]'). + $this->generateOutput(' 0 [============================]'), + stream_get_contents($output->getStream()) + ); + } + + public function testMultilineFormat() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 3); + $bar->setFormat("%bar%\nfoobar"); + + $bar->start(); + $bar->advance(); + $bar->clear(); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals( + ">---------------------------\nfoobar". + $this->generateOutput("=========>------------------\nfoobar"). + "\x0D\x1B[2K\x1B[1A\x1B[2K". + $this->generateOutput("============================\nfoobar"), + stream_get_contents($output->getStream()) + ); + } + + public function testAnsiColorsAndEmojis() + { + $bar = new ProgressBar($output = $this->getOutputStream(), 15); + ProgressBar::setPlaceholderFormatterDefinition('memory', function (ProgressBar $bar) { + static $i = 0; + $mem = 100000 * $i; + $colors = $i++ ? '41;37' : '44;37'; + + return "\033[".$colors.'m '.Helper::formatMemory($mem)." \033[0m"; + }); + $bar->setFormat(" \033[44;37m %title:-37s% \033[0m\n %current%/%max% %bar% %percent:3s%%\n 🏁 %remaining:-10s% %memory:37s%"); + $bar->setBarCharacter($done = "\033[32m●\033[0m"); + $bar->setEmptyBarCharacter($empty = "\033[31m●\033[0m"); + $bar->setProgressCharacter($progress = "\033[32m➤ \033[0m"); + + $bar->setMessage('Starting the demo... fingers crossed', 'title'); + $bar->start(); + $bar->setMessage('Looks good to me...', 'title'); + $bar->advance(4); + $bar->setMessage('Thanks, bye', 'title'); + $bar->finish(); + + rewind($output->getStream()); + $this->assertEquals( + " \033[44;37m Starting the demo... fingers crossed \033[0m\n". + ' 0/15 '.$progress.str_repeat($empty, 26)." 0%\n". + " \xf0\x9f\x8f\x81 < 1 sec \033[44;37m 0 B \033[0m" + . + $this->generateOutput( + " \033[44;37m Looks good to me... \033[0m\n". + ' 4/15 '.str_repeat($done, 7).$progress.str_repeat($empty, 19)." 26%\n". + " \xf0\x9f\x8f\x81 < 1 sec \033[41;37m 97 KiB \033[0m" + ). + $this->generateOutput( + " \033[44;37m Thanks, bye \033[0m\n". + ' 15/15 '.str_repeat($done, 28)." 100%\n". + " \xf0\x9f\x8f\x81 < 1 sec \033[41;37m 195 KiB \033[0m" + ), + stream_get_contents($output->getStream()) + ); + } + + public function testSetFormat() + { + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->setFormat('normal'); + $bar->start(); + rewind($output->getStream()); + $this->assertEquals( + ' 0 [>---------------------------]', + stream_get_contents($output->getStream()) + ); + + $bar = new ProgressBar($output = $this->getOutputStream(), 10); + $bar->setFormat('normal'); + $bar->start(); + rewind($output->getStream()); + $this->assertEquals( + ' 0/10 [>---------------------------] 0%', + stream_get_contents($output->getStream()) + ); + } + + /** + * @dataProvider provideFormat + */ + public function testFormatsWithoutMax($format) + { + $bar = new ProgressBar($output = $this->getOutputStream()); + $bar->setFormat($format); + $bar->start(); + + rewind($output->getStream()); + $this->assertNotEmpty(stream_get_contents($output->getStream())); + } + + /** + * Provides each defined format. + * + * @return array + */ + public function provideFormat() + { + return array( + array('normal'), + array('verbose'), + array('very_verbose'), + array('debug'), + ); + } + + protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL) + { + return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated); + } + + protected function generateOutput($expected) + { + $count = substr_count($expected, "\n"); + + return "\x0D\x1B[2K".($count ? str_repeat("\x1B[1A\x1B[2K", $count) : '').$expected; + } +} diff --git a/vendor/symfony/console/Tests/Helper/ProgressIndicatorTest.php b/vendor/symfony/console/Tests/Helper/ProgressIndicatorTest.php new file mode 100644 index 000000000..c85018dec --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/ProgressIndicatorTest.php @@ -0,0 +1,183 @@ +getOutputStream()); + $bar->start('Starting...'); + usleep(101000); + $bar->advance(); + usleep(101000); + $bar->advance(); + usleep(101000); + $bar->advance(); + usleep(101000); + $bar->advance(); + usleep(101000); + $bar->advance(); + usleep(101000); + $bar->setMessage('Advancing...'); + $bar->advance(); + $bar->finish('Done...'); + $bar->start('Starting Again...'); + usleep(101000); + $bar->advance(); + $bar->finish('Done Again...'); + + rewind($output->getStream()); + + $this->assertEquals( + $this->generateOutput(' - Starting...'). + $this->generateOutput(' \\ Starting...'). + $this->generateOutput(' | Starting...'). + $this->generateOutput(' / Starting...'). + $this->generateOutput(' - Starting...'). + $this->generateOutput(' \\ Starting...'). + $this->generateOutput(' \\ Advancing...'). + $this->generateOutput(' | Advancing...'). + $this->generateOutput(' | Done...'). + PHP_EOL. + $this->generateOutput(' - Starting Again...'). + $this->generateOutput(' \\ Starting Again...'). + $this->generateOutput(' \\ Done Again...'). + PHP_EOL, + stream_get_contents($output->getStream()) + ); + } + + public function testNonDecoratedOutput() + { + $bar = new ProgressIndicator($output = $this->getOutputStream(false)); + + $bar->start('Starting...'); + $bar->advance(); + $bar->advance(); + $bar->setMessage('Midway...'); + $bar->advance(); + $bar->advance(); + $bar->finish('Done...'); + + rewind($output->getStream()); + + $this->assertEquals( + ' Starting...'.PHP_EOL. + ' Midway...'.PHP_EOL. + ' Done...'.PHP_EOL.PHP_EOL, + stream_get_contents($output->getStream()) + ); + } + + public function testCustomIndicatorValues() + { + $bar = new ProgressIndicator($output = $this->getOutputStream(), null, 100, array('a', 'b', 'c')); + + $bar->start('Starting...'); + usleep(101000); + $bar->advance(); + usleep(101000); + $bar->advance(); + usleep(101000); + $bar->advance(); + + rewind($output->getStream()); + + $this->assertEquals( + $this->generateOutput(' a Starting...'). + $this->generateOutput(' b Starting...'). + $this->generateOutput(' c Starting...'). + $this->generateOutput(' a Starting...'), + stream_get_contents($output->getStream()) + ); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Must have at least 2 indicator value characters. + */ + public function testCannotSetInvalidIndicatorCharacters() + { + $bar = new ProgressIndicator($this->getOutputStream(), null, 100, array('1')); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Progress indicator already started. + */ + public function testCannotStartAlreadyStartedIndicator() + { + $bar = new ProgressIndicator($this->getOutputStream()); + $bar->start('Starting...'); + $bar->start('Starting Again.'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Progress indicator has not yet been started. + */ + public function testCannotAdvanceUnstartedIndicator() + { + $bar = new ProgressIndicator($this->getOutputStream()); + $bar->advance(); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Progress indicator has not yet been started. + */ + public function testCannotFinishUnstartedIndicator() + { + $bar = new ProgressIndicator($this->getOutputStream()); + $bar->finish('Finished'); + } + + /** + * @dataProvider provideFormat + */ + public function testFormats($format) + { + $bar = new ProgressIndicator($output = $this->getOutputStream(), $format); + $bar->start('Starting...'); + $bar->advance(); + + rewind($output->getStream()); + + $this->assertNotEmpty(stream_get_contents($output->getStream())); + } + + /** + * Provides each defined format. + * + * @return array + */ + public function provideFormat() + { + return array( + array('normal'), + array('verbose'), + array('very_verbose'), + array('debug'), + ); + } + + protected function getOutputStream($decorated = true, $verbosity = StreamOutput::VERBOSITY_NORMAL) + { + return new StreamOutput(fopen('php://memory', 'r+', false), $verbosity, $decorated); + } + + protected function generateOutput($expected) + { + $count = substr_count($expected, "\n"); + + return "\x0D\x1B[2K".($count ? sprintf("\033[%dA", $count) : '').$expected; + } +} diff --git a/vendor/symfony/console/Tests/Helper/QuestionHelperTest.php b/vendor/symfony/console/Tests/Helper/QuestionHelperTest.php new file mode 100644 index 000000000..7d4502523 --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/QuestionHelperTest.php @@ -0,0 +1,507 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Helper\QuestionHelper; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Output\StreamOutput; +use Symfony\Component\Console\Question\ChoiceQuestion; +use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Question\Question; + +/** + * @group tty + */ +class QuestionHelperTest extends TestCase +{ + public function testAskChoice() + { + $questionHelper = new QuestionHelper(); + + $helperSet = new HelperSet(array(new FormatterHelper())); + $questionHelper->setHelperSet($helperSet); + + $heroes = array('Superman', 'Batman', 'Spiderman'); + + $questionHelper->setInputStream($this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n")); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2'); + $question->setMaxAttempts(1); + // first answer is an empty answer, we're supposed to receive the default value + $this->assertEquals('Spiderman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes); + $question->setMaxAttempts(1); + $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes); + $question->setErrorMessage('Input "%s" is not a superhero!'); + $question->setMaxAttempts(2); + $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question)); + + rewind($output->getStream()); + $stream = stream_get_contents($output->getStream()); + $this->assertContains('Input "Fabien" is not a superhero!', $stream); + + try { + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1'); + $question->setMaxAttempts(1); + $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('Value "Fabien" is invalid', $e->getMessage()); + } + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null); + $question->setMaxAttempts(1); + $question->setMultiselect(true); + + $this->assertEquals(array('Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1'); + $question->setMaxAttempts(1); + $question->setMultiselect(true); + + $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 '); + $question->setMaxAttempts(1); + $question->setMultiselect(true); + + $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + } + + public function testAsk() + { + $dialog = new QuestionHelper(); + + $dialog->setInputStream($this->getInputStream("\n8AM\n")); + + $question = new Question('What time is it?', '2PM'); + $this->assertEquals('2PM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + + $question = new Question('What time is it?', '2PM'); + $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question)); + + rewind($output->getStream()); + $this->assertEquals('What time is it?', stream_get_contents($output->getStream())); + } + + public function testAskWithAutocomplete() + { + if (!$this->hasSttyAvailable()) { + $this->markTestSkipped('`stty` is required to test autocomplete functionality'); + } + + // Acm + // AcsTest + // + // + // Test + // + // S + // F00oo + $inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n"); + + $dialog = new QuestionHelper(); + $dialog->setInputStream($inputStream); + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $question = new Question('Please select a bundle', 'FrameworkBundle'); + $question->setAutocompleterValues(array('AcmeDemoBundle', 'AsseticBundle', 'SecurityBundle', 'FooBundle')); + + $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('AsseticBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('FrameworkBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('SecurityBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('FooBundleTest', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('FooBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + } + + public function testAskWithAutocompleteWithNonSequentialKeys() + { + if (!$this->hasSttyAvailable()) { + $this->markTestSkipped('`stty` is required to test autocomplete functionality'); + } + + // + $inputStream = $this->getInputStream("\033[A\033[A\n\033[B\033[B\n"); + + $dialog = new QuestionHelper(); + $dialog->setInputStream($inputStream); + $dialog->setHelperSet(new HelperSet(array(new FormatterHelper()))); + + $question = new ChoiceQuestion('Please select a bundle', array(1 => 'AcmeDemoBundle', 4 => 'AsseticBundle')); + $question->setMaxAttempts(1); + + $this->assertEquals('AcmeDemoBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('AsseticBundle', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + } + + public function testAskHiddenResponse() + { + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test is not supported on Windows'); + } + + $dialog = new QuestionHelper(); + $dialog->setInputStream($this->getInputStream("8AM\n")); + + $question = new Question('What time is it?'); + $question->setHidden(true); + + $this->assertEquals('8AM', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + } + + /** + * @dataProvider getAskConfirmationData + */ + public function testAskConfirmation($question, $expected, $default = true) + { + $dialog = new QuestionHelper(); + + $dialog->setInputStream($this->getInputStream($question."\n")); + $question = new ConfirmationQuestion('Do you like French fries?', $default); + $this->assertEquals($expected, $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question), 'confirmation question should '.($expected ? 'pass' : 'cancel')); + } + + public function getAskConfirmationData() + { + return array( + array('', true), + array('', false, false), + array('y', true), + array('yes', true), + array('n', false), + array('no', false), + ); + } + + public function testAskConfirmationWithCustomTrueAnswer() + { + $dialog = new QuestionHelper(); + + $dialog->setInputStream($this->getInputStream("j\ny\n")); + $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i'); + $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $question = new ConfirmationQuestion('Do you like French fries?', false, '/^(j|y)/i'); + $this->assertTrue($dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + } + + public function testAskAndValidate() + { + $dialog = new QuestionHelper(); + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $error = 'This is not a color!'; + $validator = function ($color) use ($error) { + if (!in_array($color, array('white', 'black'))) { + throw new \InvalidArgumentException($error); + } + + return $color; + }; + + $question = new Question('What color was the white horse of Henry IV?', 'white'); + $question->setValidator($validator); + $question->setMaxAttempts(2); + + $dialog->setInputStream($this->getInputStream("\nblack\n")); + $this->assertEquals('white', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('black', $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + + $dialog->setInputStream($this->getInputStream("green\nyellow\norange\n")); + try { + $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertEquals($error, $e->getMessage()); + } + } + + /** + * @dataProvider simpleAnswerProvider + */ + public function testSelectChoiceFromSimpleChoices($providedAnswer, $expectedValue) + { + $possibleChoices = array( + 'My environment 1', + 'My environment 2', + 'My environment 3', + ); + + $dialog = new QuestionHelper(); + $dialog->setInputStream($this->getInputStream($providedAnswer."\n")); + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices); + $question->setMaxAttempts(1); + $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question); + + $this->assertSame($expectedValue, $answer); + } + + public function simpleAnswerProvider() + { + return array( + array(0, 'My environment 1'), + array(1, 'My environment 2'), + array(2, 'My environment 3'), + array('My environment 1', 'My environment 1'), + array('My environment 2', 'My environment 2'), + array('My environment 3', 'My environment 3'), + ); + } + + /** + * @dataProvider specialCharacterInMultipleChoice + */ + public function testSpecialCharacterChoiceFromMultipleChoiceList($providedAnswer, $expectedValue) + { + $possibleChoices = array( + '.', + 'src', + ); + + $dialog = new QuestionHelper(); + $dialog->setInputStream($this->getInputStream($providedAnswer."\n")); + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $question = new ChoiceQuestion('Please select the directory', $possibleChoices); + $question->setMaxAttempts(1); + $question->setMultiselect(true); + $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question); + + $this->assertSame($expectedValue, $answer); + } + + public function specialCharacterInMultipleChoice() + { + return array( + array('.', array('.')), + array('., src', array('.', 'src')), + ); + } + + /** + * @dataProvider mixedKeysChoiceListAnswerProvider + */ + public function testChoiceFromChoicelistWithMixedKeys($providedAnswer, $expectedValue) + { + $possibleChoices = array( + '0' => 'No environment', + '1' => 'My environment 1', + 'env_2' => 'My environment 2', + 3 => 'My environment 3', + ); + + $dialog = new QuestionHelper(); + $dialog->setInputStream($this->getInputStream($providedAnswer."\n")); + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices); + $question->setMaxAttempts(1); + $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question); + + $this->assertSame($expectedValue, $answer); + } + + public function mixedKeysChoiceListAnswerProvider() + { + return array( + array('0', '0'), + array('No environment', '0'), + array('1', '1'), + array('env_2', 'env_2'), + array(3, '3'), + array('My environment 1', '1'), + ); + } + + /** + * @dataProvider answerProvider + */ + public function testSelectChoiceFromChoiceList($providedAnswer, $expectedValue) + { + $possibleChoices = array( + 'env_1' => 'My environment 1', + 'env_2' => 'My environment', + 'env_3' => 'My environment', + ); + + $dialog = new QuestionHelper(); + $dialog->setInputStream($this->getInputStream($providedAnswer."\n")); + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices); + $question->setMaxAttempts(1); + $answer = $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question); + + $this->assertSame($expectedValue, $answer); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The provided answer is ambiguous. Value should be one of env_2 or env_3. + */ + public function testAmbiguousChoiceFromChoicelist() + { + $possibleChoices = array( + 'env_1' => 'My first environment', + 'env_2' => 'My environment', + 'env_3' => 'My environment', + ); + + $dialog = new QuestionHelper(); + $dialog->setInputStream($this->getInputStream("My environment\n")); + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices); + $question->setMaxAttempts(1); + + $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question); + } + + public function answerProvider() + { + return array( + array('env_1', 'env_1'), + array('env_2', 'env_2'), + array('env_3', 'env_3'), + array('My environment 1', 'env_1'), + ); + } + + public function testNoInteraction() + { + $dialog = new QuestionHelper(); + $question = new Question('Do you have a job?', 'not yet'); + $this->assertEquals('not yet', $dialog->ask($this->createInputInterfaceMock(false), $this->createOutputInterface(), $question)); + } + + /** + * @requires function mb_strwidth + */ + public function testChoiceOutputFormattingQuestionForUtf8Keys() + { + $question = 'Lorem ipsum?'; + $possibleChoices = array( + 'foo' => 'foo', + 'żółw' => 'bar', + 'łabądź' => 'baz', + ); + $outputShown = array( + $question, + ' [foo ] foo', + ' [żółw ] bar', + ' [łabądź] baz', + ); + $output = $this->getMockBuilder('\Symfony\Component\Console\Output\OutputInterface')->getMock(); + $output->method('getFormatter')->willReturn(new OutputFormatter()); + + $dialog = new QuestionHelper(); + $dialog->setInputStream($this->getInputStream("\n")); + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $output->expects($this->once())->method('writeln')->with($this->equalTo($outputShown)); + + $question = new ChoiceQuestion($question, $possibleChoices, 'foo'); + $dialog->ask($this->createInputInterfaceMock(), $output, $question); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\RuntimeException + * @expectedExceptionMessage Aborted + */ + public function testAskThrowsExceptionOnMissingInput() + { + $dialog = new QuestionHelper(); + $dialog->setInputStream($this->getInputStream('')); + + $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), new Question('What\'s your name?')); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\RuntimeException + * @expectedExceptionMessage Aborted + */ + public function testAskThrowsExceptionOnMissingInputWithValidator() + { + $dialog = new QuestionHelper(); + $dialog->setInputStream($this->getInputStream('')); + + $question = new Question('What\'s your name?'); + $question->setValidator(function () { + if (!$value) { + throw new \Exception('A value is required.'); + } + }); + + $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Choice question must have at least 1 choice available. + */ + public function testEmptyChoices() + { + new ChoiceQuestion('Question', array(), 'irrelevant'); + } + + protected function getInputStream($input) + { + $stream = fopen('php://memory', 'r+', false); + fwrite($stream, $input); + rewind($stream); + + return $stream; + } + + protected function createOutputInterface() + { + return new StreamOutput(fopen('php://memory', 'r+', false)); + } + + protected function createInputInterfaceMock($interactive = true) + { + $mock = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface')->getMock(); + $mock->expects($this->any()) + ->method('isInteractive') + ->will($this->returnValue($interactive)); + + return $mock; + } + + private function hasSttyAvailable() + { + exec('stty 2>&1', $output, $exitcode); + + return $exitcode === 0; + } +} diff --git a/vendor/symfony/console/Tests/Helper/SymfonyQuestionHelperTest.php b/vendor/symfony/console/Tests/Helper/SymfonyQuestionHelperTest.php new file mode 100644 index 000000000..1a2d1b843 --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/SymfonyQuestionHelperTest.php @@ -0,0 +1,159 @@ +setHelperSet($helperSet); + + $heroes = array('Superman', 'Batman', 'Spiderman'); + + $questionHelper->setInputStream($this->getInputStream("\n1\n 1 \nFabien\n1\nFabien\n1\n0,2\n 0 , 2 \n\n\n")); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '2'); + $question->setMaxAttempts(1); + // first answer is an empty answer, we're supposed to receive the default value + $this->assertEquals('Spiderman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question)); + $this->assertOutputContains('What is your favorite superhero? [Spiderman]', $output); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes); + $question->setMaxAttempts(1); + $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes); + $question->setErrorMessage('Input "%s" is not a superhero!'); + $question->setMaxAttempts(2); + $this->assertEquals('Batman', $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question)); + $this->assertOutputContains('Input "Fabien" is not a superhero!', $output); + + try { + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '1'); + $question->setMaxAttempts(1); + $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('Value "Fabien" is invalid', $e->getMessage()); + } + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, null); + $question->setMaxAttempts(1); + $question->setMultiselect(true); + + $this->assertEquals(array('Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + $this->assertEquals(array('Superman', 'Spiderman'), $questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, '0,1'); + $question->setMaxAttempts(1); + $question->setMultiselect(true); + + $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question)); + $this->assertOutputContains('What is your favorite superhero? [Superman, Batman]', $output); + + $question = new ChoiceQuestion('What is your favorite superhero?', $heroes, ' 0 , 1 '); + $question->setMaxAttempts(1); + $question->setMultiselect(true); + + $this->assertEquals(array('Superman', 'Batman'), $questionHelper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), $question)); + $this->assertOutputContains('What is your favorite superhero? [Superman, Batman]', $output); + } + + public function testAskReturnsNullIfValidatorAllowsIt() + { + $questionHelper = new SymfonyQuestionHelper(); + $questionHelper->setInputStream($this->getInputStream("\n")); + $question = new Question('What is your favorite superhero?'); + $question->setValidator(function ($value) { return $value; }); + $this->assertNull($questionHelper->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), $question)); + } + + public function testAskEscapeDefaultValue() + { + $helper = new SymfonyQuestionHelper(); + $helper->setInputStream($this->getInputStream('\\')); + $helper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), new Question('Can I have a backslash?', '\\')); + + $this->assertOutputContains('Can I have a backslash? [\]', $output); + } + + public function testAskEscapeAndFormatLabel() + { + $helper = new SymfonyQuestionHelper(); + $helper->setInputStream($this->getInputStream('Foo\\Bar')); + $helper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), new Question('Do you want to use Foo\\Bar or Foo\\Baz\\?', 'Foo\\Baz')); + + $this->assertOutputContains('Do you want to use Foo\\Bar or Foo\\Baz\\? [Foo\\Baz]:', $output); + } + + public function testLabelTrailingBackslash() + { + $helper = new SymfonyQuestionHelper(); + $helper->setInputStream($this->getInputStream('sure')); + $helper->ask($this->createInputInterfaceMock(), $output = $this->createOutputInterface(), new Question('Question with a trailing \\')); + + $this->assertOutputContains('Question with a trailing \\', $output); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\RuntimeException + * @expectedExceptionMessage Aborted + */ + public function testAskThrowsExceptionOnMissingInput() + { + $dialog = new SymfonyQuestionHelper(); + + $dialog->setInputStream($this->getInputStream('')); + $dialog->ask($this->createInputInterfaceMock(), $this->createOutputInterface(), new Question('What\'s your name?')); + } + + protected function getInputStream($input) + { + $stream = fopen('php://memory', 'r+', false); + fwrite($stream, $input); + rewind($stream); + + return $stream; + } + + protected function createOutputInterface() + { + $output = new StreamOutput(fopen('php://memory', 'r+', false)); + $output->setDecorated(false); + + return $output; + } + + protected function createInputInterfaceMock($interactive = true) + { + $mock = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface')->getMock(); + $mock->expects($this->any()) + ->method('isInteractive') + ->will($this->returnValue($interactive)); + + return $mock; + } + + private function assertOutputContains($expected, StreamOutput $output) + { + rewind($output->getStream()); + $stream = stream_get_contents($output->getStream()); + $this->assertContains($expected, $stream); + } +} diff --git a/vendor/symfony/console/Tests/Helper/TableStyleTest.php b/vendor/symfony/console/Tests/Helper/TableStyleTest.php new file mode 100644 index 000000000..13e918b3a --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/TableStyleTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Helper\TableStyle; + +class TableStyleTest extends TestCase +{ + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH). + */ + public function testSetPadTypeWithInvalidType() + { + $style = new TableStyle(); + $style->setPadType('TEST'); + } +} diff --git a/vendor/symfony/console/Tests/Helper/TableTest.php b/vendor/symfony/console/Tests/Helper/TableTest.php new file mode 100644 index 000000000..01c30fb0f --- /dev/null +++ b/vendor/symfony/console/Tests/Helper/TableTest.php @@ -0,0 +1,759 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Helper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Helper\Table; +use Symfony\Component\Console\Helper\TableStyle; +use Symfony\Component\Console\Helper\TableSeparator; +use Symfony\Component\Console\Helper\TableCell; +use Symfony\Component\Console\Output\StreamOutput; + +class TableTest extends TestCase +{ + protected $stream; + + protected function setUp() + { + $this->stream = fopen('php://memory', 'r+'); + } + + protected function tearDown() + { + fclose($this->stream); + $this->stream = null; + } + + /** + * @dataProvider renderProvider + */ + public function testRender($headers, $rows, $style, $expected, $decorated = false) + { + $table = new Table($output = $this->getOutputStream($decorated)); + $table + ->setHeaders($headers) + ->setRows($rows) + ->setStyle($style) + ; + $table->render(); + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + /** + * @dataProvider renderProvider + */ + public function testRenderAddRows($headers, $rows, $style, $expected, $decorated = false) + { + $table = new Table($output = $this->getOutputStream($decorated)); + $table + ->setHeaders($headers) + ->addRows($rows) + ->setStyle($style) + ; + $table->render(); + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + /** + * @dataProvider renderProvider + */ + public function testRenderAddRowsOneByOne($headers, $rows, $style, $expected, $decorated = false) + { + $table = new Table($output = $this->getOutputStream($decorated)); + $table + ->setHeaders($headers) + ->setStyle($style) + ; + foreach ($rows as $row) { + $table->addRow($row); + } + $table->render(); + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + public function renderProvider() + { + $books = array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), + array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), + ); + + return array( + array( + array('ISBN', 'Title', 'Author'), + $books, + 'default', +<<<'TABLE' ++---------------+--------------------------+------------------+ +| ISBN | Title | Author | ++---------------+--------------------------+------------------+ +| 99921-58-10-7 | Divine Comedy | Dante Alighieri | +| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | +| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | +| 80-902734-1-6 | And Then There Were None | Agatha Christie | ++---------------+--------------------------+------------------+ + +TABLE + ), + array( + array('ISBN', 'Title', 'Author'), + $books, + 'compact', +<<<'TABLE' + ISBN Title Author + 99921-58-10-7 Divine Comedy Dante Alighieri + 9971-5-0210-0 A Tale of Two Cities Charles Dickens + 960-425-059-0 The Lord of the Rings J. R. R. Tolkien + 80-902734-1-6 And Then There Were None Agatha Christie + +TABLE + ), + array( + array('ISBN', 'Title', 'Author'), + $books, + 'borderless', +<<<'TABLE' + =============== ========================== ================== + ISBN Title Author + =============== ========================== ================== + 99921-58-10-7 Divine Comedy Dante Alighieri + 9971-5-0210-0 A Tale of Two Cities Charles Dickens + 960-425-059-0 The Lord of the Rings J. R. R. Tolkien + 80-902734-1-6 And Then There Were None Agatha Christie + =============== ========================== ================== + +TABLE + ), + array( + array('ISBN', 'Title'), + array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0'), + array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), + array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), + ), + 'default', +<<<'TABLE' ++---------------+--------------------------+------------------+ +| ISBN | Title | | ++---------------+--------------------------+------------------+ +| 99921-58-10-7 | Divine Comedy | Dante Alighieri | +| 9971-5-0210-0 | | | +| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | +| 80-902734-1-6 | And Then There Were None | Agatha Christie | ++---------------+--------------------------+------------------+ + +TABLE + ), + array( + array(), + array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0'), + array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'), + array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'), + ), + 'default', +<<<'TABLE' ++---------------+--------------------------+------------------+ +| 99921-58-10-7 | Divine Comedy | Dante Alighieri | +| 9971-5-0210-0 | | | +| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | +| 80-902734-1-6 | And Then There Were None | Agatha Christie | ++---------------+--------------------------+------------------+ + +TABLE + ), + array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-7', "Divine\nComedy", 'Dante Alighieri'), + array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."), + array('9971-5-0210-2', "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."), + array('960-425-059-0', 'The Lord of the Rings', "J. R. R.\nTolkien"), + ), + 'default', +<<<'TABLE' ++---------------+----------------------------+-----------------+ +| ISBN | Title | Author | ++---------------+----------------------------+-----------------+ +| 99921-58-10-7 | Divine | Dante Alighieri | +| | Comedy | | +| 9971-5-0210-2 | Harry Potter | Rowling | +| | and the Chamber of Secrets | Joanne K. | +| 9971-5-0210-2 | Harry Potter | Rowling | +| | and the Chamber of Secrets | Joanne K. | +| 960-425-059-0 | The Lord of the Rings | J. R. R. | +| | | Tolkien | ++---------------+----------------------------+-----------------+ + +TABLE + ), + array( + array('ISBN', 'Title'), + array(), + 'default', +<<<'TABLE' ++------+-------+ +| ISBN | Title | ++------+-------+ + +TABLE + ), + array( + array(), + array(), + 'default', + '', + ), + 'Cell text with tags used for Output styling' => array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + ), + 'default', +<<<'TABLE' ++---------------+----------------------+-----------------+ +| ISBN | Title | Author | ++---------------+----------------------+-----------------+ +| 99921-58-10-7 | Divine Comedy | Dante Alighieri | +| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | ++---------------+----------------------+-----------------+ + +TABLE + ), + 'Cell text with tags not used for Output styling' => array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-700', 'Divine Com', 'Dante Alighieri'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'), + ), + 'default', +<<<'TABLE' ++----------------------------------+----------------------+-----------------+ +| ISBN | Title | Author | ++----------------------------------+----------------------+-----------------+ +| 99921-58-10-700 | Divine Com | Dante Alighieri | +| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | ++----------------------------------+----------------------+-----------------+ + +TABLE + ), + 'Cell with colspan' => array( + array('ISBN', 'Title', 'Author'), + array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'), + new TableSeparator(), + array(new TableCell('Divine Comedy(Dante Alighieri)', array('colspan' => 3))), + new TableSeparator(), + array( + new TableCell('Arduino: A Quick-Start Guide', array('colspan' => 2)), + 'Mark Schmidt', + ), + new TableSeparator(), + array( + '9971-5-0210-0', + new TableCell("A Tale of \nTwo Cities", array('colspan' => 2)), + ), + new TableSeparator(), + array( + new TableCell('Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil!', array('colspan' => 3)), + ), + ), + 'default', +<<<'TABLE' ++-------------------------------+-------------------------------+-----------------------------+ +| ISBN | Title | Author | ++-------------------------------+-------------------------------+-----------------------------+ +| 99921-58-10-7 | Divine Comedy | Dante Alighieri | ++-------------------------------+-------------------------------+-----------------------------+ +| Divine Comedy(Dante Alighieri) | ++-------------------------------+-------------------------------+-----------------------------+ +| Arduino: A Quick-Start Guide | Mark Schmidt | ++-------------------------------+-------------------------------+-----------------------------+ +| 9971-5-0210-0 | A Tale of | +| | Two Cities | ++-------------------------------+-------------------------------+-----------------------------+ +| Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil! | ++-------------------------------+-------------------------------+-----------------------------+ + +TABLE + ), + 'Cell with rowspan' => array( + array('ISBN', 'Title', 'Author'), + array( + array( + new TableCell('9971-5-0210-0', array('rowspan' => 3)), + new TableCell('Divine Comedy', array('rowspan' => 2)), + 'Dante Alighieri', + ), + array(), + array("The Lord of \nthe Rings", "J. R. \nR. Tolkien"), + new TableSeparator(), + array('80-902734-1-6', new TableCell("And Then \nThere \nWere None", array('rowspan' => 3)), 'Agatha Christie'), + array('80-902734-1-7', 'Test'), + ), + 'default', +<<<'TABLE' ++---------------+---------------+-----------------+ +| ISBN | Title | Author | ++---------------+---------------+-----------------+ +| 9971-5-0210-0 | Divine Comedy | Dante Alighieri | +| | | | +| | The Lord of | J. R. | +| | the Rings | R. Tolkien | ++---------------+---------------+-----------------+ +| 80-902734-1-6 | And Then | Agatha Christie | +| 80-902734-1-7 | There | Test | +| | Were None | | ++---------------+---------------+-----------------+ + +TABLE + ), + 'Cell with rowspan and colspan' => array( + array('ISBN', 'Title', 'Author'), + array( + array( + new TableCell('9971-5-0210-0', array('rowspan' => 2, 'colspan' => 2)), + 'Dante Alighieri', + ), + array('Charles Dickens'), + new TableSeparator(), + array( + 'Dante Alighieri', + new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 2)), + ), + array('J. R. R. Tolkien'), + array('J. R. R'), + ), + 'default', +<<<'TABLE' ++------------------+---------+-----------------+ +| ISBN | Title | Author | ++------------------+---------+-----------------+ +| 9971-5-0210-0 | Dante Alighieri | +| | Charles Dickens | ++------------------+---------+-----------------+ +| Dante Alighieri | 9971-5-0210-0 | +| J. R. R. Tolkien | | +| J. R. R | | ++------------------+---------+-----------------+ + +TABLE + ), + 'Cell with rowspan and colspan contains new line break' => array( + array('ISBN', 'Title', 'Author'), + array( + array( + new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)), + 'Dante Alighieri', + ), + array('Charles Dickens'), + new TableSeparator(), + array( + 'Dante Alighieri', + new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)), + ), + array('Charles Dickens'), + new TableSeparator(), + array( + new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)), + new TableCell("Dante \nAlighieri", array('rowspan' => 2, 'colspan' => 1)), + ), + ), + 'default', +<<<'TABLE' ++-----------------+-------+-----------------+ +| ISBN | Title | Author | ++-----------------+-------+-----------------+ +| 9971 | Dante Alighieri | +| -5- | Charles Dickens | +| 021 | | +| 0-0 | | ++-----------------+-------+-----------------+ +| Dante Alighieri | 9971 | +| Charles Dickens | -5- | +| | 021 | +| | 0-0 | ++-----------------+-------+-----------------+ +| 9971 | Dante | +| -5- | Alighieri | +| 021 | | +| 0-0 | | ++-----------------+-------+-----------------+ + +TABLE + ), + 'Cell with rowspan and colspan without using TableSeparator' => array( + array('ISBN', 'Title', 'Author'), + array( + array( + new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)), + 'Dante Alighieri', + ), + array('Charles Dickens'), + array( + 'Dante Alighieri', + new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)), + ), + array('Charles Dickens'), + ), + 'default', +<<<'TABLE' ++-----------------+-------+-----------------+ +| ISBN | Title | Author | ++-----------------+-------+-----------------+ +| 9971 | Dante Alighieri | +| -5- | Charles Dickens | +| 021 | | +| 0-0 | | +| Dante Alighieri | 9971 | +| Charles Dickens | -5- | +| | 021 | +| | 0-0 | ++-----------------+-------+-----------------+ + +TABLE + ), + 'Cell with rowspan and colspan with separator inside a rowspan' => array( + array('ISBN', 'Author'), + array( + array( + new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 1)), + 'Dante Alighieri', + ), + array(new TableSeparator()), + array('Charles Dickens'), + ), + 'default', +<<<'TABLE' ++---------------+-----------------+ +| ISBN | Author | ++---------------+-----------------+ +| 9971-5-0210-0 | Dante Alighieri | +| |-----------------| +| | Charles Dickens | ++---------------+-----------------+ + +TABLE + ), + 'Multiple header lines' => array( + array( + array(new TableCell('Main title', array('colspan' => 3))), + array('ISBN', 'Title', 'Author'), + ), + array(), + 'default', +<<<'TABLE' ++------+-------+--------+ +| Main title | ++------+-------+--------+ +| ISBN | Title | Author | ++------+-------+--------+ + +TABLE + ), + 'Row with multiple cells' => array( + array(), + array( + array( + new TableCell('1', array('colspan' => 3)), + new TableCell('2', array('colspan' => 2)), + new TableCell('3', array('colspan' => 2)), + new TableCell('4', array('colspan' => 2)), + ), + ), + 'default', +<<<'TABLE' ++---+--+--+---+--+---+--+---+--+ +| 1 | 2 | 3 | 4 | ++---+--+--+---+--+---+--+---+--+ + +TABLE + ), + 'Coslpan and table cells with comment style' => array( + array( + new TableCell('Long Title', array('colspan' => 3)), + ), + array( + array( + new TableCell('9971-5-0210-0', array('colspan' => 3)), + ), + new TableSeparator(), + array( + 'Dante Alighieri', + 'J. R. R. Tolkien', + 'J. R. R', + ), + ), + 'default', + << array( + array(), + array( + array( + new TableCell('Dont break'."\n".'here', array('colspan' => 2)), + ), + new TableSeparator(), + array( + 'foo', + new TableCell('Dont break'."\n".'here', array('rowspan' => 2)), + ), + array( + 'bar', + ), + ), + 'default', + <<<'TABLE' ++-------+------------+ +| Dont break | +| here | ++-------+------------+ +| foo | Dont break | +| bar | here | ++-------+------------+ + +TABLE + , + true, + ), + ); + } + + public function testRenderMultiByte() + { + $table = new Table($output = $this->getOutputStream()); + $table + ->setHeaders(array('■■')) + ->setRows(array(array(1234))) + ->setStyle('default') + ; + $table->render(); + + $expected = +<<<'TABLE' ++------+ +| ■■ | ++------+ +| 1234 | ++------+ + +TABLE; + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + public function testTableCellWithNumericIntValue() + { + $table = new Table($output = $this->getOutputStream()); + + $table->setRows(array(array(new TableCell(12345)))); + $table->render(); + + $expected = +<<<'TABLE' ++-------+ +| 12345 | ++-------+ + +TABLE; + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + public function testTableCellWithNumericFloatValue() + { + $table = new Table($output = $this->getOutputStream()); + + $table->setRows(array(array(new TableCell(12345.01)))); + $table->render(); + + $expected = +<<<'TABLE' ++----------+ +| 12345.01 | ++----------+ + +TABLE; + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + public function testStyle() + { + $style = new TableStyle(); + $style + ->setHorizontalBorderChar('.') + ->setVerticalBorderChar('.') + ->setCrossingChar('.') + ; + + Table::setStyleDefinition('dotfull', $style); + $table = new Table($output = $this->getOutputStream()); + $table + ->setHeaders(array('Foo')) + ->setRows(array(array('Bar'))) + ->setStyle('dotfull'); + $table->render(); + + $expected = +<<<'TABLE' +....... +. Foo . +....... +. Bar . +....... + +TABLE; + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + public function testRowSeparator() + { + $table = new Table($output = $this->getOutputStream()); + $table + ->setHeaders(array('Foo')) + ->setRows(array( + array('Bar1'), + new TableSeparator(), + array('Bar2'), + new TableSeparator(), + array('Bar3'), + )); + $table->render(); + + $expected = +<<<'TABLE' ++------+ +| Foo | ++------+ +| Bar1 | ++------+ +| Bar2 | ++------+ +| Bar3 | ++------+ + +TABLE; + + $this->assertEquals($expected, $this->getOutputContent($output)); + + $this->assertEquals($table, $table->addRow(new TableSeparator()), 'fluent interface on addRow() with a single TableSeparator() works'); + } + + public function testRenderMultiCalls() + { + $table = new Table($output = $this->getOutputStream()); + $table->setRows(array( + array(new TableCell('foo', array('colspan' => 2))), + )); + $table->render(); + $table->render(); + $table->render(); + + $expected = +<<
assertEquals($expected, $this->getOutputContent($output)); + } + + public function testColumnStyle() + { + $table = new Table($output = $this->getOutputStream()); + $table + ->setHeaders(array('ISBN', 'Title', 'Author', 'Price')) + ->setRows(array( + array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri', '9.95'), + array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens', '139.25'), + )); + + $style = new TableStyle(); + $style->setPadType(STR_PAD_LEFT); + $table->setColumnStyle(3, $style); + + $table->render(); + + $expected = + <<
assertEquals($expected, $this->getOutputContent($output)); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\InvalidArgumentException + * @expectedExceptionMessage Style "absent" is not defined. + */ + public function testIsNotDefinedStyleException() + { + $table = new Table($this->getOutputStream()); + $table->setStyle('absent'); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\InvalidArgumentException + * @expectedExceptionMessage Style "absent" is not defined. + */ + public function testGetStyleDefinition() + { + Table::getStyleDefinition('absent'); + } + + protected function getOutputStream($decorated = false) + { + return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, $decorated); + } + + protected function getOutputContent(StreamOutput $output) + { + rewind($output->getStream()); + + return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream())); + } +} diff --git a/vendor/symfony/console/Tests/Input/ArgvInputTest.php b/vendor/symfony/console/Tests/Input/ArgvInputTest.php new file mode 100644 index 000000000..1fe21d0f6 --- /dev/null +++ b/vendor/symfony/console/Tests/Input/ArgvInputTest.php @@ -0,0 +1,371 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Input; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; + +class ArgvInputTest extends TestCase +{ + public function testConstructor() + { + $_SERVER['argv'] = array('cli.php', 'foo'); + $input = new ArgvInput(); + $r = new \ReflectionObject($input); + $p = $r->getProperty('tokens'); + $p->setAccessible(true); + + $this->assertEquals(array('foo'), $p->getValue($input), '__construct() automatically get its input from the argv server variable'); + } + + public function testParseArguments() + { + $input = new ArgvInput(array('cli.php', 'foo')); + $input->bind(new InputDefinition(array(new InputArgument('name')))); + $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments'); + + $input->bind(new InputDefinition(array(new InputArgument('name')))); + $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() is stateless'); + } + + /** + * @dataProvider provideOptions + */ + public function testParseOptions($input, $options, $expectedOptions, $message) + { + $input = new ArgvInput($input); + $input->bind(new InputDefinition($options)); + + $this->assertEquals($expectedOptions, $input->getOptions(), $message); + } + + public function provideOptions() + { + return array( + array( + array('cli.php', '--foo'), + array(new InputOption('foo')), + array('foo' => true), + '->parse() parses long options without a value', + ), + array( + array('cli.php', '--foo=bar'), + array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)), + array('foo' => 'bar'), + '->parse() parses long options with a required value (with a = separator)', + ), + array( + array('cli.php', '--foo', 'bar'), + array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)), + array('foo' => 'bar'), + '->parse() parses long options with a required value (with a space separator)', + ), + array( + array('cli.php', '--foo='), + array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)), + array('foo' => null), + '->parse() parses long options with optional value which is empty (with a = separator) as null', + ), + array( + array('cli.php', '--foo=', 'bar'), + array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED)), + array('foo' => null), + '->parse() parses long options with optional value which is empty (with a = separator) followed by an argument', + ), + array( + array('cli.php', '-f'), + array(new InputOption('foo', 'f')), + array('foo' => true), + '->parse() parses short options without a value', + ), + array( + array('cli.php', '-fbar'), + array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)), + array('foo' => 'bar'), + '->parse() parses short options with a required value (with no separator)', + ), + array( + array('cli.php', '-f', 'bar'), + array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED)), + array('foo' => 'bar'), + '->parse() parses short options with a required value (with a space separator)', + ), + array( + array('cli.php', '-f', ''), + array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)), + array('foo' => ''), + '->parse() parses short options with an optional empty value', + ), + array( + array('cli.php', '-f', '', 'foo'), + array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)), + array('foo' => ''), + '->parse() parses short options with an optional empty value followed by an argument', + ), + array( + array('cli.php', '-f', '', '-b'), + array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')), + array('foo' => '', 'bar' => true), + '->parse() parses short options with an optional empty value followed by an option', + ), + array( + array('cli.php', '-f', '-b', 'foo'), + array(new InputArgument('name'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b')), + array('foo' => null, 'bar' => true), + '->parse() parses short options with an optional value which is not present', + ), + array( + array('cli.php', '-fb'), + array(new InputOption('foo', 'f'), new InputOption('bar', 'b')), + array('foo' => true, 'bar' => true), + '->parse() parses short options when they are aggregated as a single one', + ), + array( + array('cli.php', '-fb', 'bar'), + array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_REQUIRED)), + array('foo' => true, 'bar' => 'bar'), + '->parse() parses short options when they are aggregated as a single one and the last one has a required value', + ), + array( + array('cli.php', '-fb', 'bar'), + array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)), + array('foo' => true, 'bar' => 'bar'), + '->parse() parses short options when they are aggregated as a single one and the last one has an optional value', + ), + array( + array('cli.php', '-fbbar'), + array(new InputOption('foo', 'f'), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)), + array('foo' => true, 'bar' => 'bar'), + '->parse() parses short options when they are aggregated as a single one and the last one has an optional value with no separator', + ), + array( + array('cli.php', '-fbbar'), + array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL)), + array('foo' => 'bbar', 'bar' => null), + '->parse() parses short options when they are aggregated as a single one and one of them takes a value', + ), + ); + } + + /** + * @dataProvider provideInvalidInput + */ + public function testInvalidInput($argv, $definition, $expectedExceptionMessage) + { + if (method_exists($this, 'expectException')) { + $this->expectException('RuntimeException'); + $this->expectExceptionMessage($expectedExceptionMessage); + } else { + $this->setExpectedException('RuntimeException', $expectedExceptionMessage); + } + + $input = new ArgvInput($argv); + $input->bind($definition); + } + + public function provideInvalidInput() + { + return array( + array( + array('cli.php', '--foo'), + new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))), + 'The "--foo" option requires a value.', + ), + array( + array('cli.php', '-f'), + new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))), + 'The "--foo" option requires a value.', + ), + array( + array('cli.php', '-ffoo'), + new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))), + 'The "-o" option does not exist.', + ), + array( + array('cli.php', '--foo=bar'), + new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_NONE))), + 'The "--foo" option does not accept a value.', + ), + array( + array('cli.php', 'foo', 'bar'), + new InputDefinition(), + 'No arguments expected, got "foo".', + ), + array( + array('cli.php', 'foo', 'bar'), + new InputDefinition(array(new InputArgument('number'))), + 'Too many arguments, expected arguments "number".', + ), + array( + array('cli.php', 'foo', 'bar', 'zzz'), + new InputDefinition(array(new InputArgument('number'), new InputArgument('county'))), + 'Too many arguments, expected arguments "number" "county".', + ), + array( + array('cli.php', '--foo'), + new InputDefinition(), + 'The "--foo" option does not exist.', + ), + array( + array('cli.php', '-f'), + new InputDefinition(), + 'The "-f" option does not exist.', + ), + array( + array('cli.php', '-1'), + new InputDefinition(array(new InputArgument('number'))), + 'The "-1" option does not exist.', + ), + ); + } + + public function testParseArrayArgument() + { + $input = new ArgvInput(array('cli.php', 'foo', 'bar', 'baz', 'bat')); + $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::IS_ARRAY)))); + + $this->assertEquals(array('name' => array('foo', 'bar', 'baz', 'bat')), $input->getArguments(), '->parse() parses array arguments'); + } + + public function testParseArrayOption() + { + $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=baz')); + $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY)))); + + $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option=value" syntax)'); + + $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', 'baz')); + $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY)))); + $this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option value" syntax)'); + + $input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=')); + $input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY)))); + $this->assertSame(array('name' => array('foo', 'bar', null)), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)'); + + $input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', '--anotherOption')); + $input->bind(new InputDefinition(array( + new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY), + new InputOption('anotherOption', null, InputOption::VALUE_NONE), + ))); + $this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options as null ("--option value" syntax)'); + } + + public function testParseNegativeNumberAfterDoubleDash() + { + $input = new ArgvInput(array('cli.php', '--', '-1')); + $input->bind(new InputDefinition(array(new InputArgument('number')))); + $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence'); + + $input = new ArgvInput(array('cli.php', '-f', 'bar', '--', '-1')); + $input->bind(new InputDefinition(array(new InputArgument('number'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)))); + $this->assertEquals(array('foo' => 'bar'), $input->getOptions(), '->parse() parses arguments with leading dashes as options before having encountered a double-dash sequence'); + $this->assertEquals(array('number' => '-1'), $input->getArguments(), '->parse() parses arguments with leading dashes as arguments after having encountered a double-dash sequence'); + } + + public function testParseEmptyStringArgument() + { + $input = new ArgvInput(array('cli.php', '-f', 'bar', '')); + $input->bind(new InputDefinition(array(new InputArgument('empty'), new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)))); + + $this->assertEquals(array('empty' => ''), $input->getArguments(), '->parse() parses empty string arguments'); + } + + public function testGetFirstArgument() + { + $input = new ArgvInput(array('cli.php', '-fbbar')); + $this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null when there is no arguments'); + + $input = new ArgvInput(array('cli.php', '-fbbar', 'foo')); + $this->assertEquals('foo', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input'); + } + + public function testHasParameterOption() + { + $input = new ArgvInput(array('cli.php', '-f', 'foo')); + $this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input'); + + $input = new ArgvInput(array('cli.php', '--foo', 'foo')); + $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given short option is in the raw input'); + + $input = new ArgvInput(array('cli.php', 'foo')); + $this->assertFalse($input->hasParameterOption('--foo'), '->hasParameterOption() returns false if the given short option is not in the raw input'); + + $input = new ArgvInput(array('cli.php', '--foo=bar')); + $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given option with provided value is in the raw input'); + } + + public function testToString() + { + $input = new ArgvInput(array('cli.php', '-f', 'foo')); + $this->assertEquals('-f foo', (string) $input); + + $input = new ArgvInput(array('cli.php', '-f', '--bar=foo', 'a b c d', "A\nB'C")); + $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input); + } + + /** + * @dataProvider provideGetParameterOptionValues + */ + public function testGetParameterOptionEqualSign($argv, $key, $expected) + { + $input = new ArgvInput($argv); + $this->assertEquals($expected, $input->getParameterOption($key), '->getParameterOption() returns the expected value'); + } + + public function provideGetParameterOptionValues() + { + return array( + array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'dev'), + array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'dev'), + array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'), + array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'dev'), + array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), '1'), + array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), '1'), + ); + } + + public function testParseSingleDashAsArgument() + { + $input = new ArgvInput(array('cli.php', '-')); + $input->bind(new InputDefinition(array(new InputArgument('file')))); + $this->assertEquals(array('file' => '-'), $input->getArguments(), '->parse() parses single dash as an argument'); + } + + public function testParseOptionWithValueOptionalGivenEmptyAndRequiredArgument() + { + $input = new ArgvInput(array('cli.php', '--foo=', 'bar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED)))); + $this->assertEquals(array('foo' => null), $input->getOptions(), '->parse() parses optional options with empty value as null'); + $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses required arguments'); + + $input = new ArgvInput(array('cli.php', '--foo=0', 'bar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED)))); + $this->assertEquals(array('foo' => '0'), $input->getOptions(), '->parse() parses optional options with empty value as null'); + $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses required arguments'); + } + + public function testParseOptionWithValueOptionalGivenEmptyAndOptionalArgument() + { + $input = new ArgvInput(array('cli.php', '--foo=', 'bar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::OPTIONAL)))); + $this->assertEquals(array('foo' => null), $input->getOptions(), '->parse() parses optional options with empty value as null'); + $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses optional arguments'); + + $input = new ArgvInput(array('cli.php', '--foo=0', 'bar')); + $input->bind(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::OPTIONAL)))); + $this->assertEquals(array('foo' => '0'), $input->getOptions(), '->parse() parses optional options with empty value as null'); + $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->parse() parses optional arguments'); + } +} diff --git a/vendor/symfony/console/Tests/Input/ArrayInputTest.php b/vendor/symfony/console/Tests/Input/ArrayInputTest.php new file mode 100644 index 000000000..06e65f739 --- /dev/null +++ b/vendor/symfony/console/Tests/Input/ArrayInputTest.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Input; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; + +class ArrayInputTest extends TestCase +{ + public function testGetFirstArgument() + { + $input = new ArrayInput(array()); + $this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null if no argument were passed'); + $input = new ArrayInput(array('name' => 'Fabien')); + $this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument'); + $input = new ArrayInput(array('--foo' => 'bar', 'name' => 'Fabien')); + $this->assertEquals('Fabien', $input->getFirstArgument(), '->getFirstArgument() returns the first passed argument'); + } + + public function testHasParameterOption() + { + $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar')); + $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters'); + $this->assertFalse($input->hasParameterOption('--bar'), '->hasParameterOption() returns false if an option is not present in the passed parameters'); + + $input = new ArrayInput(array('--foo')); + $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters'); + } + + public function testGetParameterOption() + { + $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar')); + $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name'); + + $input = new ArrayInput(array('Fabien', '--foo' => 'bar')); + $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name'); + } + + public function testParseArguments() + { + $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name')))); + + $this->assertEquals(array('name' => 'foo'), $input->getArguments(), '->parse() parses required arguments'); + } + + /** + * @dataProvider provideOptions + */ + public function testParseOptions($input, $options, $expectedOptions, $message) + { + $input = new ArrayInput($input, new InputDefinition($options)); + + $this->assertEquals($expectedOptions, $input->getOptions(), $message); + } + + public function provideOptions() + { + return array( + array( + array('--foo' => 'bar'), + array(new InputOption('foo')), + array('foo' => 'bar'), + '->parse() parses long options', + ), + array( + array('--foo' => 'bar'), + array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')), + array('foo' => 'bar'), + '->parse() parses long options with a default value', + ), + array( + array('--foo' => null), + array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')), + array('foo' => 'default'), + '->parse() parses long options with a default value', + ), + array( + array('-f' => 'bar'), + array(new InputOption('foo', 'f')), + array('foo' => 'bar'), + '->parse() parses short options', + ), + ); + } + + /** + * @dataProvider provideInvalidInput + */ + public function testParseInvalidInput($parameters, $definition, $expectedExceptionMessage) + { + if (method_exists($this, 'expectException')) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage($expectedExceptionMessage); + } else { + $this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage); + } + + new ArrayInput($parameters, $definition); + } + + public function provideInvalidInput() + { + return array( + array( + array('foo' => 'foo'), + new InputDefinition(array(new InputArgument('name'))), + 'The "foo" argument does not exist.', + ), + array( + array('--foo' => null), + new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))), + 'The "--foo" option requires a value.', + ), + array( + array('--foo' => 'foo'), + new InputDefinition(), + 'The "--foo" option does not exist.', + ), + array( + array('-o' => 'foo'), + new InputDefinition(), + 'The "-o" option does not exist.', + ), + ); + } + + public function testToString() + { + $input = new ArrayInput(array('-f' => null, '-b' => 'bar', '--foo' => 'b a z', '--lala' => null, 'test' => 'Foo', 'test2' => "A\nB'C")); + $this->assertEquals('-f -b=bar --foo='.escapeshellarg('b a z').' --lala Foo '.escapeshellarg("A\nB'C"), (string) $input); + } +} diff --git a/vendor/symfony/console/Tests/Input/InputArgumentTest.php b/vendor/symfony/console/Tests/Input/InputArgumentTest.php new file mode 100644 index 000000000..66af98b33 --- /dev/null +++ b/vendor/symfony/console/Tests/Input/InputArgumentTest.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Input; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Input\InputArgument; + +class InputArgumentTest extends TestCase +{ + public function testConstructor() + { + $argument = new InputArgument('foo'); + $this->assertEquals('foo', $argument->getName(), '__construct() takes a name as its first argument'); + } + + public function testModes() + { + $argument = new InputArgument('foo'); + $this->assertFalse($argument->isRequired(), '__construct() gives a "InputArgument::OPTIONAL" mode by default'); + + $argument = new InputArgument('foo', null); + $this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode'); + + $argument = new InputArgument('foo', InputArgument::OPTIONAL); + $this->assertFalse($argument->isRequired(), '__construct() can take "InputArgument::OPTIONAL" as its mode'); + + $argument = new InputArgument('foo', InputArgument::REQUIRED); + $this->assertTrue($argument->isRequired(), '__construct() can take "InputArgument::REQUIRED" as its mode'); + } + + /** + * @dataProvider provideInvalidModes + */ + public function testInvalidModes($mode) + { + if (method_exists($this, 'expectException')) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage(sprintf('Argument mode "%s" is not valid.', $mode)); + } else { + $this->setExpectedException('InvalidArgumentException', sprintf('Argument mode "%s" is not valid.', $mode)); + } + + new InputArgument('foo', $mode); + } + + public function provideInvalidModes() + { + return array( + array('ANOTHER_ONE'), + array(-1), + ); + } + + public function testIsArray() + { + $argument = new InputArgument('foo', InputArgument::IS_ARRAY); + $this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array'); + $argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY); + $this->assertTrue($argument->isArray(), '->isArray() returns true if the argument can be an array'); + $argument = new InputArgument('foo', InputArgument::OPTIONAL); + $this->assertFalse($argument->isArray(), '->isArray() returns false if the argument can not be an array'); + } + + public function testGetDescription() + { + $argument = new InputArgument('foo', null, 'Some description'); + $this->assertEquals('Some description', $argument->getDescription(), '->getDescription() return the message description'); + } + + public function testGetDefault() + { + $argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default'); + $this->assertEquals('default', $argument->getDefault(), '->getDefault() return the default value'); + } + + public function testSetDefault() + { + $argument = new InputArgument('foo', InputArgument::OPTIONAL, '', 'default'); + $argument->setDefault(null); + $this->assertNull($argument->getDefault(), '->setDefault() can reset the default value by passing null'); + $argument->setDefault('another'); + $this->assertEquals('another', $argument->getDefault(), '->setDefault() changes the default value'); + + $argument = new InputArgument('foo', InputArgument::OPTIONAL | InputArgument::IS_ARRAY); + $argument->setDefault(array(1, 2)); + $this->assertEquals(array(1, 2), $argument->getDefault(), '->setDefault() changes the default value'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot set a default value except for InputArgument::OPTIONAL mode. + */ + public function testSetDefaultWithRequiredArgument() + { + $argument = new InputArgument('foo', InputArgument::REQUIRED); + $argument->setDefault('default'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage A default value for an array argument must be an array. + */ + public function testSetDefaultWithArrayArgument() + { + $argument = new InputArgument('foo', InputArgument::IS_ARRAY); + $argument->setDefault('default'); + } +} diff --git a/vendor/symfony/console/Tests/Input/InputDefinitionTest.php b/vendor/symfony/console/Tests/Input/InputDefinitionTest.php new file mode 100644 index 000000000..b19708ebb --- /dev/null +++ b/vendor/symfony/console/Tests/Input/InputDefinitionTest.php @@ -0,0 +1,441 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Input; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; + +class InputDefinitionTest extends TestCase +{ + protected static $fixtures; + + protected $foo; + protected $bar; + protected $foo1; + protected $foo2; + + public static function setUpBeforeClass() + { + self::$fixtures = __DIR__.'/../Fixtures/'; + } + + public function testConstructorArguments() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $this->assertEquals(array(), $definition->getArguments(), '__construct() creates a new InputDefinition object'); + + $definition = new InputDefinition(array($this->foo, $this->bar)); + $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '__construct() takes an array of InputArgument objects as its first argument'); + } + + public function testConstructorOptions() + { + $this->initializeOptions(); + + $definition = new InputDefinition(); + $this->assertEquals(array(), $definition->getOptions(), '__construct() creates a new InputDefinition object'); + + $definition = new InputDefinition(array($this->foo, $this->bar)); + $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '__construct() takes an array of InputOption objects as its first argument'); + } + + public function testSetArguments() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->setArguments(array($this->foo)); + $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->setArguments() sets the array of InputArgument objects'); + $definition->setArguments(array($this->bar)); + + $this->assertEquals(array('bar' => $this->bar), $definition->getArguments(), '->setArguments() clears all InputArgument objects'); + } + + public function testAddArguments() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArguments(array($this->foo)); + $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArguments() adds an array of InputArgument objects'); + $definition->addArguments(array($this->bar)); + $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArguments() does not clear existing InputArgument objects'); + } + + public function testAddArgument() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArgument($this->foo); + $this->assertEquals(array('foo' => $this->foo), $definition->getArguments(), '->addArgument() adds a InputArgument object'); + $definition->addArgument($this->bar); + $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getArguments(), '->addArgument() adds a InputArgument object'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage An argument with name "foo" already exists. + */ + public function testArgumentsMustHaveDifferentNames() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArgument($this->foo); + $definition->addArgument($this->foo1); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot add an argument after an array argument. + */ + public function testArrayArgumentHasToBeLast() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArgument(new InputArgument('fooarray', InputArgument::IS_ARRAY)); + $definition->addArgument(new InputArgument('anotherbar')); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot add a required argument after an optional one. + */ + public function testRequiredArgumentCannotFollowAnOptionalOne() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArgument($this->foo); + $definition->addArgument($this->foo2); + } + + public function testGetArgument() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArguments(array($this->foo)); + $this->assertEquals($this->foo, $definition->getArgument('foo'), '->getArgument() returns a InputArgument by its name'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The "bar" argument does not exist. + */ + public function testGetInvalidArgument() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArguments(array($this->foo)); + $definition->getArgument('bar'); + } + + public function testHasArgument() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArguments(array($this->foo)); + + $this->assertTrue($definition->hasArgument('foo'), '->hasArgument() returns true if a InputArgument exists for the given name'); + $this->assertFalse($definition->hasArgument('bar'), '->hasArgument() returns false if a InputArgument exists for the given name'); + } + + public function testGetArgumentRequiredCount() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArgument($this->foo2); + $this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments'); + $definition->addArgument($this->foo); + $this->assertEquals(1, $definition->getArgumentRequiredCount(), '->getArgumentRequiredCount() returns the number of required arguments'); + } + + public function testGetArgumentCount() + { + $this->initializeArguments(); + + $definition = new InputDefinition(); + $definition->addArgument($this->foo2); + $this->assertEquals(1, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments'); + $definition->addArgument($this->foo); + $this->assertEquals(2, $definition->getArgumentCount(), '->getArgumentCount() returns the number of arguments'); + } + + public function testGetArgumentDefaults() + { + $definition = new InputDefinition(array( + new InputArgument('foo1', InputArgument::OPTIONAL), + new InputArgument('foo2', InputArgument::OPTIONAL, '', 'default'), + new InputArgument('foo3', InputArgument::OPTIONAL | InputArgument::IS_ARRAY), + // new InputArgument('foo4', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, '', array(1, 2)), + )); + $this->assertEquals(array('foo1' => null, 'foo2' => 'default', 'foo3' => array()), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument'); + + $definition = new InputDefinition(array( + new InputArgument('foo4', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, '', array(1, 2)), + )); + $this->assertEquals(array('foo4' => array(1, 2)), $definition->getArgumentDefaults(), '->getArgumentDefaults() return the default values for each argument'); + } + + public function testSetOptions() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->foo)); + $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->setOptions() sets the array of InputOption objects'); + $definition->setOptions(array($this->bar)); + $this->assertEquals(array('bar' => $this->bar), $definition->getOptions(), '->setOptions() clears all InputOption objects'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The "-f" option does not exist. + */ + public function testSetOptionsClearsOptions() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->foo)); + $definition->setOptions(array($this->bar)); + $definition->getOptionForShortcut('f'); + } + + public function testAddOptions() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->foo)); + $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOptions() adds an array of InputOption objects'); + $definition->addOptions(array($this->bar)); + $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOptions() does not clear existing InputOption objects'); + } + + public function testAddOption() + { + $this->initializeOptions(); + + $definition = new InputDefinition(); + $definition->addOption($this->foo); + $this->assertEquals(array('foo' => $this->foo), $definition->getOptions(), '->addOption() adds a InputOption object'); + $definition->addOption($this->bar); + $this->assertEquals(array('foo' => $this->foo, 'bar' => $this->bar), $definition->getOptions(), '->addOption() adds a InputOption object'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage An option named "foo" already exists. + */ + public function testAddDuplicateOption() + { + $this->initializeOptions(); + + $definition = new InputDefinition(); + $definition->addOption($this->foo); + $definition->addOption($this->foo2); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage An option with shortcut "f" already exists. + */ + public function testAddDuplicateShortcutOption() + { + $this->initializeOptions(); + + $definition = new InputDefinition(); + $definition->addOption($this->foo); + $definition->addOption($this->foo1); + } + + public function testGetOption() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->foo)); + $this->assertEquals($this->foo, $definition->getOption('foo'), '->getOption() returns a InputOption by its name'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The "--bar" option does not exist. + */ + public function testGetInvalidOption() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->foo)); + $definition->getOption('bar'); + } + + public function testHasOption() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->foo)); + $this->assertTrue($definition->hasOption('foo'), '->hasOption() returns true if a InputOption exists for the given name'); + $this->assertFalse($definition->hasOption('bar'), '->hasOption() returns false if a InputOption exists for the given name'); + } + + public function testHasShortcut() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->foo)); + $this->assertTrue($definition->hasShortcut('f'), '->hasShortcut() returns true if a InputOption exists for the given shortcut'); + $this->assertFalse($definition->hasShortcut('b'), '->hasShortcut() returns false if a InputOption exists for the given shortcut'); + } + + public function testGetOptionForShortcut() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->foo)); + $this->assertEquals($this->foo, $definition->getOptionForShortcut('f'), '->getOptionForShortcut() returns a InputOption by its shortcut'); + } + + public function testGetOptionForMultiShortcut() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->multi)); + $this->assertEquals($this->multi, $definition->getOptionForShortcut('m'), '->getOptionForShortcut() returns a InputOption by its shortcut'); + $this->assertEquals($this->multi, $definition->getOptionForShortcut('mmm'), '->getOptionForShortcut() returns a InputOption by its shortcut'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The "-l" option does not exist. + */ + public function testGetOptionForInvalidShortcut() + { + $this->initializeOptions(); + + $definition = new InputDefinition(array($this->foo)); + $definition->getOptionForShortcut('l'); + } + + public function testGetOptionDefaults() + { + $definition = new InputDefinition(array( + new InputOption('foo1', null, InputOption::VALUE_NONE), + new InputOption('foo2', null, InputOption::VALUE_REQUIRED), + new InputOption('foo3', null, InputOption::VALUE_REQUIRED, '', 'default'), + new InputOption('foo4', null, InputOption::VALUE_OPTIONAL), + new InputOption('foo5', null, InputOption::VALUE_OPTIONAL, '', 'default'), + new InputOption('foo6', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY), + new InputOption('foo7', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, '', array(1, 2)), + )); + $defaults = array( + 'foo1' => false, + 'foo2' => null, + 'foo3' => 'default', + 'foo4' => null, + 'foo5' => 'default', + 'foo6' => array(), + 'foo7' => array(1, 2), + ); + $this->assertSame($defaults, $definition->getOptionDefaults(), '->getOptionDefaults() returns the default values for all options'); + } + + /** + * @dataProvider getGetSynopsisData + */ + public function testGetSynopsis(InputDefinition $definition, $expectedSynopsis, $message = null) + { + $this->assertEquals($expectedSynopsis, $definition->getSynopsis(), $message ? '->getSynopsis() '.$message : ''); + } + + public function getGetSynopsisData() + { + return array( + array(new InputDefinition(array(new InputOption('foo'))), '[--foo]', 'puts optional options in square brackets'), + array(new InputDefinition(array(new InputOption('foo', 'f'))), '[-f|--foo]', 'separates shortcut with a pipe'), + array(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_REQUIRED))), '[-f|--foo FOO]', 'uses shortcut as value placeholder'), + array(new InputDefinition(array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL))), '[-f|--foo [FOO]]', 'puts optional values in square brackets'), + + array(new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED))), '', 'puts arguments in angle brackets'), + array(new InputDefinition(array(new InputArgument('foo'))), '[]', 'puts optional arguments in square brackets'), + array(new InputDefinition(array(new InputArgument('foo', InputArgument::IS_ARRAY))), '[]...', 'uses an ellipsis for array arguments'), + array(new InputDefinition(array(new InputArgument('foo', InputArgument::REQUIRED | InputArgument::IS_ARRAY))), ' ()...', 'uses parenthesis and ellipsis for required array arguments'), + + array(new InputDefinition(array(new InputOption('foo'), new InputArgument('foo', InputArgument::REQUIRED))), '[--foo] [--] ', 'puts [--] between options and arguments'), + ); + } + + public function testGetShortSynopsis() + { + $definition = new InputDefinition(array(new InputOption('foo'), new InputOption('bar'), new InputArgument('cat'))); + $this->assertEquals('[options] [--] []', $definition->getSynopsis(true), '->getSynopsis(true) groups options in [options]'); + } + + /** + * @group legacy + */ + public function testLegacyAsText() + { + $definition = new InputDefinition(array( + new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'), + new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true), + new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('http://foo.com/')), + new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'), + new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false), + new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'), + new InputOption('qux', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux option', array('http://foo.com/', 'bar')), + new InputOption('qux2', '', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The qux2 option', array('foo' => 'bar')), + )); + + $this->assertStringEqualsFile(self::$fixtures.'/definition_astext.txt', $definition->asText(), '->asText() returns a textual representation of the InputDefinition'); + } + + /** + * @group legacy + */ + public function testLegacyAsXml() + { + $definition = new InputDefinition(array( + new InputArgument('foo', InputArgument::OPTIONAL, 'The foo argument'), + new InputArgument('baz', InputArgument::OPTIONAL, 'The baz argument', true), + new InputArgument('bar', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The bar argument', array('bar')), + new InputOption('foo', 'f', InputOption::VALUE_REQUIRED, 'The foo option'), + new InputOption('baz', null, InputOption::VALUE_OPTIONAL, 'The baz option', false), + new InputOption('bar', 'b', InputOption::VALUE_OPTIONAL, 'The bar option', 'bar'), + )); + $this->assertXmlStringEqualsXmlFile(self::$fixtures.'/definition_asxml.txt', $definition->asXml(), '->asXml() returns an XML representation of the InputDefinition'); + } + + protected function initializeArguments() + { + $this->foo = new InputArgument('foo'); + $this->bar = new InputArgument('bar'); + $this->foo1 = new InputArgument('foo'); + $this->foo2 = new InputArgument('foo2', InputArgument::REQUIRED); + } + + protected function initializeOptions() + { + $this->foo = new InputOption('foo', 'f'); + $this->bar = new InputOption('bar', 'b'); + $this->foo1 = new InputOption('fooBis', 'f'); + $this->foo2 = new InputOption('foo', 'p'); + $this->multi = new InputOption('multi', 'm|mm|mmm'); + } +} diff --git a/vendor/symfony/console/Tests/Input/InputOptionTest.php b/vendor/symfony/console/Tests/Input/InputOptionTest.php new file mode 100644 index 000000000..943bf607f --- /dev/null +++ b/vendor/symfony/console/Tests/Input/InputOptionTest.php @@ -0,0 +1,210 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Input; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Input\InputOption; + +class InputOptionTest extends TestCase +{ + public function testConstructor() + { + $option = new InputOption('foo'); + $this->assertEquals('foo', $option->getName(), '__construct() takes a name as its first argument'); + $option = new InputOption('--foo'); + $this->assertEquals('foo', $option->getName(), '__construct() removes the leading -- of the option name'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value. + */ + public function testArrayModeWithoutValue() + { + new InputOption('foo', 'f', InputOption::VALUE_IS_ARRAY); + } + + public function testShortcut() + { + $option = new InputOption('foo', 'f'); + $this->assertEquals('f', $option->getShortcut(), '__construct() can take a shortcut as its second argument'); + $option = new InputOption('foo', '-f|-ff|fff'); + $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts'); + $option = new InputOption('foo', array('f', 'ff', '-fff')); + $this->assertEquals('f|ff|fff', $option->getShortcut(), '__construct() removes the leading - of the shortcuts'); + $option = new InputOption('foo'); + $this->assertNull($option->getShortcut(), '__construct() makes the shortcut null by default'); + } + + public function testModes() + { + $option = new InputOption('foo', 'f'); + $this->assertFalse($option->acceptValue(), '__construct() gives a "InputOption::VALUE_NONE" mode by default'); + $this->assertFalse($option->isValueRequired(), '__construct() gives a "InputOption::VALUE_NONE" mode by default'); + $this->assertFalse($option->isValueOptional(), '__construct() gives a "InputOption::VALUE_NONE" mode by default'); + + $option = new InputOption('foo', 'f', null); + $this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode'); + $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode'); + $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode'); + + $option = new InputOption('foo', 'f', InputOption::VALUE_NONE); + $this->assertFalse($option->acceptValue(), '__construct() can take "InputOption::VALUE_NONE" as its mode'); + $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_NONE" as its mode'); + $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_NONE" as its mode'); + + $option = new InputOption('foo', 'f', InputOption::VALUE_REQUIRED); + $this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode'); + $this->assertTrue($option->isValueRequired(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode'); + $this->assertFalse($option->isValueOptional(), '__construct() can take "InputOption::VALUE_REQUIRED" as its mode'); + + $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL); + $this->assertTrue($option->acceptValue(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode'); + $this->assertFalse($option->isValueRequired(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode'); + $this->assertTrue($option->isValueOptional(), '__construct() can take "InputOption::VALUE_OPTIONAL" as its mode'); + } + + /** + * @dataProvider provideInvalidModes + */ + public function testInvalidModes($mode) + { + if (method_exists($this, 'expectException')) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage(sprintf('Option mode "%s" is not valid.', $mode)); + } else { + $this->setExpectedException('InvalidArgumentException', sprintf('Option mode "%s" is not valid.', $mode)); + } + + new InputOption('foo', 'f', $mode); + } + + public function provideInvalidModes() + { + return array( + array('ANOTHER_ONE'), + array(-1), + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testEmptyNameIsInvalid() + { + new InputOption(''); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testDoubleDashNameIsInvalid() + { + new InputOption('--'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSingleDashOptionIsInvalid() + { + new InputOption('foo', '-'); + } + + public function testIsArray() + { + $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY); + $this->assertTrue($option->isArray(), '->isArray() returns true if the option can be an array'); + $option = new InputOption('foo', null, InputOption::VALUE_NONE); + $this->assertFalse($option->isArray(), '->isArray() returns false if the option can not be an array'); + } + + public function testGetDescription() + { + $option = new InputOption('foo', 'f', null, 'Some description'); + $this->assertEquals('Some description', $option->getDescription(), '->getDescription() returns the description message'); + } + + public function testGetDefault() + { + $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL, '', 'default'); + $this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value'); + + $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default'); + $this->assertEquals('default', $option->getDefault(), '->getDefault() returns the default value'); + + $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED); + $this->assertNull($option->getDefault(), '->getDefault() returns null if no default value is configured'); + + $option = new InputOption('foo', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY); + $this->assertEquals(array(), $option->getDefault(), '->getDefault() returns an empty array if option is an array'); + + $option = new InputOption('foo', null, InputOption::VALUE_NONE); + $this->assertFalse($option->getDefault(), '->getDefault() returns false if the option does not take a value'); + } + + public function testSetDefault() + { + $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED, '', 'default'); + $option->setDefault(null); + $this->assertNull($option->getDefault(), '->setDefault() can reset the default value by passing null'); + $option->setDefault('another'); + $this->assertEquals('another', $option->getDefault(), '->setDefault() changes the default value'); + + $option = new InputOption('foo', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY); + $option->setDefault(array(1, 2)); + $this->assertEquals(array(1, 2), $option->getDefault(), '->setDefault() changes the default value'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot set a default value when using InputOption::VALUE_NONE mode. + */ + public function testDefaultValueWithValueNoneMode() + { + $option = new InputOption('foo', 'f', InputOption::VALUE_NONE); + $option->setDefault('default'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage A default value for an array option must be an array. + */ + public function testDefaultValueWithIsArrayMode() + { + $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY); + $option->setDefault('default'); + } + + public function testEquals() + { + $option = new InputOption('foo', 'f', null, 'Some description'); + $option2 = new InputOption('foo', 'f', null, 'Alternative description'); + $this->assertTrue($option->equals($option2)); + + $option = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description'); + $option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description', true); + $this->assertFalse($option->equals($option2)); + + $option = new InputOption('foo', 'f', null, 'Some description'); + $option2 = new InputOption('bar', 'f', null, 'Some description'); + $this->assertFalse($option->equals($option2)); + + $option = new InputOption('foo', 'f', null, 'Some description'); + $option2 = new InputOption('foo', '', null, 'Some description'); + $this->assertFalse($option->equals($option2)); + + $option = new InputOption('foo', 'f', null, 'Some description'); + $option2 = new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, 'Some description'); + $this->assertFalse($option->equals($option2)); + } +} diff --git a/vendor/symfony/console/Tests/Input/InputTest.php b/vendor/symfony/console/Tests/Input/InputTest.php new file mode 100644 index 000000000..42abd82ea --- /dev/null +++ b/vendor/symfony/console/Tests/Input/InputTest.php @@ -0,0 +1,133 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Input; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; + +class InputTest extends TestCase +{ + public function testConstructor() + { + $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name')))); + $this->assertEquals('foo', $input->getArgument('name'), '->__construct() takes a InputDefinition as an argument'); + } + + public function testOptions() + { + $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name')))); + $this->assertEquals('foo', $input->getOption('name'), '->getOption() returns the value for the given option'); + + $input->setOption('name', 'bar'); + $this->assertEquals('bar', $input->getOption('name'), '->setOption() sets the value for a given option'); + $this->assertEquals(array('name' => 'bar'), $input->getOptions(), '->getOptions() returns all option values'); + + $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default')))); + $this->assertEquals('default', $input->getOption('bar'), '->getOption() returns the default value for optional options'); + $this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getOptions(), '->getOptions() returns all option values, even optional ones'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The "foo" option does not exist. + */ + public function testSetInvalidOption() + { + $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default')))); + $input->setOption('foo', 'bar'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The "foo" option does not exist. + */ + public function testGetInvalidOption() + { + $input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default')))); + $input->getOption('foo'); + } + + public function testArguments() + { + $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name')))); + $this->assertEquals('foo', $input->getArgument('name'), '->getArgument() returns the value for the given argument'); + + $input->setArgument('name', 'bar'); + $this->assertEquals('bar', $input->getArgument('name'), '->setArgument() sets the value for a given argument'); + $this->assertEquals(array('name' => 'bar'), $input->getArguments(), '->getArguments() returns all argument values'); + + $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default')))); + $this->assertEquals('default', $input->getArgument('bar'), '->getArgument() returns the default value for optional arguments'); + $this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getArguments(), '->getArguments() returns all argument values, even optional ones'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The "foo" argument does not exist. + */ + public function testSetInvalidArgument() + { + $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default')))); + $input->setArgument('foo', 'bar'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The "foo" argument does not exist. + */ + public function testGetInvalidArgument() + { + $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name'), new InputArgument('bar', InputArgument::OPTIONAL, '', 'default')))); + $input->getArgument('foo'); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Not enough arguments (missing: "name"). + */ + public function testValidateWithMissingArguments() + { + $input = new ArrayInput(array()); + $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED)))); + $input->validate(); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Not enough arguments (missing: "name"). + */ + public function testValidateWithMissingRequiredArguments() + { + $input = new ArrayInput(array('bar' => 'baz')); + $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED), new InputArgument('bar', InputArgument::OPTIONAL)))); + $input->validate(); + } + + public function testValidate() + { + $input = new ArrayInput(array('name' => 'foo')); + $input->bind(new InputDefinition(array(new InputArgument('name', InputArgument::REQUIRED)))); + + $this->assertNull($input->validate()); + } + + public function testSetGetInteractive() + { + $input = new ArrayInput(array()); + $this->assertTrue($input->isInteractive(), '->isInteractive() returns whether the input should be interactive or not'); + $input->setInteractive(false); + $this->assertFalse($input->isInteractive(), '->setInteractive() changes the interactive flag'); + } +} diff --git a/vendor/symfony/console/Tests/Input/StringInputTest.php b/vendor/symfony/console/Tests/Input/StringInputTest.php new file mode 100644 index 000000000..839af7387 --- /dev/null +++ b/vendor/symfony/console/Tests/Input/StringInputTest.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Input; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\StringInput; + +class StringInputTest extends TestCase +{ + /** + * @dataProvider getTokenizeData + */ + public function testTokenize($input, $tokens, $message) + { + $input = new StringInput($input); + $r = new \ReflectionClass('Symfony\Component\Console\Input\ArgvInput'); + $p = $r->getProperty('tokens'); + $p->setAccessible(true); + $this->assertEquals($tokens, $p->getValue($input), $message); + } + + public function testInputOptionWithGivenString() + { + $definition = new InputDefinition( + array(new InputOption('foo', null, InputOption::VALUE_REQUIRED)) + ); + + // call to bind + $input = new StringInput('--foo=bar'); + $input->bind($definition); + $this->assertEquals('bar', $input->getOption('foo')); + } + + /** + * @group legacy + */ + public function testLegacyInputOptionDefinitionInConstructor() + { + $definition = new InputDefinition( + array(new InputOption('foo', null, InputOption::VALUE_REQUIRED)) + ); + + $input = new StringInput('--foo=bar', $definition); + $this->assertEquals('bar', $input->getOption('foo')); + } + + public function getTokenizeData() + { + return array( + array('', array(), '->tokenize() parses an empty string'), + array('foo', array('foo'), '->tokenize() parses arguments'), + array(' foo bar ', array('foo', 'bar'), '->tokenize() ignores whitespaces between arguments'), + array('"quoted"', array('quoted'), '->tokenize() parses quoted arguments'), + array("'quoted'", array('quoted'), '->tokenize() parses quoted arguments'), + array("'a\rb\nc\td'", array("a\rb\nc\td"), '->tokenize() parses whitespace chars in strings'), + array("'a'\r'b'\n'c'\t'd'", array('a', 'b', 'c', 'd'), '->tokenize() parses whitespace chars between args as spaces'), + array('\"quoted\"', array('"quoted"'), '->tokenize() parses escaped-quoted arguments'), + array("\'quoted\'", array('\'quoted\''), '->tokenize() parses escaped-quoted arguments'), + array('-a', array('-a'), '->tokenize() parses short options'), + array('-azc', array('-azc'), '->tokenize() parses aggregated short options'), + array('-awithavalue', array('-awithavalue'), '->tokenize() parses short options with a value'), + array('-a"foo bar"', array('-afoo bar'), '->tokenize() parses short options with a value'), + array('-a"foo bar""foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'), + array('-a\'foo bar\'', array('-afoo bar'), '->tokenize() parses short options with a value'), + array('-a\'foo bar\'\'foo bar\'', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'), + array('-a\'foo bar\'"foo bar"', array('-afoo barfoo bar'), '->tokenize() parses short options with a value'), + array('--long-option', array('--long-option'), '->tokenize() parses long options'), + array('--long-option=foo', array('--long-option=foo'), '->tokenize() parses long options with a value'), + array('--long-option="foo bar"', array('--long-option=foo bar'), '->tokenize() parses long options with a value'), + array('--long-option="foo bar""another"', array('--long-option=foo baranother'), '->tokenize() parses long options with a value'), + array('--long-option=\'foo bar\'', array('--long-option=foo bar'), '->tokenize() parses long options with a value'), + array("--long-option='foo bar''another'", array('--long-option=foo baranother'), '->tokenize() parses long options with a value'), + array("--long-option='foo bar'\"another\"", array('--long-option=foo baranother'), '->tokenize() parses long options with a value'), + array('foo -a -ffoo --long bar', array('foo', '-a', '-ffoo', '--long', 'bar'), '->tokenize() parses when several arguments and options'), + ); + } + + public function testToString() + { + $input = new StringInput('-f foo'); + $this->assertEquals('-f foo', (string) $input); + + $input = new StringInput('-f --bar=foo "a b c d"'); + $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d'), (string) $input); + + $input = new StringInput('-f --bar=foo \'a b c d\' '."'A\nB\\'C'"); + $this->assertEquals('-f --bar=foo '.escapeshellarg('a b c d').' '.escapeshellarg("A\nB'C"), (string) $input); + } +} diff --git a/vendor/symfony/console/Tests/Logger/ConsoleLoggerTest.php b/vendor/symfony/console/Tests/Logger/ConsoleLoggerTest.php new file mode 100644 index 000000000..dac911b2b --- /dev/null +++ b/vendor/symfony/console/Tests/Logger/ConsoleLoggerTest.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Logger; + +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; +use Symfony\Component\Console\Logger\ConsoleLogger; +use Symfony\Component\Console\Tests\Fixtures\DummyOutput; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Console logger test. + * + * @author Kévin Dunglas + * @author Jordi Boggiano + */ +class ConsoleLoggerTest extends TestCase +{ + /** + * @var DummyOutput + */ + protected $output; + + /** + * @return LoggerInterface + */ + public function getLogger() + { + $this->output = new DummyOutput(OutputInterface::VERBOSITY_VERBOSE); + + return new ConsoleLogger($this->output, array( + LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL, + LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL, + LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL, + LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL, + LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL, + LogLevel::NOTICE => OutputInterface::VERBOSITY_NORMAL, + LogLevel::INFO => OutputInterface::VERBOSITY_NORMAL, + LogLevel::DEBUG => OutputInterface::VERBOSITY_NORMAL, + )); + } + + /** + * Return the log messages in order. + * + * @return string[] + */ + public function getLogs() + { + return $this->output->getLogs(); + } + + public function testImplements() + { + $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); + } + + /** + * @dataProvider provideLevelsAndMessages + */ + public function testLogsAtAllLevels($level, $message) + { + $logger = $this->getLogger(); + $logger->{$level}($message, array('user' => 'Bob')); + $logger->log($level, $message, array('user' => 'Bob')); + + $expected = array( + $level.' message of level '.$level.' with context: Bob', + $level.' message of level '.$level.' with context: Bob', + ); + $this->assertEquals($expected, $this->getLogs()); + } + + public function provideLevelsAndMessages() + { + return array( + LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), + LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), + LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), + LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), + LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), + LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), + LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), + LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), + ); + } + + /** + * @expectedException \Psr\Log\InvalidArgumentException + */ + public function testThrowsOnInvalidLevel() + { + $logger = $this->getLogger(); + $logger->log('invalid level', 'Foo'); + } + + public function testContextReplacement() + { + $logger = $this->getLogger(); + $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + + $expected = array('info {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testObjectCastToString() + { + if (method_exists($this, 'createPartialMock')) { + $dummy = $this->createPartialMock('Symfony\Component\Console\Tests\Logger\DummyTest', array('__toString')); + } else { + $dummy = $this->getMock('Symfony\Component\Console\Tests\Logger\DummyTest', array('__toString')); + } + $dummy->expects($this->once()) + ->method('__toString') + ->will($this->returnValue('DUMMY')); + + $this->getLogger()->warning($dummy); + + $expected = array('warning DUMMY'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextCanContainAnything() + { + $context = array( + 'bool' => true, + 'null' => null, + 'string' => 'Foo', + 'int' => 0, + 'float' => 0.5, + 'nested' => array('with object' => new DummyTest()), + 'object' => new \DateTime(), + 'resource' => fopen('php://memory', 'r'), + ); + + $this->getLogger()->warning('Crazy context data', $context); + + $expected = array('warning Crazy context data'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextExceptionKeyCanBeExceptionOrOtherValues() + { + $logger = $this->getLogger(); + $logger->warning('Random message', array('exception' => 'oops')); + $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + + $expected = array( + 'warning Random message', + 'critical Uncaught Exception!', + ); + $this->assertEquals($expected, $this->getLogs()); + } +} + +class DummyTest +{ + public function __toString() + { + } +} diff --git a/vendor/symfony/console/Tests/Output/ConsoleOutputTest.php b/vendor/symfony/console/Tests/Output/ConsoleOutputTest.php new file mode 100644 index 000000000..db39a02b8 --- /dev/null +++ b/vendor/symfony/console/Tests/Output/ConsoleOutputTest.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Output; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Output\ConsoleOutput; +use Symfony\Component\Console\Output\Output; + +class ConsoleOutputTest extends TestCase +{ + public function testConstructor() + { + $output = new ConsoleOutput(Output::VERBOSITY_QUIET, true); + $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument'); + $this->assertSame($output->getFormatter(), $output->getErrorOutput()->getFormatter(), '__construct() takes a formatter or null as the third argument'); + } + + public function testSetFormatter() + { + $output = new ConsoleOutput(); + $outputFormatter = new OutputFormatter(); + $output->setFormatter($outputFormatter); + $this->assertSame($outputFormatter, $output->getFormatter()); + } + + public function testSetVerbosity() + { + $output = new ConsoleOutput(); + $output->setVerbosity(Output::VERBOSITY_VERBOSE); + $this->assertSame(Output::VERBOSITY_VERBOSE, $output->getVerbosity()); + } +} diff --git a/vendor/symfony/console/Tests/Output/NullOutputTest.php b/vendor/symfony/console/Tests/Output/NullOutputTest.php new file mode 100644 index 000000000..b7ff4be31 --- /dev/null +++ b/vendor/symfony/console/Tests/Output/NullOutputTest.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Output; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Output\OutputInterface; + +class NullOutputTest extends TestCase +{ + public function testConstructor() + { + $output = new NullOutput(); + + ob_start(); + $output->write('foo'); + $buffer = ob_get_clean(); + + $this->assertSame('', $buffer, '->write() does nothing (at least nothing is printed)'); + $this->assertFalse($output->isDecorated(), '->isDecorated() returns false'); + } + + public function testVerbosity() + { + $output = new NullOutput(); + $this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() returns VERBOSITY_QUIET for NullOutput by default'); + + $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); + $this->assertSame(OutputInterface::VERBOSITY_QUIET, $output->getVerbosity(), '->getVerbosity() always returns VERBOSITY_QUIET for NullOutput'); + } + + public function testSetFormatter() + { + $output = new NullOutput(); + $outputFormatter = new OutputFormatter(); + $output->setFormatter($outputFormatter); + $this->assertNotSame($outputFormatter, $output->getFormatter()); + } + + public function testSetVerbosity() + { + $output = new NullOutput(); + $output->setVerbosity(Output::VERBOSITY_NORMAL); + $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity()); + } + + public function testSetDecorated() + { + $output = new NullOutput(); + $output->setDecorated(true); + $this->assertFalse($output->isDecorated()); + } + + public function testIsQuiet() + { + $output = new NullOutput(); + $this->assertTrue($output->isQuiet()); + } + + public function testIsVerbose() + { + $output = new NullOutput(); + $this->assertFalse($output->isVerbose()); + } + + public function testIsVeryVerbose() + { + $output = new NullOutput(); + $this->assertFalse($output->isVeryVerbose()); + } + + public function testIsDebug() + { + $output = new NullOutput(); + $this->assertFalse($output->isDebug()); + } +} diff --git a/vendor/symfony/console/Tests/Output/OutputTest.php b/vendor/symfony/console/Tests/Output/OutputTest.php new file mode 100644 index 000000000..d8330d0bd --- /dev/null +++ b/vendor/symfony/console/Tests/Output/OutputTest.php @@ -0,0 +1,176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Output; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; + +class OutputTest extends TestCase +{ + public function testConstructor() + { + $output = new TestOutput(Output::VERBOSITY_QUIET, true); + $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument'); + $this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument'); + } + + public function testSetIsDecorated() + { + $output = new TestOutput(); + $output->setDecorated(true); + $this->assertTrue($output->isDecorated(), 'setDecorated() sets the decorated flag'); + } + + public function testSetGetVerbosity() + { + $output = new TestOutput(); + $output->setVerbosity(Output::VERBOSITY_QUIET); + $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '->setVerbosity() sets the verbosity'); + + $this->assertTrue($output->isQuiet()); + $this->assertFalse($output->isVerbose()); + $this->assertFalse($output->isVeryVerbose()); + $this->assertFalse($output->isDebug()); + + $output->setVerbosity(Output::VERBOSITY_NORMAL); + $this->assertFalse($output->isQuiet()); + $this->assertFalse($output->isVerbose()); + $this->assertFalse($output->isVeryVerbose()); + $this->assertFalse($output->isDebug()); + + $output->setVerbosity(Output::VERBOSITY_VERBOSE); + $this->assertFalse($output->isQuiet()); + $this->assertTrue($output->isVerbose()); + $this->assertFalse($output->isVeryVerbose()); + $this->assertFalse($output->isDebug()); + + $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE); + $this->assertFalse($output->isQuiet()); + $this->assertTrue($output->isVerbose()); + $this->assertTrue($output->isVeryVerbose()); + $this->assertFalse($output->isDebug()); + + $output->setVerbosity(Output::VERBOSITY_DEBUG); + $this->assertFalse($output->isQuiet()); + $this->assertTrue($output->isVerbose()); + $this->assertTrue($output->isVeryVerbose()); + $this->assertTrue($output->isDebug()); + } + + public function testWriteWithVerbosityQuiet() + { + $output = new TestOutput(Output::VERBOSITY_QUIET); + $output->writeln('foo'); + $this->assertEquals('', $output->output, '->writeln() outputs nothing if verbosity is set to VERBOSITY_QUIET'); + } + + public function testWriteAnArrayOfMessages() + { + $output = new TestOutput(); + $output->writeln(array('foo', 'bar')); + $this->assertEquals("foo\nbar\n", $output->output, '->writeln() can take an array of messages to output'); + } + + /** + * @dataProvider provideWriteArguments + */ + public function testWriteRawMessage($message, $type, $expectedOutput) + { + $output = new TestOutput(); + $output->writeln($message, $type); + $this->assertEquals($expectedOutput, $output->output); + } + + public function provideWriteArguments() + { + return array( + array('foo', Output::OUTPUT_RAW, "foo\n"), + array('foo', Output::OUTPUT_PLAIN, "foo\n"), + ); + } + + public function testWriteWithDecorationTurnedOff() + { + $output = new TestOutput(); + $output->setDecorated(false); + $output->writeln('foo'); + $this->assertEquals("foo\n", $output->output, '->writeln() strips decoration tags if decoration is set to false'); + } + + public function testWriteDecoratedMessage() + { + $fooStyle = new OutputFormatterStyle('yellow', 'red', array('blink')); + $output = new TestOutput(); + $output->getFormatter()->setStyle('FOO', $fooStyle); + $output->setDecorated(true); + $output->writeln('foo'); + $this->assertEquals("\033[33;41;5mfoo\033[39;49;25m\n", $output->output, '->writeln() decorates the output'); + } + + public function testWriteWithInvalidStyle() + { + $output = new TestOutput(); + + $output->clear(); + $output->write('foo'); + $this->assertEquals('foo', $output->output, '->write() do nothing when a style does not exist'); + + $output->clear(); + $output->writeln('foo'); + $this->assertEquals("foo\n", $output->output, '->writeln() do nothing when a style does not exist'); + } + + /** + * @dataProvider verbosityProvider + */ + public function testWriteWithVerbosityOption($verbosity, $expected, $msg) + { + $output = new TestOutput(); + + $output->setVerbosity($verbosity); + $output->clear(); + $output->write('1', false); + $output->write('2', false, Output::VERBOSITY_QUIET); + $output->write('3', false, Output::VERBOSITY_NORMAL); + $output->write('4', false, Output::VERBOSITY_VERBOSE); + $output->write('5', false, Output::VERBOSITY_VERY_VERBOSE); + $output->write('6', false, Output::VERBOSITY_DEBUG); + $this->assertEquals($expected, $output->output, $msg); + } + + public function verbosityProvider() + { + return array( + array(Output::VERBOSITY_QUIET, '2', '->write() in QUIET mode only outputs when an explicit QUIET verbosity is passed'), + array(Output::VERBOSITY_NORMAL, '123', '->write() in NORMAL mode outputs anything below an explicit VERBOSE verbosity'), + array(Output::VERBOSITY_VERBOSE, '1234', '->write() in VERBOSE mode outputs anything below an explicit VERY_VERBOSE verbosity'), + array(Output::VERBOSITY_VERY_VERBOSE, '12345', '->write() in VERY_VERBOSE mode outputs anything below an explicit DEBUG verbosity'), + array(Output::VERBOSITY_DEBUG, '123456', '->write() in DEBUG mode outputs everything'), + ); + } +} + +class TestOutput extends Output +{ + public $output = ''; + + public function clear() + { + $this->output = ''; + } + + protected function doWrite($message, $newline) + { + $this->output .= $message.($newline ? "\n" : ''); + } +} diff --git a/vendor/symfony/console/Tests/Output/StreamOutputTest.php b/vendor/symfony/console/Tests/Output/StreamOutputTest.php new file mode 100644 index 000000000..780b5681f --- /dev/null +++ b/vendor/symfony/console/Tests/Output/StreamOutputTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Output; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Output\StreamOutput; + +class StreamOutputTest extends TestCase +{ + protected $stream; + + protected function setUp() + { + $this->stream = fopen('php://memory', 'a', false); + } + + protected function tearDown() + { + $this->stream = null; + } + + public function testConstructor() + { + $output = new StreamOutput($this->stream, Output::VERBOSITY_QUIET, true); + $this->assertEquals(Output::VERBOSITY_QUIET, $output->getVerbosity(), '__construct() takes the verbosity as its first argument'); + $this->assertTrue($output->isDecorated(), '__construct() takes the decorated flag as its second argument'); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The StreamOutput class needs a stream as its first argument. + */ + public function testStreamIsRequired() + { + new StreamOutput('foo'); + } + + public function testGetStream() + { + $output = new StreamOutput($this->stream); + $this->assertEquals($this->stream, $output->getStream(), '->getStream() returns the current stream'); + } + + public function testDoWrite() + { + $output = new StreamOutput($this->stream); + $output->writeln('foo'); + rewind($output->getStream()); + $this->assertEquals('foo'.PHP_EOL, stream_get_contents($output->getStream()), '->doWrite() writes to the stream'); + } +} diff --git a/vendor/symfony/console/Tests/Style/SymfonyStyleTest.php b/vendor/symfony/console/Tests/Style/SymfonyStyleTest.php new file mode 100644 index 000000000..ee9b09f8f --- /dev/null +++ b/vendor/symfony/console/Tests/Style/SymfonyStyleTest.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Style; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Console\Tester\CommandTester; + +class SymfonyStyleTest extends TestCase +{ + /** @var Command */ + protected $command; + /** @var CommandTester */ + protected $tester; + + protected function setUp() + { + $this->command = new Command('sfstyle'); + $this->tester = new CommandTester($this->command); + } + + protected function tearDown() + { + $this->command = null; + $this->tester = null; + } + + /** + * @dataProvider inputCommandToOutputFilesProvider + */ + public function testOutputs($inputCommandFilepath, $outputFilepath) + { + $code = require $inputCommandFilepath; + $this->command->setCode($code); + $this->tester->execute(array(), array('interactive' => false, 'decorated' => false)); + $this->assertStringEqualsFile($outputFilepath, $this->tester->getDisplay(true)); + } + + public function inputCommandToOutputFilesProvider() + { + $baseDir = __DIR__.'/../Fixtures/Style/SymfonyStyle'; + + return array_map(null, glob($baseDir.'/command/command_*.php'), glob($baseDir.'/output/output_*.txt')); + } +} + +/** + * Use this class in tests to force the line length + * and ensure a consistent output for expectations. + */ +class SymfonyStyleWithForcedLineLength extends SymfonyStyle +{ + public function __construct(InputInterface $input, OutputInterface $output) + { + parent::__construct($input, $output); + + $ref = new \ReflectionProperty(get_parent_class($this), 'lineLength'); + $ref->setAccessible(true); + $ref->setValue($this, 120); + } +} diff --git a/vendor/symfony/console/Tests/Tester/ApplicationTesterTest.php b/vendor/symfony/console/Tests/Tester/ApplicationTesterTest.php new file mode 100644 index 000000000..57e7136d5 --- /dev/null +++ b/vendor/symfony/console/Tests/Tester/ApplicationTesterTest.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Tester; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Tester\ApplicationTester; + +class ApplicationTesterTest extends TestCase +{ + protected $application; + protected $tester; + + protected function setUp() + { + $this->application = new Application(); + $this->application->setAutoExit(false); + $this->application->register('foo') + ->addArgument('foo') + ->setCode(function ($input, $output) { $output->writeln('foo'); }) + ; + + $this->tester = new ApplicationTester($this->application); + $this->tester->run(array('command' => 'foo', 'foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE)); + } + + protected function tearDown() + { + $this->application = null; + $this->tester = null; + } + + public function testRun() + { + $this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option'); + $this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option'); + $this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option'); + } + + public function testGetInput() + { + $this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance'); + } + + public function testGetOutput() + { + rewind($this->tester->getOutput()->getStream()); + $this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance'); + } + + public function testGetDisplay() + { + $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution'); + } + + public function testGetStatusCode() + { + $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code'); + } +} diff --git a/vendor/symfony/console/Tests/Tester/CommandTesterTest.php b/vendor/symfony/console/Tests/Tester/CommandTesterTest.php new file mode 100644 index 000000000..8d4e05a76 --- /dev/null +++ b/vendor/symfony/console/Tests/Tester/CommandTesterTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Tester; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Tester\CommandTester; + +class CommandTesterTest extends TestCase +{ + protected $command; + protected $tester; + + protected function setUp() + { + $this->command = new Command('foo'); + $this->command->addArgument('command'); + $this->command->addArgument('foo'); + $this->command->setCode(function ($input, $output) { $output->writeln('foo'); }); + + $this->tester = new CommandTester($this->command); + $this->tester->execute(array('foo' => 'bar'), array('interactive' => false, 'decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE)); + } + + protected function tearDown() + { + $this->command = null; + $this->tester = null; + } + + public function testExecute() + { + $this->assertFalse($this->tester->getInput()->isInteractive(), '->execute() takes an interactive option'); + $this->assertFalse($this->tester->getOutput()->isDecorated(), '->execute() takes a decorated option'); + $this->assertEquals(Output::VERBOSITY_VERBOSE, $this->tester->getOutput()->getVerbosity(), '->execute() takes a verbosity option'); + } + + public function testGetInput() + { + $this->assertEquals('bar', $this->tester->getInput()->getArgument('foo'), '->getInput() returns the current input instance'); + } + + public function testGetOutput() + { + rewind($this->tester->getOutput()->getStream()); + $this->assertEquals('foo'.PHP_EOL, stream_get_contents($this->tester->getOutput()->getStream()), '->getOutput() returns the current output instance'); + } + + public function testGetDisplay() + { + $this->assertEquals('foo'.PHP_EOL, $this->tester->getDisplay(), '->getDisplay() returns the display of the last execution'); + } + + public function testGetStatusCode() + { + $this->assertSame(0, $this->tester->getStatusCode(), '->getStatusCode() returns the status code'); + } + + public function testCommandFromApplication() + { + $application = new Application(); + $application->setAutoExit(false); + + $command = new Command('foo'); + $command->setCode(function ($input, $output) { $output->writeln('foo'); }); + + $application->add($command); + + $tester = new CommandTester($application->find('foo')); + + // check that there is no need to pass the command name here + $this->assertEquals(0, $tester->execute(array())); + } +} diff --git a/vendor/symfony/console/phpunit.xml.dist b/vendor/symfony/console/phpunit.xml.dist index 8c09554f8..32569d63c 100644 --- a/vendor/symfony/console/phpunit.xml.dist +++ b/vendor/symfony/console/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/css-selector/Parser/Reader.php b/vendor/symfony/css-selector/Parser/Reader.php index 79ea34f9d..546730b8f 100644 --- a/vendor/symfony/css-selector/Parser/Reader.php +++ b/vendor/symfony/css-selector/Parser/Reader.php @@ -97,7 +97,7 @@ class Reader /** * @param string $pattern * - * @return bool + * @return array|false */ public function findPattern($pattern) { diff --git a/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php b/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php index 09e6469e7..b0c78fa81 100644 --- a/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php @@ -72,7 +72,7 @@ class NodeExtension extends AbstractExtension */ public function hasFlag($flag) { - return $this->flags & $flag; + return (bool) ($this->flags & $flag); } /** diff --git a/vendor/symfony/css-selector/phpunit.xml.dist b/vendor/symfony/css-selector/phpunit.xml.dist index 14a320c87..65ff1827a 100644 --- a/vendor/symfony/css-selector/phpunit.xml.dist +++ b/vendor/symfony/css-selector/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/debug/DebugClassLoader.php b/vendor/symfony/debug/DebugClassLoader.php index 12d379aa7..a6a5cd7af 100644 --- a/vendor/symfony/debug/DebugClassLoader.php +++ b/vendor/symfony/debug/DebugClassLoader.php @@ -186,7 +186,7 @@ class DebugClassLoader $exists = class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false)); - if ('\\' === $class[0]) { + if ($class && '\\' === $class[0]) { $class = substr($class, 1); } diff --git a/vendor/symfony/debug/ErrorHandler.php b/vendor/symfony/debug/ErrorHandler.php index 1b7201171..ae3c2ff8f 100644 --- a/vendor/symfony/debug/ErrorHandler.php +++ b/vendor/symfony/debug/ErrorHandler.php @@ -103,6 +103,7 @@ class ErrorHandler private static $stackedErrors = array(); private static $stackedErrorLevels = array(); private static $toStringException = null; + private static $exitCode = 0; /** * Same init value as thrownErrors. @@ -432,7 +433,7 @@ class ErrorHandler $throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line); } - if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) { + if (\PHP_VERSION_ID <= 50407 && (\PHP_VERSION_ID >= 50400 || \PHP_VERSION_ID <= 50317)) { // Exceptions thrown from error handlers are sometimes not caught by the exception // handler and shutdown handlers are bypassed before 5.4.8/5.3.18. // We temporarily re-enable display_errors to prevent any blank page related to this bug. @@ -547,6 +548,9 @@ class ErrorHandler */ public function handleException($exception, array $error = null) { + if (null === $error) { + self::$exitCode = 255; + } if (!$exception instanceof \Exception) { $exception = new FatalThrowableError($exception); } @@ -632,7 +636,7 @@ class ErrorHandler return; } - if (null === $error) { + if ($exit = null === $error) { $error = error_get_last(); } @@ -656,15 +660,21 @@ class ErrorHandler } else { $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace); } - } elseif (!isset($exception)) { - return; } try { - $handler->handleException($exception, $error); + if (isset($exception)) { + self::$exitCode = 255; + $handler->handleException($exception, $error); + } } catch (FatalErrorException $e) { // Ignore this re-throw } + + if ($exit && self::$exitCode) { + $exitCode = self::$exitCode; + register_shutdown_function('register_shutdown_function', function () use ($exitCode) { exit($exitCode); }); + } } /** diff --git a/vendor/symfony/debug/ExceptionHandler.php b/vendor/symfony/debug/ExceptionHandler.php index 3cdc09213..0ac644ef0 100644 --- a/vendor/symfony/debug/ExceptionHandler.php +++ b/vendor/symfony/debug/ExceptionHandler.php @@ -457,7 +457,7 @@ EOF; { @trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED); - return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8'); + return htmlspecialchars($str, ENT_QUOTES | (\PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8'); } /** @@ -465,7 +465,7 @@ EOF; */ private function escapeHtml($str) { - return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset); + return htmlspecialchars($str, ENT_QUOTES | (\PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset); } /** diff --git a/vendor/symfony/debug/Tests/DebugClassLoaderTest.php b/vendor/symfony/debug/Tests/DebugClassLoaderTest.php new file mode 100644 index 000000000..196b92c88 --- /dev/null +++ b/vendor/symfony/debug/Tests/DebugClassLoaderTest.php @@ -0,0 +1,320 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Debug\DebugClassLoader; +use Symfony\Component\Debug\ErrorHandler; + +class DebugClassLoaderTest extends TestCase +{ + /** + * @var int Error reporting level before running tests + */ + private $errorReporting; + + private $loader; + + protected function setUp() + { + $this->errorReporting = error_reporting(E_ALL | E_STRICT); + $this->loader = new ClassLoader(); + spl_autoload_register(array($this->loader, 'loadClass'), true, true); + DebugClassLoader::enable(); + } + + protected function tearDown() + { + DebugClassLoader::disable(); + spl_autoload_unregister(array($this->loader, 'loadClass')); + error_reporting($this->errorReporting); + } + + public function testIdempotence() + { + DebugClassLoader::enable(); + + $functions = spl_autoload_functions(); + foreach ($functions as $function) { + if (is_array($function) && $function[0] instanceof DebugClassLoader) { + $reflClass = new \ReflectionClass($function[0]); + $reflProp = $reflClass->getProperty('classLoader'); + $reflProp->setAccessible(true); + + $this->assertNotInstanceOf('Symfony\Component\Debug\DebugClassLoader', $reflProp->getValue($function[0])); + + return; + } + } + + $this->fail('DebugClassLoader did not register'); + } + + public function testUnsilencing() + { + if (\PHP_VERSION_ID >= 70000) { + $this->markTestSkipped('PHP7 throws exceptions, unsilencing is not required anymore.'); + } + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM is not handled in this test case.'); + } + + ob_start(); + + $this->iniSet('log_errors', 0); + $this->iniSet('display_errors', 1); + + // See below: this will fail with parse error + // but this should not be @-silenced. + @class_exists(__NAMESPACE__.'\TestingUnsilencing', true); + + $output = ob_get_clean(); + + $this->assertStringMatchesFormat('%aParse error%a', $output); + } + + public function testStacking() + { + // the ContextErrorException must not be loaded to test the workaround + // for https://bugs.php.net/65322. + if (class_exists('Symfony\Component\Debug\Exception\ContextErrorException', false)) { + $this->markTestSkipped('The ContextErrorException class is already loaded.'); + } + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM is not handled in this test case.'); + } + + ErrorHandler::register(); + + try { + // Trigger autoloading + E_STRICT at compile time + // which in turn triggers $errorHandler->handle() + // that again triggers autoloading for ContextErrorException. + // Error stacking works around the bug above and everything is fine. + + eval(' + namespace '.__NAMESPACE__.'; + class ChildTestingStacking extends TestingStacking { function foo($bar) {} } + '); + $this->fail('ContextErrorException expected'); + } catch (\ErrorException $exception) { + // if an exception is thrown, the test passed + restore_error_handler(); + restore_exception_handler(); + $this->assertStringStartsWith(__FILE__, $exception->getFile()); + if (\PHP_VERSION_ID < 70000) { + $this->assertRegExp('/^Runtime Notice: Declaration/', $exception->getMessage()); + $this->assertEquals(E_STRICT, $exception->getSeverity()); + } else { + $this->assertRegExp('/^Warning: Declaration/', $exception->getMessage()); + $this->assertEquals(E_WARNING, $exception->getSeverity()); + } + } catch (\Exception $exception) { + restore_error_handler(); + restore_exception_handler(); + + throw $exception; + } + } + + /** + * @expectedException \RuntimeException + */ + public function testNameCaseMismatch() + { + class_exists(__NAMESPACE__.'\TestingCaseMismatch', true); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Case mismatch between class and real file names + */ + public function testFileCaseMismatch() + { + if (!file_exists(__DIR__.'/Fixtures/CaseMismatch.php')) { + $this->markTestSkipped('Can only be run on case insensitive filesystems'); + } + + class_exists(__NAMESPACE__.'\Fixtures\CaseMismatch', true); + } + + /** + * @expectedException \RuntimeException + */ + public function testPsr4CaseMismatch() + { + class_exists(__NAMESPACE__.'\Fixtures\Psr4CaseMismatch', true); + } + + public function testNotPsr0() + { + $this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\NotPSR0', true)); + } + + public function testNotPsr0Bis() + { + $this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\NotPSR0bis', true)); + } + + public function testClassAlias() + { + $this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\ClassAlias', true)); + } + + /** + * @dataProvider provideDeprecatedSuper + */ + public function testDeprecatedSuper($class, $super, $type) + { + set_error_handler(function () { return false; }); + $e = error_reporting(0); + trigger_error('', E_USER_DEPRECATED); + + class_exists('Test\\'.__NAMESPACE__.'\\'.$class, true); + + error_reporting($e); + restore_error_handler(); + + $lastError = error_get_last(); + unset($lastError['file'], $lastError['line']); + + $xError = array( + 'type' => E_USER_DEPRECATED, + 'message' => 'The Test\Symfony\Component\Debug\Tests\\'.$class.' class '.$type.' Symfony\Component\Debug\Tests\Fixtures\\'.$super.' that is deprecated but this is a test deprecation notice.', + ); + + $this->assertSame($xError, $lastError); + } + + public function provideDeprecatedSuper() + { + return array( + array('DeprecatedInterfaceClass', 'DeprecatedInterface', 'implements'), + array('DeprecatedParentClass', 'DeprecatedClass', 'extends'), + ); + } + + public function testInterfaceExtendsDeprecatedInterface() + { + set_error_handler(function () { return false; }); + $e = error_reporting(0); + trigger_error('', E_USER_NOTICE); + + class_exists('Test\\'.__NAMESPACE__.'\\NonDeprecatedInterfaceClass', true); + + error_reporting($e); + restore_error_handler(); + + $lastError = error_get_last(); + unset($lastError['file'], $lastError['line']); + + $xError = array( + 'type' => E_USER_NOTICE, + 'message' => '', + ); + + $this->assertSame($xError, $lastError); + } + + public function testDeprecatedSuperInSameNamespace() + { + set_error_handler(function () { return false; }); + $e = error_reporting(0); + trigger_error('', E_USER_NOTICE); + + class_exists('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent', true); + + error_reporting($e); + restore_error_handler(); + + $lastError = error_get_last(); + unset($lastError['file'], $lastError['line']); + + $xError = array( + 'type' => E_USER_NOTICE, + 'message' => '', + ); + + $this->assertSame($xError, $lastError); + } + + public function testReservedForPhp7() + { + if (\PHP_VERSION_ID >= 70000) { + $this->markTestSkipped('PHP7 already prevents using reserved names.'); + } + + set_error_handler(function () { return false; }); + $e = error_reporting(0); + trigger_error('', E_USER_NOTICE); + + class_exists('Test\\'.__NAMESPACE__.'\\Float', true); + + error_reporting($e); + restore_error_handler(); + + $lastError = error_get_last(); + unset($lastError['file'], $lastError['line']); + + $xError = array( + 'type' => E_USER_DEPRECATED, + 'message' => 'Test\Symfony\Component\Debug\Tests\Float uses a reserved class name (Float) that will break on PHP 7 and higher', + ); + + $this->assertSame($xError, $lastError); + } +} + +class ClassLoader +{ + public function loadClass($class) + { + } + + public function getClassMap() + { + return array(__NAMESPACE__.'\Fixtures\NotPSR0bis' => __DIR__.'/Fixtures/notPsr0Bis.php'); + } + + public function findFile($class) + { + $fixtureDir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR; + + if (__NAMESPACE__.'\TestingUnsilencing' === $class) { + eval('-- parse error --'); + } elseif (__NAMESPACE__.'\TestingStacking' === $class) { + eval('namespace '.__NAMESPACE__.'; class TestingStacking { function foo() {} }'); + } elseif (__NAMESPACE__.'\TestingCaseMismatch' === $class) { + eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}'); + } elseif (__NAMESPACE__.'\Fixtures\CaseMismatch' === $class) { + return $fixtureDir.'CaseMismatch.php'; + } elseif (__NAMESPACE__.'\Fixtures\Psr4CaseMismatch' === $class) { + return $fixtureDir.'psr4'.DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php'; + } elseif (__NAMESPACE__.'\Fixtures\NotPSR0' === $class) { + return $fixtureDir.'reallyNotPsr0.php'; + } elseif (__NAMESPACE__.'\Fixtures\NotPSR0bis' === $class) { + return $fixtureDir.'notPsr0Bis.php'; + } elseif (__NAMESPACE__.'\Fixtures\DeprecatedInterface' === $class) { + return $fixtureDir.'DeprecatedInterface.php'; + } elseif ('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent' === $class) { + eval('namespace Symfony\Bridge\Debug\Tests\Fixtures; class ExtendsDeprecatedParent extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}'); + } elseif ('Test\\'.__NAMESPACE__.'\DeprecatedParentClass' === $class) { + eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedParentClass extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}'); + } elseif ('Test\\'.__NAMESPACE__.'\DeprecatedInterfaceClass' === $class) { + eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\DeprecatedInterface {}'); + } elseif ('Test\\'.__NAMESPACE__.'\NonDeprecatedInterfaceClass' === $class) { + eval('namespace Test\\'.__NAMESPACE__.'; class NonDeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\NonDeprecatedInterface {}'); + } elseif ('Test\\'.__NAMESPACE__.'\Float' === $class) { + eval('namespace Test\\'.__NAMESPACE__.'; class Float {}'); + } + } +} diff --git a/vendor/symfony/debug/Tests/ErrorHandlerTest.php b/vendor/symfony/debug/Tests/ErrorHandlerTest.php new file mode 100644 index 000000000..001a64d9b --- /dev/null +++ b/vendor/symfony/debug/Tests/ErrorHandlerTest.php @@ -0,0 +1,593 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests; + +use PHPUnit\Framework\TestCase; +use Psr\Log\LogLevel; +use Symfony\Component\Debug\ErrorHandler; +use Symfony\Component\Debug\BufferingLogger; +use Symfony\Component\Debug\Exception\ContextErrorException; + +/** + * ErrorHandlerTest. + * + * @author Robert Schönthal + * @author Nicolas Grekas + */ +class ErrorHandlerTest extends TestCase +{ + public function testRegister() + { + $handler = ErrorHandler::register(); + + try { + $this->assertInstanceOf('Symfony\Component\Debug\ErrorHandler', $handler); + $this->assertSame($handler, ErrorHandler::register()); + + $newHandler = new ErrorHandler(); + + $this->assertSame($newHandler, ErrorHandler::register($newHandler, false)); + $h = set_error_handler('var_dump'); + restore_error_handler(); + $this->assertSame(array($handler, 'handleError'), $h); + + try { + $this->assertSame($newHandler, ErrorHandler::register($newHandler, true)); + $h = set_error_handler('var_dump'); + restore_error_handler(); + $this->assertSame(array($newHandler, 'handleError'), $h); + } catch (\Exception $e) { + } + + restore_error_handler(); + restore_exception_handler(); + + if (isset($e)) { + throw $e; + } + } catch (\Exception $e) { + } + + restore_error_handler(); + restore_exception_handler(); + + if (isset($e)) { + throw $e; + } + } + + public function testNotice() + { + ErrorHandler::register(); + + try { + self::triggerNotice($this); + $this->fail('ContextErrorException expected'); + } catch (ContextErrorException $exception) { + // if an exception is thrown, the test passed + restore_error_handler(); + restore_exception_handler(); + + $this->assertEquals(E_NOTICE, $exception->getSeverity()); + $this->assertEquals(__FILE__, $exception->getFile()); + $this->assertRegExp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage()); + $this->assertArrayHasKey('foobar', $exception->getContext()); + + $trace = $exception->getTrace(); + $this->assertEquals(__FILE__, $trace[0]['file']); + $this->assertEquals('Symfony\Component\Debug\ErrorHandler', $trace[0]['class']); + $this->assertEquals('handleError', $trace[0]['function']); + $this->assertEquals('->', $trace[0]['type']); + + $this->assertEquals(__FILE__, $trace[1]['file']); + $this->assertEquals(__CLASS__, $trace[1]['class']); + $this->assertEquals('triggerNotice', $trace[1]['function']); + $this->assertEquals('::', $trace[1]['type']); + + $this->assertEquals(__FILE__, $trace[1]['file']); + $this->assertEquals(__CLASS__, $trace[2]['class']); + $this->assertEquals(__FUNCTION__, $trace[2]['function']); + $this->assertEquals('->', $trace[2]['type']); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + // dummy function to test trace in error handler. + private static function triggerNotice($that) + { + // dummy variable to check for in error handler. + $foobar = 123; + $that->assertSame('', $foo.$foo.$bar); + } + + public function testConstruct() + { + try { + $handler = ErrorHandler::register(); + $handler->throwAt(3, true); + $this->assertEquals(3 | E_RECOVERABLE_ERROR | E_USER_ERROR, $handler->throwAt(0)); + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + public function testDefaultLogger() + { + try { + $handler = ErrorHandler::register(); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $handler->setDefaultLogger($logger, E_NOTICE); + $handler->setDefaultLogger($logger, array(E_USER_NOTICE => LogLevel::CRITICAL)); + + $loggers = array( + E_DEPRECATED => array(null, LogLevel::INFO), + E_USER_DEPRECATED => array(null, LogLevel::INFO), + E_NOTICE => array($logger, LogLevel::WARNING), + E_USER_NOTICE => array($logger, LogLevel::CRITICAL), + E_STRICT => array(null, LogLevel::WARNING), + E_WARNING => array(null, LogLevel::WARNING), + E_USER_WARNING => array(null, LogLevel::WARNING), + E_COMPILE_WARNING => array(null, LogLevel::WARNING), + E_CORE_WARNING => array(null, LogLevel::WARNING), + E_USER_ERROR => array(null, LogLevel::CRITICAL), + E_RECOVERABLE_ERROR => array(null, LogLevel::CRITICAL), + E_COMPILE_ERROR => array(null, LogLevel::CRITICAL), + E_PARSE => array(null, LogLevel::CRITICAL), + E_ERROR => array(null, LogLevel::CRITICAL), + E_CORE_ERROR => array(null, LogLevel::CRITICAL), + ); + $this->assertSame($loggers, $handler->setLoggers(array())); + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + public function testHandleError() + { + try { + $handler = ErrorHandler::register(); + $handler->throwAt(0, true); + $this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, array())); + + restore_error_handler(); + restore_exception_handler(); + + $handler = ErrorHandler::register(); + $handler->throwAt(3, true); + $this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, array())); + + restore_error_handler(); + restore_exception_handler(); + + $handler = ErrorHandler::register(); + $handler->throwAt(3, true); + try { + $handler->handleError(4, 'foo', 'foo.php', 12, array()); + } catch (\ErrorException $e) { + $this->assertSame('Parse Error: foo', $e->getMessage()); + $this->assertSame(4, $e->getSeverity()); + $this->assertSame('foo.php', $e->getFile()); + $this->assertSame(12, $e->getLine()); + } + + restore_error_handler(); + restore_exception_handler(); + + $handler = ErrorHandler::register(); + $handler->throwAt(E_USER_DEPRECATED, true); + $this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array())); + + restore_error_handler(); + restore_exception_handler(); + + $handler = ErrorHandler::register(); + $handler->throwAt(E_DEPRECATED, true); + $this->assertFalse($handler->handleError(E_DEPRECATED, 'foo', 'foo.php', 12, array())); + + restore_error_handler(); + restore_exception_handler(); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $that = $this; + $warnArgCheck = function ($logLevel, $message, $context) use ($that) { + $that->assertEquals('info', $logLevel); + $that->assertEquals('foo', $message); + $that->assertArrayHasKey('type', $context); + $that->assertEquals($context['type'], E_USER_DEPRECATED); + $that->assertArrayHasKey('stack', $context); + $that->assertInternalType('array', $context['stack']); + }; + + $logger + ->expects($this->once()) + ->method('log') + ->will($this->returnCallback($warnArgCheck)) + ; + + $handler = ErrorHandler::register(); + $handler->setDefaultLogger($logger, E_USER_DEPRECATED); + $this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, array())); + + restore_error_handler(); + restore_exception_handler(); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $that = $this; + $logArgCheck = function ($level, $message, $context) use ($that) { + $that->assertEquals('Undefined variable: undefVar', $message); + $that->assertArrayHasKey('type', $context); + $that->assertEquals($context['type'], E_NOTICE); + }; + + $logger + ->expects($this->once()) + ->method('log') + ->will($this->returnCallback($logArgCheck)) + ; + + $handler = ErrorHandler::register(); + $handler->setDefaultLogger($logger, E_NOTICE); + $handler->screamAt(E_NOTICE); + unset($undefVar); + @$undefVar++; + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + public function testHandleUserError() + { + try { + $handler = ErrorHandler::register(); + $handler->throwAt(0, true); + + $e = null; + $x = new \Exception('Foo'); + + try { + $f = new Fixtures\ToStringThrower($x); + $f .= ''; // Trigger $f->__toString() + } catch (\Exception $e) { + } + + $this->assertSame($x, $e); + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + public function testHandleDeprecation() + { + $that = $this; + $logArgCheck = function ($level, $message, $context) use ($that) { + $that->assertEquals(LogLevel::INFO, $level); + $that->assertArrayHasKey('level', $context); + $that->assertEquals(E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED, $context['level']); + $that->assertArrayHasKey('stack', $context); + }; + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $logger + ->expects($this->once()) + ->method('log') + ->will($this->returnCallback($logArgCheck)) + ; + + $handler = new ErrorHandler(); + $handler->setDefaultLogger($logger); + @$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, array()); + } + + public function testHandleException() + { + try { + $handler = ErrorHandler::register(); + + $exception = new \Exception('foo'); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $that = $this; + $logArgCheck = function ($level, $message, $context) use ($that) { + $that->assertEquals('Uncaught Exception: foo', $message); + $that->assertArrayHasKey('type', $context); + $that->assertEquals($context['type'], E_ERROR); + }; + + $logger + ->expects($this->exactly(2)) + ->method('log') + ->will($this->returnCallback($logArgCheck)) + ; + + $handler->setDefaultLogger($logger, E_ERROR); + + try { + $handler->handleException($exception); + $this->fail('Exception expected'); + } catch (\Exception $e) { + $this->assertSame($exception, $e); + } + + $that = $this; + $handler->setExceptionHandler(function ($e) use ($exception, $that) { + $that->assertSame($exception, $e); + }); + + $handler->handleException($exception); + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + public function testErrorStacking() + { + try { + $handler = ErrorHandler::register(); + $handler->screamAt(E_USER_WARNING); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $logger + ->expects($this->exactly(2)) + ->method('log') + ->withConsecutive( + array($this->equalTo(LogLevel::WARNING), $this->equalTo('Dummy log')), + array($this->equalTo(LogLevel::DEBUG), $this->equalTo('Silenced warning')) + ) + ; + + $handler->setDefaultLogger($logger, array(E_USER_WARNING => LogLevel::WARNING)); + + ErrorHandler::stackErrors(); + @trigger_error('Silenced warning', E_USER_WARNING); + $logger->log(LogLevel::WARNING, 'Dummy log'); + ErrorHandler::unstackErrors(); + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + public function testBootstrappingLogger() + { + $bootLogger = new BufferingLogger(); + $handler = new ErrorHandler($bootLogger); + + $loggers = array( + E_DEPRECATED => array($bootLogger, LogLevel::INFO), + E_USER_DEPRECATED => array($bootLogger, LogLevel::INFO), + E_NOTICE => array($bootLogger, LogLevel::WARNING), + E_USER_NOTICE => array($bootLogger, LogLevel::WARNING), + E_STRICT => array($bootLogger, LogLevel::WARNING), + E_WARNING => array($bootLogger, LogLevel::WARNING), + E_USER_WARNING => array($bootLogger, LogLevel::WARNING), + E_COMPILE_WARNING => array($bootLogger, LogLevel::WARNING), + E_CORE_WARNING => array($bootLogger, LogLevel::WARNING), + E_USER_ERROR => array($bootLogger, LogLevel::CRITICAL), + E_RECOVERABLE_ERROR => array($bootLogger, LogLevel::CRITICAL), + E_COMPILE_ERROR => array($bootLogger, LogLevel::CRITICAL), + E_PARSE => array($bootLogger, LogLevel::CRITICAL), + E_ERROR => array($bootLogger, LogLevel::CRITICAL), + E_CORE_ERROR => array($bootLogger, LogLevel::CRITICAL), + ); + + $this->assertSame($loggers, $handler->setLoggers(array())); + + $handler->handleError(E_DEPRECATED, 'Foo message', __FILE__, 123, array()); + $expectedLog = array(LogLevel::INFO, 'Foo message', array('type' => E_DEPRECATED, 'file' => __FILE__, 'line' => 123, 'level' => error_reporting())); + + $logs = $bootLogger->cleanLogs(); + unset($logs[0][2]['stack']); + + $this->assertSame(array($expectedLog), $logs); + + $bootLogger->log($expectedLog[0], $expectedLog[1], $expectedLog[2]); + + $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $mockLogger->expects($this->once()) + ->method('log') + ->with(LogLevel::WARNING, 'Foo message', $expectedLog[2]); + + $handler->setLoggers(array(E_DEPRECATED => array($mockLogger, LogLevel::WARNING))); + } + + public function testHandleFatalError() + { + try { + $handler = ErrorHandler::register(); + + $error = array( + 'type' => E_PARSE, + 'message' => 'foo', + 'file' => 'bar', + 'line' => 123, + ); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $that = $this; + $logArgCheck = function ($level, $message, $context) use ($that) { + $that->assertEquals('Fatal Parse Error: foo', $message); + $that->assertArrayHasKey('type', $context); + $that->assertEquals($context['type'], E_PARSE); + }; + + $logger + ->expects($this->once()) + ->method('log') + ->will($this->returnCallback($logArgCheck)) + ; + + $handler->setDefaultLogger($logger, E_PARSE); + + $handler->handleFatalError($error); + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + /** + * @requires PHP 7 + */ + public function testHandleErrorException() + { + $exception = new \Error("Class 'Foo' not found"); + + $handler = new ErrorHandler(); + $handler->setExceptionHandler(function () use (&$args) { + $args = func_get_args(); + }); + + $handler->handleException($exception); + + $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $args[0]); + $this->assertStringStartsWith("Attempted to load class \"Foo\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage()); + } + + public function testHandleFatalErrorOnHHVM() + { + try { + $handler = ErrorHandler::register(); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $logger + ->expects($this->once()) + ->method('log') + ->with( + $this->equalTo(LogLevel::CRITICAL), + $this->equalTo('Fatal Error: foo'), + $this->equalTo(array( + 'type' => 1, + 'file' => 'bar', + 'line' => 123, + 'level' => -1, + 'stack' => array(456), + )) + ) + ; + + $handler->setDefaultLogger($logger, E_ERROR); + + $error = array( + 'type' => E_ERROR + 0x1000000, // This error level is used by HHVM for fatal errors + 'message' => 'foo', + 'file' => 'bar', + 'line' => 123, + 'context' => array(123), + 'backtrace' => array(456), + ); + + call_user_func_array(array($handler, 'handleError'), $error); + $handler->handleFatalError($error); + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + /** + * @group legacy + */ + public function testLegacyInterface() + { + try { + $handler = ErrorHandler::register(0); + $this->assertFalse($handler->handle(0, 'foo', 'foo.php', 12, array())); + + restore_error_handler(); + restore_exception_handler(); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $that = $this; + $logArgCheck = function ($level, $message, $context) use ($that) { + $that->assertEquals('Undefined variable: undefVar', $message); + $that->assertArrayHasKey('type', $context); + $that->assertEquals($context['type'], E_NOTICE); + }; + + $logger + ->expects($this->once()) + ->method('log') + ->will($this->returnCallback($logArgCheck)) + ; + + $handler = ErrorHandler::register(E_NOTICE); + @$handler->setLogger($logger, 'scream'); + unset($undefVar); + @$undefVar++; + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } +} diff --git a/vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.php b/vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.php new file mode 100644 index 000000000..ae01e9cb0 --- /dev/null +++ b/vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.php @@ -0,0 +1,271 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests\Exception; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Debug\Exception\FlattenException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; +use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException; +use Symfony\Component\HttpKernel\Exception\ConflictHttpException; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\GoneHttpException; +use Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException; +use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException; +use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException; +use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; +use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; +use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException; + +class FlattenExceptionTest extends TestCase +{ + public function testStatusCode() + { + $flattened = FlattenException::create(new \RuntimeException(), 403); + $this->assertEquals('403', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new \RuntimeException()); + $this->assertEquals('500', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new NotFoundHttpException()); + $this->assertEquals('404', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"')); + $this->assertEquals('401', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new BadRequestHttpException()); + $this->assertEquals('400', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new NotAcceptableHttpException()); + $this->assertEquals('406', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new ConflictHttpException()); + $this->assertEquals('409', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new MethodNotAllowedHttpException(array('POST'))); + $this->assertEquals('405', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new AccessDeniedHttpException()); + $this->assertEquals('403', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new GoneHttpException()); + $this->assertEquals('410', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new LengthRequiredHttpException()); + $this->assertEquals('411', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new PreconditionFailedHttpException()); + $this->assertEquals('412', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new PreconditionRequiredHttpException()); + $this->assertEquals('428', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new ServiceUnavailableHttpException()); + $this->assertEquals('503', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new TooManyRequestsHttpException()); + $this->assertEquals('429', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new UnsupportedMediaTypeHttpException()); + $this->assertEquals('415', $flattened->getStatusCode()); + } + + public function testHeadersForHttpException() + { + $flattened = FlattenException::create(new MethodNotAllowedHttpException(array('POST'))); + $this->assertEquals(array('Allow' => 'POST'), $flattened->getHeaders()); + + $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"')); + $this->assertEquals(array('WWW-Authenticate' => 'Basic realm="My Realm"'), $flattened->getHeaders()); + + $flattened = FlattenException::create(new ServiceUnavailableHttpException('Fri, 31 Dec 1999 23:59:59 GMT')); + $this->assertEquals(array('Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'), $flattened->getHeaders()); + + $flattened = FlattenException::create(new ServiceUnavailableHttpException(120)); + $this->assertEquals(array('Retry-After' => 120), $flattened->getHeaders()); + + $flattened = FlattenException::create(new TooManyRequestsHttpException('Fri, 31 Dec 1999 23:59:59 GMT')); + $this->assertEquals(array('Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'), $flattened->getHeaders()); + + $flattened = FlattenException::create(new TooManyRequestsHttpException(120)); + $this->assertEquals(array('Retry-After' => 120), $flattened->getHeaders()); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testFlattenHttpException(\Exception $exception, $statusCode) + { + $flattened = FlattenException::create($exception); + $flattened2 = FlattenException::create($exception); + + $flattened->setPrevious($flattened2); + + $this->assertEquals($exception->getMessage(), $flattened->getMessage(), 'The message is copied from the original exception.'); + $this->assertEquals($exception->getCode(), $flattened->getCode(), 'The code is copied from the original exception.'); + $this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception'); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testPrevious(\Exception $exception, $statusCode) + { + $flattened = FlattenException::create($exception); + $flattened2 = FlattenException::create($exception); + + $flattened->setPrevious($flattened2); + + $this->assertSame($flattened2, $flattened->getPrevious()); + + $this->assertSame(array($flattened2), $flattened->getAllPrevious()); + } + + /** + * @requires PHP 7.0 + */ + public function testPreviousError() + { + $exception = new \Exception('test', 123, new \ParseError('Oh noes!', 42)); + + $flattened = FlattenException::create($exception)->getPrevious(); + + $this->assertEquals($flattened->getMessage(), 'Parse error: Oh noes!', 'The message is copied from the original exception.'); + $this->assertEquals($flattened->getCode(), 42, 'The code is copied from the original exception.'); + $this->assertEquals($flattened->getClass(), 'Symfony\Component\Debug\Exception\FatalThrowableError', 'The class is set to the class of the original exception'); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testLine(\Exception $exception) + { + $flattened = FlattenException::create($exception); + $this->assertSame($exception->getLine(), $flattened->getLine()); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testFile(\Exception $exception) + { + $flattened = FlattenException::create($exception); + $this->assertSame($exception->getFile(), $flattened->getFile()); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testToArray(\Exception $exception, $statusCode) + { + $flattened = FlattenException::create($exception); + $flattened->setTrace(array(), 'foo.php', 123); + + $this->assertEquals(array( + array( + 'message' => 'test', + 'class' => 'Exception', + 'trace' => array(array( + 'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => 'foo.php', 'line' => 123, + 'args' => array(), + )), + ), + ), $flattened->toArray()); + } + + public function flattenDataProvider() + { + return array( + array(new \Exception('test', 123), 500), + ); + } + + public function testRecursionInArguments() + { + $a = array('foo', array(2, &$a)); + $exception = $this->createException($a); + + $flattened = FlattenException::create($exception); + $trace = $flattened->getTrace(); + $this->assertContains('*DEEP NESTED ARRAY*', serialize($trace)); + } + + public function testTooBigArray() + { + $a = array(); + for ($i = 0; $i < 20; ++$i) { + for ($j = 0; $j < 50; ++$j) { + for ($k = 0; $k < 10; ++$k) { + $a[$i][$j][$k] = 'value'; + } + } + } + $a[20] = 'value'; + $a[21] = 'value1'; + $exception = $this->createException($a); + + $flattened = FlattenException::create($exception); + $trace = $flattened->getTrace(); + $serializeTrace = serialize($trace); + + $this->assertContains('*SKIPPED over 10000 entries*', $serializeTrace); + $this->assertNotContains('*value1*', $serializeTrace); + } + + private function createException($foo) + { + return new \Exception(); + } + + public function testSetTraceIncompleteClass() + { + $flattened = FlattenException::create(new \Exception('test', 123)); + $flattened->setTrace( + array( + array( + 'file' => __FILE__, + 'line' => 123, + 'function' => 'test', + 'args' => array( + unserialize('O:14:"BogusTestClass":0:{}'), + ), + ), + ), + 'foo.php', 123 + ); + + $this->assertEquals(array( + array( + 'message' => 'test', + 'class' => 'Exception', + 'trace' => array( + array( + 'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', + 'file' => 'foo.php', 'line' => 123, + 'args' => array(), + ), + array( + 'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => 'test', + 'file' => __FILE__, 'line' => 123, + 'args' => array( + array( + 'incomplete-object', 'BogusTestClass', + ), + ), + ), + ), + ), + ), $flattened->toArray()); + } +} diff --git a/vendor/symfony/debug/Tests/ExceptionHandlerTest.php b/vendor/symfony/debug/Tests/ExceptionHandlerTest.php new file mode 100644 index 000000000..77cc0b5cb --- /dev/null +++ b/vendor/symfony/debug/Tests/ExceptionHandlerTest.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Debug\ExceptionHandler; +use Symfony\Component\Debug\Exception\OutOfMemoryException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; + +require_once __DIR__.'/HeaderMock.php'; + +class ExceptionHandlerTest extends TestCase +{ + protected function setUp() + { + testHeader(); + } + + protected function tearDown() + { + testHeader(); + } + + public function testDebug() + { + $handler = new ExceptionHandler(false); + + ob_start(); + $handler->sendPhpResponse(new \RuntimeException('Foo')); + $response = ob_get_clean(); + + $this->assertContains('

Whoops, looks like something went wrong.

', $response); + $this->assertNotContains('

', $response); + + $handler = new ExceptionHandler(true); + + ob_start(); + $handler->sendPhpResponse(new \RuntimeException('Foo')); + $response = ob_get_clean(); + + $this->assertContains('

Whoops, looks like something went wrong.

', $response); + $this->assertContains('

', $response); + } + + public function testStatusCode() + { + $handler = new ExceptionHandler(false, 'iso8859-1'); + + ob_start(); + $handler->sendPhpResponse(new NotFoundHttpException('Foo')); + $response = ob_get_clean(); + + $this->assertContains('Sorry, the page you are looking for could not be found.', $response); + + $expectedHeaders = array( + array('HTTP/1.0 404', true, null), + array('Content-Type: text/html; charset=iso8859-1', true, null), + ); + + $this->assertSame($expectedHeaders, testHeader()); + } + + public function testHeaders() + { + $handler = new ExceptionHandler(false, 'iso8859-1'); + + ob_start(); + $handler->sendPhpResponse(new MethodNotAllowedHttpException(array('POST'))); + $response = ob_get_clean(); + + $expectedHeaders = array( + array('HTTP/1.0 405', true, null), + array('Allow: POST', false, null), + array('Content-Type: text/html; charset=iso8859-1', true, null), + ); + + $this->assertSame($expectedHeaders, testHeader()); + } + + public function testNestedExceptions() + { + $handler = new ExceptionHandler(true); + ob_start(); + $handler->sendPhpResponse(new \RuntimeException('Foo', 0, new \RuntimeException('Bar'))); + $response = ob_get_clean(); + + $this->assertStringMatchesFormat('%AFoo%ABar%A', $response); + } + + public function testHandle() + { + $exception = new \Exception('foo'); + + $handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(array('sendPhpResponse'))->getMock(); + $handler + ->expects($this->exactly(2)) + ->method('sendPhpResponse'); + + $handler->handle($exception); + + $that = $this; + $handler->setHandler(function ($e) use ($exception, $that) { + $that->assertSame($exception, $e); + }); + + $handler->handle($exception); + } + + public function testHandleOutOfMemoryException() + { + $exception = new OutOfMemoryException('foo', 0, E_ERROR, __FILE__, __LINE__); + + $handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(array('sendPhpResponse'))->getMock(); + $handler + ->expects($this->once()) + ->method('sendPhpResponse'); + + $that = $this; + $handler->setHandler(function ($e) use ($that) { + $that->fail('OutOfMemoryException should bypass the handler'); + }); + + $handler->handle($exception); + } +} diff --git a/vendor/symfony/debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php b/vendor/symfony/debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php new file mode 100644 index 000000000..0611ed91e --- /dev/null +++ b/vendor/symfony/debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php @@ -0,0 +1,201 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests\FatalErrorHandler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader; +use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader; +use Symfony\Component\Debug\Exception\FatalErrorException; +use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler; +use Symfony\Component\Debug\DebugClassLoader; +use Composer\Autoload\ClassLoader as ComposerClassLoader; + +class ClassNotFoundFatalErrorHandlerTest extends TestCase +{ + public static function setUpBeforeClass() + { + foreach (spl_autoload_functions() as $function) { + if (!is_array($function)) { + continue; + } + + // get class loaders wrapped by DebugClassLoader + if ($function[0] instanceof DebugClassLoader) { + $function = $function[0]->getClassLoader(); + } + + if ($function[0] instanceof ComposerClassLoader) { + $function[0]->add('Symfony_Component_Debug_Tests_Fixtures', dirname(dirname(dirname(dirname(dirname(__DIR__)))))); + break; + } + } + } + + /** + * @dataProvider provideClassNotFoundData + */ + public function testHandleClassNotFound($error, $translatedMessage, $autoloader = null) + { + if ($autoloader) { + // Unregister all autoloaders to ensure the custom provided + // autoloader is the only one to be used during the test run. + $autoloaders = spl_autoload_functions(); + array_map('spl_autoload_unregister', $autoloaders); + spl_autoload_register($autoloader); + } + + $handler = new ClassNotFoundFatalErrorHandler(); + + $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line'])); + + if ($autoloader) { + spl_autoload_unregister($autoloader); + array_map('spl_autoload_register', $autoloaders); + } + + $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception); + $this->assertSame($translatedMessage, $exception->getMessage()); + $this->assertSame($error['type'], $exception->getSeverity()); + $this->assertSame($error['file'], $exception->getFile()); + $this->assertSame($error['line'], $exception->getLine()); + } + + /** + * @group legacy + */ + public function testLegacyHandleClassNotFound() + { + $prefixes = array('Symfony\Component\Debug\Exception\\' => realpath(__DIR__.'/../../Exception')); + $symfonyUniversalClassLoader = new SymfonyUniversalClassLoader(); + $symfonyUniversalClassLoader->registerPrefixes($prefixes); + + $this->testHandleClassNotFound( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found', + ), + "Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?", + array($symfonyUniversalClassLoader, 'loadClass') + ); + } + + public function provideClassNotFoundData() + { + $prefixes = array('Symfony\Component\Debug\Exception\\' => realpath(__DIR__.'/../../Exception')); + + $symfonyAutoloader = new SymfonyClassLoader(); + $symfonyAutoloader->addPrefixes($prefixes); + + $debugClassLoader = new DebugClassLoader(array($symfonyAutoloader, 'loadClass')); + + return array( + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'WhizBangFactory\' not found', + ), + "Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement?", + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'Foo\\Bar\\WhizBangFactory\' not found', + ), + "Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?", + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'UndefinedFunctionException\' not found', + ), + "Attempted to load class \"UndefinedFunctionException\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?", + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'PEARClass\' not found', + ), + "Attempted to load class \"PEARClass\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony_Component_Debug_Tests_Fixtures_PEARClass\"?", + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found', + ), + "Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?", + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found', + ), + "Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?", + array($symfonyAutoloader, 'loadClass'), + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found', + ), + "Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?", + array($debugClassLoader, 'loadClass'), + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found', + ), + "Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?", + function ($className) { /* do nothing here */ }, + ), + ); + } + + public function testCannotRedeclareClass() + { + if (!file_exists(__DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP')) { + $this->markTestSkipped('Can only be run on case insensitive filesystems'); + } + + require_once __DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP'; + + $error = array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Class \'Foo\\Bar\\RequiredTwice\' not found', + ); + + $handler = new ClassNotFoundFatalErrorHandler(); + $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line'])); + + $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception); + } +} diff --git a/vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php b/vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php new file mode 100644 index 000000000..1dc212004 --- /dev/null +++ b/vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests\FatalErrorHandler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Debug\Exception\FatalErrorException; +use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler; + +class UndefinedFunctionFatalErrorHandlerTest extends TestCase +{ + /** + * @dataProvider provideUndefinedFunctionData + */ + public function testUndefinedFunction($error, $translatedMessage) + { + $handler = new UndefinedFunctionFatalErrorHandler(); + $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line'])); + + $this->assertInstanceOf('Symfony\Component\Debug\Exception\UndefinedFunctionException', $exception); + // class names are case insensitive and PHP/HHVM do not return the same + $this->assertSame(strtolower($translatedMessage), strtolower($exception->getMessage())); + $this->assertSame($error['type'], $exception->getSeverity()); + $this->assertSame($error['file'], $exception->getFile()); + $this->assertSame($error['line'], $exception->getLine()); + } + + public function provideUndefinedFunctionData() + { + return array( + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Call to undefined function test_namespaced_function()', + ), + "Attempted to call function \"test_namespaced_function\" from the global namespace.\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?", + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Call to undefined function Foo\\Bar\\Baz\\test_namespaced_function()', + ), + "Attempted to call function \"test_namespaced_function\" from namespace \"Foo\\Bar\\Baz\".\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?", + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Call to undefined function foo()', + ), + 'Attempted to call function "foo" from the global namespace.', + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Call to undefined function Foo\\Bar\\Baz\\foo()', + ), + 'Attempted to call function "foo" from namespace "Foo\Bar\Baz".', + ), + ); + } +} + +function test_namespaced_function() +{ +} diff --git a/vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php b/vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php new file mode 100644 index 000000000..739e5b2b1 --- /dev/null +++ b/vendor/symfony/debug/Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests\FatalErrorHandler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Debug\Exception\FatalErrorException; +use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler; + +class UndefinedMethodFatalErrorHandlerTest extends TestCase +{ + /** + * @dataProvider provideUndefinedMethodData + */ + public function testUndefinedMethod($error, $translatedMessage) + { + $handler = new UndefinedMethodFatalErrorHandler(); + $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line'])); + + $this->assertInstanceOf('Symfony\Component\Debug\Exception\UndefinedMethodException', $exception); + $this->assertSame($translatedMessage, $exception->getMessage()); + $this->assertSame($error['type'], $exception->getSeverity()); + $this->assertSame($error['file'], $exception->getFile()); + $this->assertSame($error['line'], $exception->getLine()); + } + + public function provideUndefinedMethodData() + { + return array( + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Call to undefined method SplObjectStorage::what()', + ), + 'Attempted to call an undefined method named "what" of class "SplObjectStorage".', + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Call to undefined method SplObjectStorage::walid()', + ), + "Attempted to call an undefined method named \"walid\" of class \"SplObjectStorage\".\nDid you mean to call \"valid\"?", + ), + array( + array( + 'type' => 1, + 'line' => 12, + 'file' => 'foo.php', + 'message' => 'Call to undefined method SplObjectStorage::offsetFet()', + ), + "Attempted to call an undefined method named \"offsetFet\" of class \"SplObjectStorage\".\nDid you mean to call e.g. \"offsetGet\", \"offsetSet\" or \"offsetUnset\"?", + ), + array( + array( + 'type' => 1, + 'message' => 'Call to undefined method class@anonymous::test()', + 'file' => '/home/possum/work/symfony/test.php', + 'line' => 11, + ), + 'Attempted to call an undefined method named "test" of class "class@anonymous".', + ), + ); + } +} diff --git a/vendor/symfony/debug/Tests/Fixtures/ClassAlias.php b/vendor/symfony/debug/Tests/Fixtures/ClassAlias.php new file mode 100644 index 000000000..9d6dbaa71 --- /dev/null +++ b/vendor/symfony/debug/Tests/Fixtures/ClassAlias.php @@ -0,0 +1,3 @@ +exception = $e; + } + + public function __toString() + { + try { + throw $this->exception; + } catch (\Exception $e) { + // Using user_error() here is on purpose so we do not forget + // that this alias also should work alongside with trigger_error(). + return user_error($e, E_USER_ERROR); + } + } +} diff --git a/vendor/symfony/debug/Tests/Fixtures/casemismatch.php b/vendor/symfony/debug/Tests/Fixtures/casemismatch.php new file mode 100644 index 000000000..691d660fd --- /dev/null +++ b/vendor/symfony/debug/Tests/Fixtures/casemismatch.php @@ -0,0 +1,7 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug; + +function headers_sent() +{ + return false; +} + +function header($str, $replace = true, $status = null) +{ + Tests\testHeader($str, $replace, $status); +} + +namespace Symfony\Component\Debug\Tests; + +function testHeader() +{ + static $headers = array(); + + if (!$h = func_get_args()) { + $h = $headers; + $headers = array(); + + return $h; + } + + $headers[] = func_get_args(); +} diff --git a/vendor/symfony/debug/Tests/MockExceptionHandler.php b/vendor/symfony/debug/Tests/MockExceptionHandler.php new file mode 100644 index 000000000..2d6ce564d --- /dev/null +++ b/vendor/symfony/debug/Tests/MockExceptionHandler.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests; + +use Symfony\Component\Debug\ExceptionHandler; + +class MockExceptionHandler extends ExceptionHandler +{ + public $e; + + public function handle(\Exception $e) + { + $this->e = $e; + } +} diff --git a/vendor/symfony/debug/phpunit.xml.dist b/vendor/symfony/debug/phpunit.xml.dist index e99c4ddf4..12e58612b 100644 --- a/vendor/symfony/debug/phpunit.xml.dist +++ b/vendor/symfony/debug/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/dependency-injection/Compiler/AutowirePass.php b/vendor/symfony/dependency-injection/Compiler/AutowirePass.php index 07919b74d..b27954855 100644 --- a/vendor/symfony/dependency-injection/Compiler/AutowirePass.php +++ b/vendor/symfony/dependency-injection/Compiler/AutowirePass.php @@ -116,7 +116,8 @@ class AutowirePass implements CompilerPassInterface } if (isset($this->autowired[$typeHint->name])) { - return $this->autowired[$typeHint->name] ? new Reference($this->autowired[$typeHint->name]) : null; + $arguments[$index] = $this->autowired[$typeHint->name] ? new Reference($this->autowired[$typeHint->name]) : null; + continue; } if (null === $this->types) { @@ -303,9 +304,28 @@ class AutowirePass implements CompilerPassInterface $class = $this->container->getParameterBag()->resolveValue($class); + if ($deprecated = $definition->isDeprecated()) { + $prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) { + return (E_USER_DEPRECATED === $level || !$prevErrorHandler) ? false : $prevErrorHandler($level, $message, $file, $line); + }); + } + + $e = null; + try { $reflector = new \ReflectionClass($class); - } catch (\ReflectionException $e) { + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + + if ($deprecated) { + restore_error_handler(); + } + + if (null !== $e) { + if (!$e instanceof \ReflectionException) { + throw $e; + } $reflector = false; } diff --git a/vendor/symfony/dependency-injection/Definition.php b/vendor/symfony/dependency-injection/Definition.php index 1b3a1c24e..7781220a9 100644 --- a/vendor/symfony/dependency-injection/Definition.php +++ b/vendor/symfony/dependency-injection/Definition.php @@ -29,7 +29,7 @@ class Definition private $factoryService; private $shared = true; private $deprecated = false; - private $deprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.'; + private $deprecationTemplate; private $scope = ContainerInterface::SCOPE_CONTAINER; private $properties = array(); private $calls = array(); @@ -44,6 +44,8 @@ class Definition private $autowired = false; private $autowiringTypes = array(); + private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.'; + protected $arguments; /** @@ -379,7 +381,7 @@ class Definition public function addMethodCall($method, array $arguments = array()) { if (empty($method)) { - throw new InvalidArgumentException(sprintf('Method name cannot be empty.')); + throw new InvalidArgumentException('Method name cannot be empty.'); } $this->calls[] = array($method, $arguments); @@ -796,7 +798,7 @@ class Definition */ public function getDeprecationMessage($id) { - return str_replace('%service_id%', $id, $this->deprecationTemplate); + return str_replace('%service_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate); } /** diff --git a/vendor/symfony/dependency-injection/Dumper/PhpDumper.php b/vendor/symfony/dependency-injection/Dumper/PhpDumper.php index 888e14439..6c131aae1 100644 --- a/vendor/symfony/dependency-injection/Dumper/PhpDumper.php +++ b/vendor/symfony/dependency-injection/Dumper/PhpDumper.php @@ -847,7 +847,7 @@ EOF; private function startClass($class, $baseClass, $namespace) { $bagClass = $this->container->isFrozen() ? 'use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;' : 'use Symfony\Component\DependencyInjection\ParameterBag\\ParameterBag;'; - $namespaceLine = $namespace ? "namespace $namespace;\n" : ''; + $namespaceLine = $namespace ? "\nnamespace $namespace;\n" : ''; return <<definitionVariables && $this->definitionVariables->contains($value)) { return $this->dumpValue($this->definitionVariables->offsetGet($value), $interpolate); } - if (count($value->getMethodCalls()) > 0) { + if ($value->getMethodCalls()) { throw new RuntimeException('Cannot dump definitions which have method calls.'); } + if ($value->getProperties()) { + throw new RuntimeException('Cannot dump definitions which have properties.'); + } if (null !== $value->getConfigurator()) { throw new RuntimeException('Cannot dump definitions which have a configurator.'); } diff --git a/vendor/symfony/dependency-injection/Dumper/XmlDumper.php b/vendor/symfony/dependency-injection/Dumper/XmlDumper.php index d76982354..ce7ec49d8 100644 --- a/vendor/symfony/dependency-injection/Dumper/XmlDumper.php +++ b/vendor/symfony/dependency-injection/Dumper/XmlDumper.php @@ -215,6 +215,10 @@ class XmlDumper extends Dumper $service->appendChild($autowiringType); } + if ($definition->isAbstract()) { + $service->setAttribute('abstract', 'true'); + } + if ($callable = $definition->getConfigurator()) { $configurator = $this->document->createElement('configurator'); diff --git a/vendor/symfony/dependency-injection/Dumper/YamlDumper.php b/vendor/symfony/dependency-injection/Dumper/YamlDumper.php index 431b40f9d..f966b8234 100644 --- a/vendor/symfony/dependency-injection/Dumper/YamlDumper.php +++ b/vendor/symfony/dependency-injection/Dumper/YamlDumper.php @@ -93,11 +93,11 @@ class YamlDumper extends Dumper } if ($definition->isSynthetic()) { - $code .= sprintf(" synthetic: true\n"); + $code .= " synthetic: true\n"; } if ($definition->isSynchronized(false)) { - $code .= sprintf(" synchronized: true\n"); + $code .= " synchronized: true\n"; } if ($definition->isDeprecated()) { @@ -121,7 +121,7 @@ class YamlDumper extends Dumper } if ($definition->isLazy()) { - $code .= sprintf(" lazy: true\n"); + $code .= " lazy: true\n"; } if ($definition->getFactoryMethod(false)) { diff --git a/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd b/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd index 530ca1c13..a8d7cf88d 100644 --- a/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd +++ b/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd @@ -145,8 +145,8 @@ - - + + @@ -158,8 +158,8 @@ - - + + @@ -170,10 +170,9 @@ - - - - + + + diff --git a/vendor/symfony/dependency-injection/Tests/Compiler/AutoAliasServicePassTest.php b/vendor/symfony/dependency-injection/Tests/Compiler/AutoAliasServicePassTest.php index f8199b8c9..281634225 100644 --- a/vendor/symfony/dependency-injection/Tests/Compiler/AutoAliasServicePassTest.php +++ b/vendor/symfony/dependency-injection/Tests/Compiler/AutoAliasServicePassTest.php @@ -25,7 +25,7 @@ class AutoAliasServicePassTest extends TestCase $container = new ContainerBuilder(); $container->register('example') - ->addTag('auto_alias', array('format' => '%non_existing%.example')); + ->addTag('auto_alias', array('format' => '%non_existing%.example')); $pass = new AutoAliasServicePass(); $pass->process($container); @@ -39,7 +39,7 @@ class AutoAliasServicePassTest extends TestCase $container = new ContainerBuilder(); $container->register('example') - ->addTag('auto_alias', array()); + ->addTag('auto_alias', array()); $container->setParameter('existing', 'mysql'); $pass = new AutoAliasServicePass(); @@ -51,7 +51,7 @@ class AutoAliasServicePassTest extends TestCase $container = new ContainerBuilder(); $container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault') - ->addTag('auto_alias', array('format' => '%existing%.example')); + ->addTag('auto_alias', array('format' => '%existing%.example')); $container->setParameter('existing', 'mysql'); $pass = new AutoAliasServicePass(); @@ -66,7 +66,7 @@ class AutoAliasServicePassTest extends TestCase $container = new ContainerBuilder(); $container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault') - ->addTag('auto_alias', array('format' => '%existing%.example')); + ->addTag('auto_alias', array('format' => '%existing%.example')); $container->register('mysql.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql'); $container->setParameter('existing', 'mysql'); @@ -84,7 +84,7 @@ class AutoAliasServicePassTest extends TestCase $container = new ContainerBuilder(); $container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault') - ->addTag('auto_alias', array('format' => '%existing%.example')); + ->addTag('auto_alias', array('format' => '%existing%.example')); $container->register('mysql.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql'); $container->register('mariadb.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMariadb'); diff --git a/vendor/symfony/dependency-injection/Tests/Compiler/AutowirePassTest.php b/vendor/symfony/dependency-injection/Tests/Compiler/AutowirePassTest.php index 9cc7d1af7..ad89c5b9b 100644 --- a/vendor/symfony/dependency-injection/Tests/Compiler/AutowirePassTest.php +++ b/vendor/symfony/dependency-injection/Tests/Compiler/AutowirePassTest.php @@ -212,8 +212,9 @@ class AutowirePassTest extends TestCase $pass = new AutowirePass(); $pass->process($container); - $this->assertCount(1, $container->getDefinition('coop_tilleuls')->getArguments()); + $this->assertCount(2, $container->getDefinition('coop_tilleuls')->getArguments()); $this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0)); + $this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas', $container->getDefinition('coop_tilleuls')->getArgument(1)); $dunglasDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas'); $this->assertEquals(__NAMESPACE__.'\Dunglas', $dunglasDefinition->getClass()); @@ -442,6 +443,21 @@ class AutowirePassTest extends TestCase $this->assertTrue($container->hasDefinition('bar')); } + public function testProcessDoesNotTriggerDeprecations() + { + $container = new ContainerBuilder(); + $container->register('deprecated', 'Symfony\Component\DependencyInjection\Tests\Fixtures\DeprecatedClass')->setDeprecated(true); + $container->register('foo', __NAMESPACE__.'\Foo'); + $container->register('bar', __NAMESPACE__.'\Bar')->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + + $this->assertTrue($container->hasDefinition('deprecated')); + $this->assertTrue($container->hasDefinition('foo')); + $this->assertTrue($container->hasDefinition('bar')); + } + public function testEmptyStringIsKept() { $container = new ContainerBuilder(); @@ -589,7 +605,7 @@ class Dunglas class LesTilleuls { - public function __construct(Dunglas $k) + public function __construct(Dunglas $j, Dunglas $k) { } } diff --git a/vendor/symfony/dependency-injection/Tests/ContainerTest.php b/vendor/symfony/dependency-injection/Tests/ContainerTest.php index 834fef32b..dbe18f607 100644 --- a/vendor/symfony/dependency-injection/Tests/ContainerTest.php +++ b/vendor/symfony/dependency-injection/Tests/ContainerTest.php @@ -698,7 +698,7 @@ class ContainerTest extends TestCase { $class = new \ReflectionClass('Symfony\Component\DependencyInjection\Container'); $clone = $class->getMethod('__clone'); - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $this->assertFalse($class->isCloneable()); } $this->assertTrue($clone->isPrivate()); diff --git a/vendor/symfony/dependency-injection/Tests/Dumper/XmlDumperTest.php b/vendor/symfony/dependency-injection/Tests/Dumper/XmlDumperTest.php index 213ee1a78..c8d429db4 100644 --- a/vendor/symfony/dependency-injection/Tests/Dumper/XmlDumperTest.php +++ b/vendor/symfony/dependency-injection/Tests/Dumper/XmlDumperTest.php @@ -192,4 +192,12 @@ class XmlDumperTest extends TestCase $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services24.xml'), $dumper->dump()); } + + public function testDumpAbstractServices() + { + $container = include self::$fixturesPath.'/containers/container_abstract.php'; + $dumper = new XmlDumper($container); + + $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_abstract.xml'), $dumper->dump()); + } } diff --git a/vendor/symfony/dependency-injection/Tests/Fixtures/DeprecatedClass.php b/vendor/symfony/dependency-injection/Tests/Fixtures/DeprecatedClass.php new file mode 100644 index 000000000..33f37a030 --- /dev/null +++ b/vendor/symfony/dependency-injection/Tests/Fixtures/DeprecatedClass.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +@trigger_error('deprecated', E_USER_DEPRECATED); + +class DeprecatedClass +{ +} diff --git a/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container14.php b/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container14.php index 56ea6c1ed..191afb8cd 100644 --- a/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container14.php +++ b/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container14.php @@ -4,7 +4,7 @@ namespace Container14; use Symfony\Component\DependencyInjection\ContainerBuilder; -/** +/* * This file is included in Tests\Dumper\GraphvizDumperTest::testDumpWithFrozenCustomClassContainer * and Tests\Dumper\XmlDumperTest::testCompiledContainerCanBeDumped. */ diff --git a/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_abstract.php b/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_abstract.php new file mode 100644 index 000000000..9622a273d --- /dev/null +++ b/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_abstract.php @@ -0,0 +1,12 @@ +register('foo', 'Foo') + ->setAbstract(true) +; + +return $container; diff --git a/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1-1.php b/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1-1.php index f15771172..0fede6502 100644 --- a/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1-1.php +++ b/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1-1.php @@ -1,4 +1,5 @@ + + + + + diff --git a/vendor/symfony/dependency-injection/phpunit.xml.dist b/vendor/symfony/dependency-injection/phpunit.xml.dist index 86252d045..781f767d5 100644 --- a/vendor/symfony/dependency-injection/phpunit.xml.dist +++ b/vendor/symfony/dependency-injection/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/dom-crawler/Tests/CrawlerTest.php b/vendor/symfony/dom-crawler/Tests/CrawlerTest.php old mode 100755 new mode 100644 diff --git a/vendor/symfony/dom-crawler/phpunit.xml.dist b/vendor/symfony/dom-crawler/phpunit.xml.dist index d15dd6a48..ad714a8fd 100644 --- a/vendor/symfony/dom-crawler/phpunit.xml.dist +++ b/vendor/symfony/dom-crawler/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php b/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php index 6a02e9f96..f2d5a4053 100644 --- a/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php +++ b/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php @@ -105,7 +105,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher public function hasListeners($eventName = null) { if (null === $eventName) { - return (bool) count($this->listenerIds) || (bool) count($this->listeners); + return $this->listenerIds || $this->listeners || parent::hasListeners(); } if (isset($this->listenerIds[$eventName])) { diff --git a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php index 9b460f55f..2f6d9be02 100644 --- a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php +++ b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php @@ -306,6 +306,12 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface 'event' => $eventName, 'priority' => $this->getListenerPriority($eventName, $listener), ); + + // unwrap for correct listener info + if ($listener instanceof WrappedListener) { + $listener = $listener->getWrappedListener(); + } + if ($listener instanceof \Closure) { $info += array( 'type' => 'Closure', diff --git a/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php new file mode 100644 index 000000000..23849168d --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php @@ -0,0 +1,398 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +abstract class AbstractEventDispatcherTest extends TestCase +{ + /* Some pseudo events */ + const preFoo = 'pre.foo'; + const postFoo = 'post.foo'; + const preBar = 'pre.bar'; + const postBar = 'post.bar'; + + /** + * @var EventDispatcher + */ + private $dispatcher; + + private $listener; + + protected function setUp() + { + $this->dispatcher = $this->createEventDispatcher(); + $this->listener = new TestEventListener(); + } + + protected function tearDown() + { + $this->dispatcher = null; + $this->listener = null; + } + + abstract protected function createEventDispatcher(); + + public function testInitialState() + { + $this->assertEquals(array(), $this->dispatcher->getListeners()); + $this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); + $this->assertFalse($this->dispatcher->hasListeners(self::postFoo)); + } + + public function testAddListener() + { + $this->dispatcher->addListener('pre.foo', array($this->listener, 'preFoo')); + $this->dispatcher->addListener('post.foo', array($this->listener, 'postFoo')); + $this->assertTrue($this->dispatcher->hasListeners()); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertTrue($this->dispatcher->hasListeners(self::postFoo)); + $this->assertCount(1, $this->dispatcher->getListeners(self::preFoo)); + $this->assertCount(1, $this->dispatcher->getListeners(self::postFoo)); + $this->assertCount(2, $this->dispatcher->getListeners()); + } + + public function testGetListenersSortsByPriority() + { + $listener1 = new TestEventListener(); + $listener2 = new TestEventListener(); + $listener3 = new TestEventListener(); + $listener1->name = '1'; + $listener2->name = '2'; + $listener3->name = '3'; + + $this->dispatcher->addListener('pre.foo', array($listener1, 'preFoo'), -10); + $this->dispatcher->addListener('pre.foo', array($listener2, 'preFoo'), 10); + $this->dispatcher->addListener('pre.foo', array($listener3, 'preFoo')); + + $expected = array( + array($listener2, 'preFoo'), + array($listener3, 'preFoo'), + array($listener1, 'preFoo'), + ); + + $this->assertSame($expected, $this->dispatcher->getListeners('pre.foo')); + } + + public function testGetAllListenersSortsByPriority() + { + $listener1 = new TestEventListener(); + $listener2 = new TestEventListener(); + $listener3 = new TestEventListener(); + $listener4 = new TestEventListener(); + $listener5 = new TestEventListener(); + $listener6 = new TestEventListener(); + + $this->dispatcher->addListener('pre.foo', $listener1, -10); + $this->dispatcher->addListener('pre.foo', $listener2); + $this->dispatcher->addListener('pre.foo', $listener3, 10); + $this->dispatcher->addListener('post.foo', $listener4, -10); + $this->dispatcher->addListener('post.foo', $listener5); + $this->dispatcher->addListener('post.foo', $listener6, 10); + + $expected = array( + 'pre.foo' => array($listener3, $listener2, $listener1), + 'post.foo' => array($listener6, $listener5, $listener4), + ); + + $this->assertSame($expected, $this->dispatcher->getListeners()); + } + + public function testGetListenerPriority() + { + $listener1 = new TestEventListener(); + $listener2 = new TestEventListener(); + + $this->dispatcher->addListener('pre.foo', $listener1, -10); + $this->dispatcher->addListener('pre.foo', $listener2); + + $this->assertSame(-10, $this->dispatcher->getListenerPriority('pre.foo', $listener1)); + $this->assertSame(0, $this->dispatcher->getListenerPriority('pre.foo', $listener2)); + $this->assertNull($this->dispatcher->getListenerPriority('pre.bar', $listener2)); + $this->assertNull($this->dispatcher->getListenerPriority('pre.foo', function () {})); + } + + public function testDispatch() + { + $this->dispatcher->addListener('pre.foo', array($this->listener, 'preFoo')); + $this->dispatcher->addListener('post.foo', array($this->listener, 'postFoo')); + $this->dispatcher->dispatch(self::preFoo); + $this->assertTrue($this->listener->preFooInvoked); + $this->assertFalse($this->listener->postFooInvoked); + $this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch('noevent')); + $this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch(self::preFoo)); + $event = new Event(); + $return = $this->dispatcher->dispatch(self::preFoo, $event); + $this->assertSame($event, $return); + } + + /** + * @group legacy + */ + public function testLegacyDispatch() + { + $event = new Event(); + $this->dispatcher->dispatch(self::preFoo, $event); + $this->assertEquals('pre.foo', $event->getName()); + } + + public function testDispatchForClosure() + { + $invoked = 0; + $listener = function () use (&$invoked) { + ++$invoked; + }; + $this->dispatcher->addListener('pre.foo', $listener); + $this->dispatcher->addListener('post.foo', $listener); + $this->dispatcher->dispatch(self::preFoo); + $this->assertEquals(1, $invoked); + } + + public function testStopEventPropagation() + { + $otherListener = new TestEventListener(); + + // postFoo() stops the propagation, so only one listener should + // be executed + // Manually set priority to enforce $this->listener to be called first + $this->dispatcher->addListener('post.foo', array($this->listener, 'postFoo'), 10); + $this->dispatcher->addListener('post.foo', array($otherListener, 'preFoo')); + $this->dispatcher->dispatch(self::postFoo); + $this->assertTrue($this->listener->postFooInvoked); + $this->assertFalse($otherListener->postFooInvoked); + } + + public function testDispatchByPriority() + { + $invoked = array(); + $listener1 = function () use (&$invoked) { + $invoked[] = '1'; + }; + $listener2 = function () use (&$invoked) { + $invoked[] = '2'; + }; + $listener3 = function () use (&$invoked) { + $invoked[] = '3'; + }; + $this->dispatcher->addListener('pre.foo', $listener1, -10); + $this->dispatcher->addListener('pre.foo', $listener2); + $this->dispatcher->addListener('pre.foo', $listener3, 10); + $this->dispatcher->dispatch(self::preFoo); + $this->assertEquals(array('3', '2', '1'), $invoked); + } + + public function testRemoveListener() + { + $this->dispatcher->addListener('pre.bar', $this->listener); + $this->assertTrue($this->dispatcher->hasListeners(self::preBar)); + $this->dispatcher->removeListener('pre.bar', $this->listener); + $this->assertFalse($this->dispatcher->hasListeners(self::preBar)); + $this->dispatcher->removeListener('notExists', $this->listener); + } + + public function testAddSubscriber() + { + $eventSubscriber = new TestEventSubscriber(); + $this->dispatcher->addSubscriber($eventSubscriber); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertTrue($this->dispatcher->hasListeners(self::postFoo)); + } + + public function testAddSubscriberWithPriorities() + { + $eventSubscriber = new TestEventSubscriber(); + $this->dispatcher->addSubscriber($eventSubscriber); + + $eventSubscriber = new TestEventSubscriberWithPriorities(); + $this->dispatcher->addSubscriber($eventSubscriber); + + $listeners = $this->dispatcher->getListeners('pre.foo'); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertCount(2, $listeners); + $this->assertInstanceOf('Symfony\Component\EventDispatcher\Tests\TestEventSubscriberWithPriorities', $listeners[0][0]); + } + + public function testAddSubscriberWithMultipleListeners() + { + $eventSubscriber = new TestEventSubscriberWithMultipleListeners(); + $this->dispatcher->addSubscriber($eventSubscriber); + + $listeners = $this->dispatcher->getListeners('pre.foo'); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertCount(2, $listeners); + $this->assertEquals('preFoo2', $listeners[0][1]); + } + + public function testRemoveSubscriber() + { + $eventSubscriber = new TestEventSubscriber(); + $this->dispatcher->addSubscriber($eventSubscriber); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertTrue($this->dispatcher->hasListeners(self::postFoo)); + $this->dispatcher->removeSubscriber($eventSubscriber); + $this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); + $this->assertFalse($this->dispatcher->hasListeners(self::postFoo)); + } + + public function testRemoveSubscriberWithPriorities() + { + $eventSubscriber = new TestEventSubscriberWithPriorities(); + $this->dispatcher->addSubscriber($eventSubscriber); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->dispatcher->removeSubscriber($eventSubscriber); + $this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); + } + + public function testRemoveSubscriberWithMultipleListeners() + { + $eventSubscriber = new TestEventSubscriberWithMultipleListeners(); + $this->dispatcher->addSubscriber($eventSubscriber); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertCount(2, $this->dispatcher->getListeners(self::preFoo)); + $this->dispatcher->removeSubscriber($eventSubscriber); + $this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); + } + + /** + * @group legacy + */ + public function testLegacyEventReceivesTheDispatcherInstance() + { + $dispatcher = null; + $this->dispatcher->addListener('test', function ($event) use (&$dispatcher) { + $dispatcher = $event->getDispatcher(); + }); + $this->dispatcher->dispatch('test'); + $this->assertSame($this->dispatcher, $dispatcher); + } + + public function testEventReceivesTheDispatcherInstanceAsArgument() + { + $listener = new TestWithDispatcher(); + $this->dispatcher->addListener('test', array($listener, 'foo')); + $this->assertNull($listener->name); + $this->assertNull($listener->dispatcher); + $this->dispatcher->dispatch('test'); + $this->assertEquals('test', $listener->name); + $this->assertSame($this->dispatcher, $listener->dispatcher); + } + + /** + * @see https://bugs.php.net/bug.php?id=62976 + * + * This bug affects: + * - The PHP 5.3 branch for versions < 5.3.18 + * - The PHP 5.4 branch for versions < 5.4.8 + * - The PHP 5.5 branch is not affected + */ + public function testWorkaroundForPhpBug62976() + { + $dispatcher = $this->createEventDispatcher(); + $dispatcher->addListener('bug.62976', new CallableClass()); + $dispatcher->removeListener('bug.62976', function () {}); + $this->assertTrue($dispatcher->hasListeners('bug.62976')); + } + + public function testHasListenersWhenAddedCallbackListenerIsRemoved() + { + $listener = function () {}; + $this->dispatcher->addListener('foo', $listener); + $this->dispatcher->removeListener('foo', $listener); + $this->assertFalse($this->dispatcher->hasListeners()); + } + + public function testGetListenersWhenAddedCallbackListenerIsRemoved() + { + $listener = function () {}; + $this->dispatcher->addListener('foo', $listener); + $this->dispatcher->removeListener('foo', $listener); + $this->assertSame(array(), $this->dispatcher->getListeners()); + } + + public function testHasListenersWithoutEventsReturnsFalseAfterHasListenersWithEventHasBeenCalled() + { + $this->assertFalse($this->dispatcher->hasListeners('foo')); + $this->assertFalse($this->dispatcher->hasListeners()); + } +} + +class CallableClass +{ + public function __invoke() + { + } +} + +class TestEventListener +{ + public $preFooInvoked = false; + public $postFooInvoked = false; + + /* Listener methods */ + + public function preFoo(Event $e) + { + $this->preFooInvoked = true; + } + + public function postFoo(Event $e) + { + $this->postFooInvoked = true; + + $e->stopPropagation(); + } +} + +class TestWithDispatcher +{ + public $name; + public $dispatcher; + + public function foo(Event $e, $name, $dispatcher) + { + $this->name = $name; + $this->dispatcher = $dispatcher; + } +} + +class TestEventSubscriber implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return array('pre.foo' => 'preFoo', 'post.foo' => 'postFoo'); + } +} + +class TestEventSubscriberWithPriorities implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return array( + 'pre.foo' => array('preFoo', 10), + 'post.foo' => array('postFoo'), + ); + } +} + +class TestEventSubscriberWithMultipleListeners implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return array('pre.foo' => array( + array('preFoo1'), + array('preFoo2', 10), + )); + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php new file mode 100644 index 000000000..b1f84d481 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php @@ -0,0 +1,277 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\Scope; +use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest +{ + protected function createEventDispatcher() + { + $container = new Container(); + + return new ContainerAwareEventDispatcher($container); + } + + public function testAddAListenerService() + { + $event = new Event(); + + $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); + + $service + ->expects($this->once()) + ->method('onEvent') + ->with($event) + ; + + $container = new Container(); + $container->set('service.listener', $service); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); + + $dispatcher->dispatch('onEvent', $event); + } + + public function testAddASubscriberService() + { + $event = new Event(); + + $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\SubscriberService')->getMock(); + + $service + ->expects($this->once()) + ->method('onEvent') + ->with($event) + ; + + $service + ->expects($this->once()) + ->method('onEventWithPriority') + ->with($event) + ; + + $service + ->expects($this->once()) + ->method('onEventNested') + ->with($event) + ; + + $container = new Container(); + $container->set('service.subscriber', $service); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addSubscriberService('service.subscriber', 'Symfony\Component\EventDispatcher\Tests\SubscriberService'); + + $dispatcher->dispatch('onEvent', $event); + $dispatcher->dispatch('onEventWithPriority', $event); + $dispatcher->dispatch('onEventNested', $event); + } + + public function testPreventDuplicateListenerService() + { + $event = new Event(); + + $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); + + $service + ->expects($this->once()) + ->method('onEvent') + ->with($event) + ; + + $container = new Container(); + $container->set('service.listener', $service); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'), 5); + $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'), 10); + + $dispatcher->dispatch('onEvent', $event); + } + + /** + * @expectedException \InvalidArgumentException + * @group legacy + */ + public function testTriggerAListenerServiceOutOfScope() + { + $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); + + $scope = new Scope('scope'); + $container = new Container(); + $container->addScope($scope); + $container->enterScope('scope'); + + $container->set('service.listener', $service, 'scope'); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); + + $container->leaveScope('scope'); + $dispatcher->dispatch('onEvent'); + } + + /** + * @group legacy + */ + public function testReEnteringAScope() + { + $event = new Event(); + + $service1 = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); + + $service1 + ->expects($this->exactly(2)) + ->method('onEvent') + ->with($event) + ; + + $scope = new Scope('scope'); + $container = new Container(); + $container->addScope($scope); + $container->enterScope('scope'); + + $container->set('service.listener', $service1, 'scope'); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); + $dispatcher->dispatch('onEvent', $event); + + $service2 = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); + + $service2 + ->expects($this->once()) + ->method('onEvent') + ->with($event) + ; + + $container->enterScope('scope'); + $container->set('service.listener', $service2, 'scope'); + + $dispatcher->dispatch('onEvent', $event); + + $container->leaveScope('scope'); + + $dispatcher->dispatch('onEvent'); + } + + public function testHasListenersOnLazyLoad() + { + $event = new Event(); + + $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); + + $container = new Container(); + $container->set('service.listener', $service); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); + + $event->setDispatcher($dispatcher); + $event->setName('onEvent'); + + $service + ->expects($this->once()) + ->method('onEvent') + ->with($event) + ; + + $this->assertTrue($dispatcher->hasListeners()); + + if ($dispatcher->hasListeners('onEvent')) { + $dispatcher->dispatch('onEvent'); + } + } + + public function testGetListenersOnLazyLoad() + { + $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); + + $container = new Container(); + $container->set('service.listener', $service); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); + + $listeners = $dispatcher->getListeners(); + + $this->assertTrue(isset($listeners['onEvent'])); + + $this->assertCount(1, $dispatcher->getListeners('onEvent')); + } + + public function testRemoveAfterDispatch() + { + $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); + + $container = new Container(); + $container->set('service.listener', $service); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); + + $dispatcher->dispatch('onEvent', new Event()); + $dispatcher->removeListener('onEvent', array($container->get('service.listener'), 'onEvent')); + $this->assertFalse($dispatcher->hasListeners('onEvent')); + } + + public function testRemoveBeforeDispatch() + { + $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); + + $container = new Container(); + $container->set('service.listener', $service); + + $dispatcher = new ContainerAwareEventDispatcher($container); + $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); + + $dispatcher->removeListener('onEvent', array($container->get('service.listener'), 'onEvent')); + $this->assertFalse($dispatcher->hasListeners('onEvent')); + } +} + +class Service +{ + public function onEvent(Event $e) + { + } +} + +class SubscriberService implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return array( + 'onEvent' => 'onEvent', + 'onEventWithPriority' => array('onEventWithPriority', 10), + 'onEventNested' => array(array('onEventNested')), + ); + } + + public function onEvent(Event $e) + { + } + + public function onEventWithPriority(Event $e) + { + } + + public function onEventNested(Event $e) + { + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php new file mode 100644 index 000000000..d99b0bf9c --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php @@ -0,0 +1,254 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests\Debug; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; +use Symfony\Component\EventDispatcher\Debug\WrappedListener; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\Stopwatch\Stopwatch; + +class TraceableEventDispatcherTest extends TestCase +{ + public function testAddRemoveListener() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $tdispatcher->addListener('foo', $listener = function () {}); + $listeners = $dispatcher->getListeners('foo'); + $this->assertCount(1, $listeners); + $this->assertSame($listener, $listeners[0]); + + $tdispatcher->removeListener('foo', $listener); + $this->assertCount(0, $dispatcher->getListeners('foo')); + } + + public function testGetListeners() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $tdispatcher->addListener('foo', $listener = function () {}); + $this->assertSame($dispatcher->getListeners('foo'), $tdispatcher->getListeners('foo')); + } + + public function testHasListeners() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $this->assertFalse($dispatcher->hasListeners('foo')); + $this->assertFalse($tdispatcher->hasListeners('foo')); + + $tdispatcher->addListener('foo', $listener = function () {}); + $this->assertTrue($dispatcher->hasListeners('foo')); + $this->assertTrue($tdispatcher->hasListeners('foo')); + } + + public function testGetListenerPriority() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $tdispatcher->addListener('foo', function () {}, 123); + + $listeners = $dispatcher->getListeners('foo'); + $this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0])); + + // Verify that priority is preserved when listener is removed and re-added + // in preProcess() and postProcess(). + $tdispatcher->dispatch('foo', new Event()); + $listeners = $dispatcher->getListeners('foo'); + $this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0])); + } + + public function testGetListenerPriorityReturnsZeroWhenWrappedMethodDoesNotExist() + { + $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); + $traceableEventDispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + $traceableEventDispatcher->addListener('foo', function () {}, 123); + $listeners = $traceableEventDispatcher->getListeners('foo'); + + $this->assertSame(0, $traceableEventDispatcher->getListenerPriority('foo', $listeners[0])); + } + + public function testAddRemoveSubscriber() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $subscriber = new EventSubscriber(); + + $tdispatcher->addSubscriber($subscriber); + $listeners = $dispatcher->getListeners('foo'); + $this->assertCount(1, $listeners); + $this->assertSame(array($subscriber, 'call'), $listeners[0]); + + $tdispatcher->removeSubscriber($subscriber); + $this->assertCount(0, $dispatcher->getListeners('foo')); + } + + /** + * @dataProvider isWrappedDataProvider + * + * @param bool $isWrapped + */ + public function testGetCalledListeners($isWrapped) + { + $dispatcher = new EventDispatcher(); + $stopWatch = new Stopwatch(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, $stopWatch); + + $listener = function () {}; + if ($isWrapped) { + $listener = new WrappedListener($listener, 'foo', $stopWatch, $dispatcher); + } + + $tdispatcher->addListener('foo', $listener, 5); + + $this->assertEquals(array(), $tdispatcher->getCalledListeners()); + $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'type' => 'Closure', 'pretty' => 'closure', 'priority' => 5)), $tdispatcher->getNotCalledListeners()); + + $tdispatcher->dispatch('foo'); + + $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'type' => 'Closure', 'pretty' => 'closure', 'priority' => 5)), $tdispatcher->getCalledListeners()); + $this->assertEquals(array(), $tdispatcher->getNotCalledListeners()); + } + + public function isWrappedDataProvider() + { + return array( + array(false), + array(true), + ); + } + + public function testGetCalledListenersNested() + { + $tdispatcher = null; + $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $dispatcher->addListener('foo', function (Event $event, $eventName, $dispatcher) use (&$tdispatcher) { + $tdispatcher = $dispatcher; + $dispatcher->dispatch('bar'); + }); + $dispatcher->addListener('bar', function (Event $event) {}); + $dispatcher->dispatch('foo'); + $this->assertSame($dispatcher, $tdispatcher); + $this->assertCount(2, $dispatcher->getCalledListeners()); + } + + public function testLogger() + { + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); + $tdispatcher->addListener('foo', $listener1 = function () {}); + $tdispatcher->addListener('foo', $listener2 = function () {}); + + $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".'); + $logger->expects($this->at(1))->method('debug')->with('Notified event "foo" to listener "closure".'); + + $tdispatcher->dispatch('foo'); + } + + public function testLoggerWithStoppedEvent() + { + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); + $tdispatcher->addListener('foo', $listener1 = function (Event $event) { $event->stopPropagation(); }); + $tdispatcher->addListener('foo', $listener2 = function () {}); + + $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".'); + $logger->expects($this->at(1))->method('debug')->with('Listener "closure" stopped propagation of the event "foo".'); + $logger->expects($this->at(2))->method('debug')->with('Listener "closure" was not called for event "foo".'); + + $tdispatcher->dispatch('foo'); + } + + public function testDispatchCallListeners() + { + $called = array(); + + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + $tdispatcher->addListener('foo', function () use (&$called) { $called[] = 'foo1'; }, 10); + $tdispatcher->addListener('foo', function () use (&$called) { $called[] = 'foo2'; }, 20); + + $tdispatcher->dispatch('foo'); + + $this->assertSame(array('foo2', 'foo1'), $called); + } + + public function testDispatchNested() + { + $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $loop = 1; + $dispatchedEvents = 0; + $dispatcher->addListener('foo', $listener1 = function () use ($dispatcher, &$loop) { + ++$loop; + if (2 == $loop) { + $dispatcher->dispatch('foo'); + } + }); + $dispatcher->addListener('foo', function () use (&$dispatchedEvents) { + ++$dispatchedEvents; + }); + + $dispatcher->dispatch('foo'); + + $this->assertSame(2, $dispatchedEvents); + } + + public function testDispatchReusedEventNested() + { + $nestedCall = false; + $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $dispatcher->addListener('foo', function (Event $e) use ($dispatcher) { + $dispatcher->dispatch('bar', $e); + }); + $dispatcher->addListener('bar', function (Event $e) use (&$nestedCall) { + $nestedCall = true; + }); + + $this->assertFalse($nestedCall); + $dispatcher->dispatch('foo'); + $this->assertTrue($nestedCall); + } + + public function testListenerCanRemoveItselfWhenExecuted() + { + $eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $listener1 = function ($event, $eventName, EventDispatcherInterface $dispatcher) use (&$listener1) { + $dispatcher->removeListener('foo', $listener1); + }; + $eventDispatcher->addListener('foo', $listener1); + $eventDispatcher->addListener('foo', function () {}); + $eventDispatcher->dispatch('foo'); + + $this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed'); + } +} + +class EventSubscriber implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return array('foo' => 'call'); + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php b/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php new file mode 100644 index 000000000..53d7282b3 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php @@ -0,0 +1,195 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; + +class RegisterListenersPassTest extends TestCase +{ + /** + * Tests that event subscribers not implementing EventSubscriberInterface + * trigger an exception. + * + * @expectedException \InvalidArgumentException + */ + public function testEventSubscriberWithoutInterface() + { + // one service, not implementing any interface + $services = array( + 'my_event_subscriber' => array(0 => array()), + ); + + $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); + $definition->expects($this->atLeastOnce()) + ->method('isPublic') + ->will($this->returnValue(true)); + $definition->expects($this->atLeastOnce()) + ->method('getClass') + ->will($this->returnValue('stdClass')); + + $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); + $builder->expects($this->any()) + ->method('hasDefinition') + ->will($this->returnValue(true)); + + // We don't test kernel.event_listener here + $builder->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->onConsecutiveCalls(array(), $services)); + + $builder->expects($this->atLeastOnce()) + ->method('getDefinition') + ->will($this->returnValue($definition)); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($builder); + } + + public function testValidEventSubscriber() + { + $services = array( + 'my_event_subscriber' => array(0 => array()), + ); + + $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); + $definition->expects($this->atLeastOnce()) + ->method('isPublic') + ->will($this->returnValue(true)); + $definition->expects($this->atLeastOnce()) + ->method('getClass') + ->will($this->returnValue('Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService')); + + $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition', 'findDefinition'))->getMock(); + $builder->expects($this->any()) + ->method('hasDefinition') + ->will($this->returnValue(true)); + + // We don't test kernel.event_listener here + $builder->expects($this->atLeastOnce()) + ->method('findTaggedServiceIds') + ->will($this->onConsecutiveCalls(array(), $services)); + + $builder->expects($this->atLeastOnce()) + ->method('getDefinition') + ->will($this->returnValue($definition)); + + $builder->expects($this->atLeastOnce()) + ->method('findDefinition') + ->will($this->returnValue($definition)); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($builder); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The service "foo" must be public as event listeners are lazy-loaded. + */ + public function testPrivateEventListener() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setPublic(false)->addTag('kernel.event_listener', array()); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The service "foo" must be public as event subscribers are lazy-loaded. + */ + public function testPrivateEventSubscriber() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setPublic(false)->addTag('kernel.event_subscriber', array()); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The service "foo" must not be abstract as event listeners are lazy-loaded. + */ + public function testAbstractEventListener() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setAbstract(true)->addTag('kernel.event_listener', array()); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The service "foo" must not be abstract as event subscribers are lazy-loaded. + */ + public function testAbstractEventSubscriber() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setAbstract(true)->addTag('kernel.event_subscriber', array()); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + } + + public function testEventSubscriberResolvableClassName() + { + $container = new ContainerBuilder(); + + $container->setParameter('subscriber.class', 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService'); + $container->register('foo', '%subscriber.class%')->addTag('kernel.event_subscriber', array()); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + + $definition = $container->getDefinition('event_dispatcher'); + $expected_calls = array( + array( + 'addSubscriberService', + array( + 'foo', + 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService', + ), + ), + ); + $this->assertSame($expected_calls, $definition->getMethodCalls()); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage You have requested a non-existent parameter "subscriber.class" + */ + public function testEventSubscriberUnresolvableClassName() + { + $container = new ContainerBuilder(); + $container->register('foo', '%subscriber.class%')->addTag('kernel.event_subscriber', array()); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + } +} + +class SubscriberService implements \Symfony\Component\EventDispatcher\EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php new file mode 100644 index 000000000..5faa5c8be --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use Symfony\Component\EventDispatcher\EventDispatcher; + +class EventDispatcherTest extends AbstractEventDispatcherTest +{ + protected function createEventDispatcher() + { + return new EventDispatcher(); + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/EventTest.php b/vendor/symfony/event-dispatcher/Tests/EventTest.php new file mode 100644 index 000000000..bdc14abbf --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/EventTest.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcher; + +/** + * Test class for Event. + */ +class EventTest extends TestCase +{ + /** + * @var \Symfony\Component\EventDispatcher\Event + */ + protected $event; + + /** + * @var \Symfony\Component\EventDispatcher\EventDispatcher + */ + protected $dispatcher; + + /** + * Sets up the fixture, for example, opens a network connection. + * This method is called before a test is executed. + */ + protected function setUp() + { + $this->event = new Event(); + $this->dispatcher = new EventDispatcher(); + } + + /** + * Tears down the fixture, for example, closes a network connection. + * This method is called after a test is executed. + */ + protected function tearDown() + { + $this->event = null; + $this->dispatcher = null; + } + + public function testIsPropagationStopped() + { + $this->assertFalse($this->event->isPropagationStopped()); + } + + public function testStopPropagationAndIsPropagationStopped() + { + $this->event->stopPropagation(); + $this->assertTrue($this->event->isPropagationStopped()); + } + + /** + * @group legacy + */ + public function testLegacySetDispatcher() + { + $this->event->setDispatcher($this->dispatcher); + $this->assertSame($this->dispatcher, $this->event->getDispatcher()); + } + + /** + * @group legacy + */ + public function testLegacyGetDispatcher() + { + $this->assertNull($this->event->getDispatcher()); + } + + /** + * @group legacy + */ + public function testLegacyGetName() + { + $this->assertNull($this->event->getName()); + } + + /** + * @group legacy + */ + public function testLegacySetName() + { + $this->event->setName('foo'); + $this->assertEquals('foo', $this->event->getName()); + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php b/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php new file mode 100644 index 000000000..c84d3ac24 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\GenericEvent; + +/** + * Test class for Event. + */ +class GenericEventTest extends TestCase +{ + /** + * @var GenericEvent + */ + private $event; + + private $subject; + + /** + * Prepares the environment before running a test. + */ + protected function setUp() + { + parent::setUp(); + + $this->subject = new \stdClass(); + $this->event = new GenericEvent($this->subject, array('name' => 'Event')); + } + + /** + * Cleans up the environment after running a test. + */ + protected function tearDown() + { + $this->subject = null; + $this->event = null; + + parent::tearDown(); + } + + public function testConstruct() + { + $this->assertEquals($this->event, new GenericEvent($this->subject, array('name' => 'Event'))); + } + + /** + * Tests Event->getArgs(). + */ + public function testGetArguments() + { + // test getting all + $this->assertSame(array('name' => 'Event'), $this->event->getArguments()); + } + + public function testSetArguments() + { + $result = $this->event->setArguments(array('foo' => 'bar')); + $this->assertAttributeSame(array('foo' => 'bar'), 'arguments', $this->event); + $this->assertSame($this->event, $result); + } + + public function testSetArgument() + { + $result = $this->event->setArgument('foo2', 'bar2'); + $this->assertAttributeSame(array('name' => 'Event', 'foo2' => 'bar2'), 'arguments', $this->event); + $this->assertEquals($this->event, $result); + } + + public function testGetArgument() + { + // test getting key + $this->assertEquals('Event', $this->event->getArgument('name')); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testGetArgException() + { + $this->event->getArgument('nameNotExist'); + } + + public function testOffsetGet() + { + // test getting key + $this->assertEquals('Event', $this->event['name']); + + // test getting invalid arg + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException'); + $this->assertFalse($this->event['nameNotExist']); + } + + public function testOffsetSet() + { + $this->event['foo2'] = 'bar2'; + $this->assertAttributeSame(array('name' => 'Event', 'foo2' => 'bar2'), 'arguments', $this->event); + } + + public function testOffsetUnset() + { + unset($this->event['name']); + $this->assertAttributeSame(array(), 'arguments', $this->event); + } + + public function testOffsetIsset() + { + $this->assertTrue(isset($this->event['name'])); + $this->assertFalse(isset($this->event['nameNotExist'])); + } + + public function testHasArgument() + { + $this->assertTrue($this->event->hasArgument('name')); + $this->assertFalse($this->event->hasArgument('nameNotExist')); + } + + public function testGetSubject() + { + $this->assertSame($this->subject, $this->event->getSubject()); + } + + public function testHasIterator() + { + $data = array(); + foreach ($this->event as $key => $value) { + $data[$key] = $value; + } + $this->assertEquals(array('name' => 'Event'), $data); + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php new file mode 100644 index 000000000..04f2861e3 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\ImmutableEventDispatcher; + +/** + * @author Bernhard Schussek + */ +class ImmutableEventDispatcherTest extends TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $innerDispatcher; + + /** + * @var ImmutableEventDispatcher + */ + private $dispatcher; + + protected function setUp() + { + $this->innerDispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); + $this->dispatcher = new ImmutableEventDispatcher($this->innerDispatcher); + } + + public function testDispatchDelegates() + { + $event = new Event(); + + $this->innerDispatcher->expects($this->once()) + ->method('dispatch') + ->with('event', $event) + ->will($this->returnValue('result')); + + $this->assertSame('result', $this->dispatcher->dispatch('event', $event)); + } + + public function testGetListenersDelegates() + { + $this->innerDispatcher->expects($this->once()) + ->method('getListeners') + ->with('event') + ->will($this->returnValue('result')); + + $this->assertSame('result', $this->dispatcher->getListeners('event')); + } + + public function testHasListenersDelegates() + { + $this->innerDispatcher->expects($this->once()) + ->method('hasListeners') + ->with('event') + ->will($this->returnValue('result')); + + $this->assertSame('result', $this->dispatcher->hasListeners('event')); + } + + /** + * @expectedException \BadMethodCallException + */ + public function testAddListenerDisallowed() + { + $this->dispatcher->addListener('event', function () { return 'foo'; }); + } + + /** + * @expectedException \BadMethodCallException + */ + public function testAddSubscriberDisallowed() + { + $subscriber = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventSubscriberInterface')->getMock(); + + $this->dispatcher->addSubscriber($subscriber); + } + + /** + * @expectedException \BadMethodCallException + */ + public function testRemoveListenerDisallowed() + { + $this->dispatcher->removeListener('event', function () { return 'foo'; }); + } + + /** + * @expectedException \BadMethodCallException + */ + public function testRemoveSubscriberDisallowed() + { + $subscriber = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventSubscriberInterface')->getMock(); + + $this->dispatcher->removeSubscriber($subscriber); + } +} diff --git a/vendor/symfony/event-dispatcher/phpunit.xml.dist b/vendor/symfony/event-dispatcher/phpunit.xml.dist index ae0586e0b..b3ad1bdf5 100644 --- a/vendor/symfony/event-dispatcher/phpunit.xml.dist +++ b/vendor/symfony/event-dispatcher/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/expression-language/Lexer.php b/vendor/symfony/expression-language/Lexer.php index 8c10b72d8..aeeda8a85 100644 --- a/vendor/symfony/expression-language/Lexer.php +++ b/vendor/symfony/expression-language/Lexer.php @@ -42,10 +42,10 @@ class Lexer continue; } - if (preg_match('/[0-9]+(?:\.[0-9]+)?/A', $expression, $match, null, $cursor)) { + if (preg_match('/[0-9]+(?:\.[0-9]+)?/A', $expression, $match, 0, $cursor)) { // numbers $number = (float) $match[0]; // floats - if (ctype_digit($match[0]) && $number <= PHP_INT_MAX) { + if (preg_match('/^[0-9]+$/', $match[0]) && $number <= PHP_INT_MAX) { $number = (int) $match[0]; // integers lower than the maximum } $tokens[] = new Token(Token::NUMBER_TYPE, $number, $cursor + 1); @@ -69,11 +69,11 @@ class Lexer $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); ++$cursor; - } elseif (preg_match('/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As', $expression, $match, null, $cursor)) { + } elseif (preg_match('/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As', $expression, $match, 0, $cursor)) { // strings $tokens[] = new Token(Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)), $cursor + 1); $cursor += strlen($match[0]); - } elseif (preg_match('/not in(?=[\s(])|\!\=\=|not(?=[\s(])|and(?=[\s(])|\=\=\=|\>\=|or(?=[\s(])|\<\=|\*\*|\.\.|in(?=[\s(])|&&|\|\||matches|\=\=|\!\=|\*|~|%|\/|\>|\||\!|\^|&|\+|\<|\-/A', $expression, $match, null, $cursor)) { + } elseif (preg_match('/not in(?=[\s(])|\!\=\=|not(?=[\s(])|and(?=[\s(])|\=\=\=|\>\=|or(?=[\s(])|\<\=|\*\*|\.\.|in(?=[\s(])|&&|\|\||matches|\=\=|\!\=|\*|~|%|\/|\>|\||\!|\^|&|\+|\<|\-/A', $expression, $match, 0, $cursor)) { // operators $tokens[] = new Token(Token::OPERATOR_TYPE, $match[0], $cursor + 1); $cursor += strlen($match[0]); @@ -81,7 +81,7 @@ class Lexer // punctuation $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); ++$cursor; - } elseif (preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $expression, $match, null, $cursor)) { + } elseif (preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $expression, $match, 0, $cursor)) { // names $tokens[] = new Token(Token::NAME_TYPE, $match[0], $cursor + 1); $cursor += strlen($match[0]); diff --git a/vendor/symfony/expression-language/Parser.php b/vendor/symfony/expression-language/Parser.php index 6f9045152..d847dfa4b 100644 --- a/vendor/symfony/expression-language/Parser.php +++ b/vendor/symfony/expression-language/Parser.php @@ -344,7 +344,7 @@ class Parser $node = new Node\GetAttrNode($node, $arg, $arguments, $type); } elseif ('[' === $token->value) { - if ($node instanceof Node\GetAttrNode && Node\GetAttrNode::METHOD_CALL === $node->attributes['type'] && PHP_VERSION_ID < 50400) { + if ($node instanceof Node\GetAttrNode && Node\GetAttrNode::METHOD_CALL === $node->attributes['type'] && \PHP_VERSION_ID < 50400) { throw new SyntaxError('Array calls on a method call is only supported on PHP 5.4+', $token->cursor, $this->stream->getExpression()); } diff --git a/vendor/symfony/expression-language/Token.php b/vendor/symfony/expression-language/Token.php index bb83d50a4..329273a84 100644 --- a/vendor/symfony/expression-language/Token.php +++ b/vendor/symfony/expression-language/Token.php @@ -32,7 +32,7 @@ class Token /** * Constructor. * - * @param int $type The type of the token + * @param string $type The type of the token (self::*_TYPE) * @param string $value The token value * @param int $cursor The cursor position in the source */ diff --git a/vendor/symfony/expression-language/phpunit.xml.dist b/vendor/symfony/expression-language/phpunit.xml.dist index 183770651..517322fb4 100644 --- a/vendor/symfony/expression-language/phpunit.xml.dist +++ b/vendor/symfony/expression-language/phpunit.xml.dist @@ -1,15 +1,12 @@ - diff --git a/vendor/symfony/filesystem/LockHandler.php b/vendor/symfony/filesystem/LockHandler.php index 67e6f8f52..3496faae2 100644 --- a/vendor/symfony/filesystem/LockHandler.php +++ b/vendor/symfony/filesystem/LockHandler.php @@ -68,8 +68,12 @@ class LockHandler return true; } + $error = null; + // Silence error reporting - set_error_handler(function () {}); + set_error_handler(function ($errno, $msg) use (&$error) { + $error = $msg; + }); if (!$this->handle = fopen($this->file, 'r')) { if ($this->handle = fopen($this->file, 'x')) { @@ -82,8 +86,7 @@ class LockHandler restore_error_handler(); if (!$this->handle) { - $error = error_get_last(); - throw new IOException($error['message'], 0, null, $this->file); + throw new IOException($error, 0, null, $this->file); } // On Windows, even if PHP doc says the contrary, LOCK_NB works, see diff --git a/vendor/symfony/filesystem/Tests/ExceptionTest.php b/vendor/symfony/filesystem/Tests/ExceptionTest.php new file mode 100644 index 000000000..5a04e0409 --- /dev/null +++ b/vendor/symfony/filesystem/Tests/ExceptionTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Exception\FileNotFoundException; + +/** + * Test class for Filesystem. + */ +class ExceptionTest extends TestCase +{ + public function testGetPath() + { + $e = new IOException('', 0, null, '/foo'); + $this->assertEquals('/foo', $e->getPath(), 'The pass should be returned.'); + } + + public function testGeneratedMessage() + { + $e = new FileNotFoundException(null, 0, null, '/foo'); + $this->assertEquals('/foo', $e->getPath()); + $this->assertEquals('File "/foo" could not be found.', $e->getMessage(), 'A message should be generated.'); + } + + public function testGeneratedMessageWithoutPath() + { + $e = new FileNotFoundException(); + $this->assertEquals('File could not be found.', $e->getMessage(), 'A message should be generated.'); + } + + public function testCustomMessage() + { + $e = new FileNotFoundException('bar', 0, null, '/foo'); + $this->assertEquals('bar', $e->getMessage(), 'A custom message should be possible still.'); + } +} diff --git a/vendor/symfony/filesystem/Tests/FilesystemTest.php b/vendor/symfony/filesystem/Tests/FilesystemTest.php new file mode 100644 index 000000000..11c064a75 --- /dev/null +++ b/vendor/symfony/filesystem/Tests/FilesystemTest.php @@ -0,0 +1,1249 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests; + +/** + * Test class for Filesystem. + */ +class FilesystemTest extends FilesystemTestCase +{ + public function testCopyCreatesNewFile() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFileExists($targetFilePath); + $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testCopyFails() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testCopyUnreadableFileFails() + { + // skip test on Windows; PHP can't easily set file as unreadable on Windows + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test cannot run on Windows.'); + } + + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + + // make sure target cannot be read + $this->filesystem->chmod($sourceFilePath, 0222); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + } + + public function testCopyOverridesExistingFileIfModified() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + touch($targetFilePath, time() - 1000); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFileExists($targetFilePath); + $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); + } + + public function testCopyDoesNotOverrideExistingFileByDefault() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + + // make sure both files have the same modification time + $modificationTime = time() - 1000; + touch($sourceFilePath, $modificationTime); + touch($targetFilePath, $modificationTime); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFileExists($targetFilePath); + $this->assertEquals('TARGET FILE', file_get_contents($targetFilePath)); + } + + public function testCopyOverridesExistingFileIfForced() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + + // make sure both files have the same modification time + $modificationTime = time() - 1000; + touch($sourceFilePath, $modificationTime); + touch($targetFilePath, $modificationTime); + + $this->filesystem->copy($sourceFilePath, $targetFilePath, true); + + $this->assertFileExists($targetFilePath); + $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testCopyWithOverrideWithReadOnlyTargetFails() + { + // skip test on Windows; PHP can't easily set file as unwritable on Windows + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test cannot run on Windows.'); + } + + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + + // make sure both files have the same modification time + $modificationTime = time() - 1000; + touch($sourceFilePath, $modificationTime); + touch($targetFilePath, $modificationTime); + + // make sure target is read-only + $this->filesystem->chmod($targetFilePath, 0444); + + $this->filesystem->copy($sourceFilePath, $targetFilePath, true); + } + + public function testCopyCreatesTargetDirectoryIfItDoesNotExist() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFileDirectory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; + $targetFilePath = $targetFileDirectory.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertTrue(is_dir($targetFileDirectory)); + $this->assertFileExists($targetFilePath); + $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); + } + + /** + * @group network + */ + public function testCopyForOriginUrlsAndExistingLocalFileDefaultsToCopy() + { + $sourceFilePath = 'http://symfony.com/images/common/logo/logo_symfony_header.png'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($targetFilePath, 'TARGET FILE'); + + $this->filesystem->copy($sourceFilePath, $targetFilePath, false); + + $this->assertFileExists($targetFilePath); + $this->assertEquals(file_get_contents($sourceFilePath), file_get_contents($targetFilePath)); + } + + public function testMkdirCreatesDirectoriesRecursively() + { + $directory = $this->workspace + .DIRECTORY_SEPARATOR.'directory' + .DIRECTORY_SEPARATOR.'sub_directory'; + + $this->filesystem->mkdir($directory); + + $this->assertTrue(is_dir($directory)); + } + + public function testMkdirCreatesDirectoriesFromArray() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $directories = array( + $basePath.'1', $basePath.'2', $basePath.'3', + ); + + $this->filesystem->mkdir($directories); + + $this->assertTrue(is_dir($basePath.'1')); + $this->assertTrue(is_dir($basePath.'2')); + $this->assertTrue(is_dir($basePath.'3')); + } + + public function testMkdirCreatesDirectoriesFromTraversableObject() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $directories = new \ArrayObject(array( + $basePath.'1', $basePath.'2', $basePath.'3', + )); + + $this->filesystem->mkdir($directories); + + $this->assertTrue(is_dir($basePath.'1')); + $this->assertTrue(is_dir($basePath.'2')); + $this->assertTrue(is_dir($basePath.'3')); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testMkdirCreatesDirectoriesFails() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $dir = $basePath.'2'; + + file_put_contents($dir, ''); + + $this->filesystem->mkdir($dir); + } + + public function testTouchCreatesEmptyFile() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'1'; + + $this->filesystem->touch($file); + + $this->assertFileExists($file); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testTouchFails() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR.'2'; + + $this->filesystem->touch($file); + } + + public function testTouchCreatesEmptyFilesFromArray() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $files = array( + $basePath.'1', $basePath.'2', $basePath.'3', + ); + + $this->filesystem->touch($files); + + $this->assertFileExists($basePath.'1'); + $this->assertFileExists($basePath.'2'); + $this->assertFileExists($basePath.'3'); + } + + public function testTouchCreatesEmptyFilesFromTraversableObject() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $files = new \ArrayObject(array( + $basePath.'1', $basePath.'2', $basePath.'3', + )); + + $this->filesystem->touch($files); + + $this->assertFileExists($basePath.'1'); + $this->assertFileExists($basePath.'2'); + $this->assertFileExists($basePath.'3'); + } + + public function testRemoveCleansFilesAndDirectoriesIteratively() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; + + mkdir($basePath); + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $this->filesystem->remove($basePath); + + $this->assertFileNotExists($basePath); + } + + public function testRemoveCleansArrayOfFilesAndDirectories() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $files = array( + $basePath.'dir', $basePath.'file', + ); + + $this->filesystem->remove($files); + + $this->assertFileNotExists($basePath.'dir'); + $this->assertFileNotExists($basePath.'file'); + } + + public function testRemoveCleansTraversableObjectOfFilesAndDirectories() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $files = new \ArrayObject(array( + $basePath.'dir', $basePath.'file', + )); + + $this->filesystem->remove($files); + + $this->assertFileNotExists($basePath.'dir'); + $this->assertFileNotExists($basePath.'file'); + } + + public function testRemoveIgnoresNonExistingFiles() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + + $files = array( + $basePath.'dir', $basePath.'file', + ); + + $this->filesystem->remove($files); + + $this->assertFileNotExists($basePath.'dir'); + } + + public function testRemoveCleansInvalidLinks() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; + + mkdir($basePath); + mkdir($basePath.'dir'); + // create symlink to nonexistent file + @symlink($basePath.'file', $basePath.'file-link'); + + // create symlink to dir using trailing forward slash + $this->filesystem->symlink($basePath.'dir/', $basePath.'dir-link'); + $this->assertTrue(is_dir($basePath.'dir-link')); + + // create symlink to nonexistent dir + rmdir($basePath.'dir'); + $this->assertFalse('\\' === DIRECTORY_SEPARATOR ? @readlink($basePath.'dir-link') : is_dir($basePath.'dir-link')); + + $this->filesystem->remove($basePath); + + $this->assertFileNotExists($basePath); + } + + public function testFilesExists() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; + + mkdir($basePath); + touch($basePath.'file1'); + mkdir($basePath.'folder'); + + $this->assertTrue($this->filesystem->exists($basePath.'file1')); + $this->assertTrue($this->filesystem->exists($basePath.'folder')); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testFilesExistsFails() + { + if ('\\' !== DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Test covers edge case on Windows only.'); + } + + $basePath = $this->workspace.'\\directory\\'; + + $oldPath = getcwd(); + mkdir($basePath); + chdir($basePath); + $file = str_repeat('T', 259 - strlen($basePath)); + $path = $basePath.$file; + exec('TYPE NUL >>'.$file); // equivalent of touch, we can not use the php touch() here because it suffers from the same limitation + $this->longPathNamesWindows[] = $path; // save this so we can clean up later + chdir($oldPath); + $this->filesystem->exists($path); + } + + public function testFilesExistsTraversableObjectOfFilesAndDirectories() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $files = new \ArrayObject(array( + $basePath.'dir', $basePath.'file', + )); + + $this->assertTrue($this->filesystem->exists($files)); + } + + public function testFilesNotExistsTraversableObjectOfFilesAndDirectories() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + touch($basePath.'file2'); + + $files = new \ArrayObject(array( + $basePath.'dir', $basePath.'file', $basePath.'file2', + )); + + unlink($basePath.'file'); + + $this->assertFalse($this->filesystem->exists($files)); + } + + public function testInvalidFileNotExists() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; + + $this->assertFalse($this->filesystem->exists($basePath.time())); + } + + public function testChmodChangesFileMode() + { + $this->markAsSkippedIfChmodIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chmod($file, 0400); + $this->filesystem->chmod($dir, 0753); + + $this->assertFilePermissions(753, $dir); + $this->assertFilePermissions(400, $file); + } + + public function testChmodWithWrongModLeavesPreviousPermissionsUntouched() + { + $this->markAsSkippedIfChmodIsMissing(); + + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('chmod() changes permissions even when passing invalid modes on HHVM'); + } + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'file'; + touch($dir); + + $permissions = fileperms($dir); + + $this->filesystem->chmod($dir, 'Wrongmode'); + + $this->assertSame($permissions, fileperms($dir)); + } + + public function testChmodRecursive() + { + $this->markAsSkippedIfChmodIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chmod($file, 0400, 0000, true); + $this->filesystem->chmod($dir, 0753, 0000, true); + + $this->assertFilePermissions(753, $dir); + $this->assertFilePermissions(753, $file); + } + + public function testChmodAppliesUmask() + { + $this->markAsSkippedIfChmodIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chmod($file, 0770, 0022); + $this->assertFilePermissions(750, $file); + } + + public function testChmodChangesModeOfArrayOfFiles() + { + $this->markAsSkippedIfChmodIsMissing(); + + $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $files = array($directory, $file); + + mkdir($directory); + touch($file); + + $this->filesystem->chmod($files, 0753); + + $this->assertFilePermissions(753, $file); + $this->assertFilePermissions(753, $directory); + } + + public function testChmodChangesModeOfTraversableFileObject() + { + $this->markAsSkippedIfChmodIsMissing(); + + $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $files = new \ArrayObject(array($directory, $file)); + + mkdir($directory); + touch($file); + + $this->filesystem->chmod($files, 0753); + + $this->assertFilePermissions(753, $file); + $this->assertFilePermissions(753, $directory); + } + + public function testChmodChangesZeroModeOnSubdirectoriesOnRecursive() + { + $this->markAsSkippedIfChmodIsMissing(); + + $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; + $subdirectory = $directory.DIRECTORY_SEPARATOR.'subdirectory'; + + mkdir($directory); + mkdir($subdirectory); + chmod($subdirectory, 0000); + + $this->filesystem->chmod($directory, 0753, 0000, true); + + $this->assertFilePermissions(753, $subdirectory); + } + + public function testChown() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $owner = $this->getFileOwner($dir); + $this->filesystem->chown($dir, $owner); + + $this->assertSame($owner, $this->getFileOwner($dir)); + } + + public function testChownRecursive() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $owner = $this->getFileOwner($dir); + $this->filesystem->chown($dir, $owner, true); + + $this->assertSame($owner, $this->getFileOwner($file)); + } + + public function testChownSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $owner = $this->getFileOwner($link); + $this->filesystem->chown($link, $owner); + + $this->assertSame($owner, $this->getFileOwner($link)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testChownSymlinkFails() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testChownFail() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $this->filesystem->chown($dir, 'user'.time().mt_rand(1000, 9999)); + } + + public function testChgrp() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $group = $this->getFileGroup($dir); + $this->filesystem->chgrp($dir, $group); + + $this->assertSame($group, $this->getFileGroup($dir)); + } + + public function testChgrpRecursive() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $group = $this->getFileGroup($dir); + $this->filesystem->chgrp($dir, $group, true); + + $this->assertSame($group, $this->getFileGroup($file)); + } + + public function testChgrpSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $group = $this->getFileGroup($link); + $this->filesystem->chgrp($link, $group); + + $this->assertSame($group, $this->getFileGroup($link)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testChgrpSymlinkFails() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testChgrpFail() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $this->filesystem->chgrp($dir, 'user'.time().mt_rand(1000, 9999)); + } + + public function testRename() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; + touch($file); + + $this->filesystem->rename($file, $newPath); + + $this->assertFileNotExists($file); + $this->assertFileExists($newPath); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testRenameThrowsExceptionIfTargetAlreadyExists() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; + + touch($file); + touch($newPath); + + $this->filesystem->rename($file, $newPath); + } + + public function testRenameOverwritesTheTargetIfItAlreadyExists() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; + + touch($file); + touch($newPath); + + $this->filesystem->rename($file, $newPath, true); + + $this->assertFileNotExists($file); + $this->assertFileExists($newPath); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testRenameThrowsExceptionOnError() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.uniqid('fs_test_', true); + $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; + + $this->filesystem->rename($file, $newPath); + } + + public function testSymlink() + { + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Windows does not support creating "broken" symlinks'); + } + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + // $file does not exists right now: creating "broken" links is a wanted feature + $this->filesystem->symlink($file, $link); + + $this->assertTrue(is_link($link)); + + // Create the linked file AFTER creating the link + touch($file); + + $this->assertEquals($file, readlink($link)); + } + + /** + * @depends testSymlink + */ + public function testRemoveSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + $this->filesystem->remove($link); + + $this->assertTrue(!is_link($link)); + $this->assertTrue(!is_file($link)); + $this->assertTrue(!is_dir($link)); + } + + public function testSymlinkIsOverwrittenIfPointsToDifferentTarget() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + symlink($this->workspace, $link); + + $this->filesystem->symlink($file, $link); + + $this->assertTrue(is_link($link)); + $this->assertEquals($file, readlink($link)); + } + + public function testSymlinkIsNotOverwrittenIfAlreadyCreated() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + symlink($file, $link); + + $this->filesystem->symlink($file, $link); + + $this->assertTrue(is_link($link)); + $this->assertEquals($file, readlink($link)); + } + + public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link1 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'link'; + $link2 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'subdir'.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link1); + $this->filesystem->symlink($file, $link2); + + $this->assertTrue(is_link($link1)); + $this->assertEquals($file, readlink($link1)); + $this->assertTrue(is_link($link2)); + $this->assertEquals($file, readlink($link2)); + } + + /** + * @dataProvider providePathsForMakePathRelative + */ + public function testMakePathRelative($endPath, $startPath, $expectedPath) + { + $path = $this->filesystem->makePathRelative($endPath, $startPath); + + $this->assertEquals($expectedPath, $path); + } + + /** + * @return array + */ + public function providePathsForMakePathRelative() + { + $paths = array( + array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'), + array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'), + array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'), + array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'), + array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'), + array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'), + array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'), + array('/aa/bb', '/aa/bb', './'), + array('/aa/bb', '/aa/bb/', './'), + array('/aa/bb/', '/aa/bb', './'), + array('/aa/bb/', '/aa/bb/', './'), + array('/aa/bb/cc', '/aa/bb/cc/dd', '../'), + array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'), + array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'), + array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'), + array('/aa/bb/cc', '/aa', 'bb/cc/'), + array('/aa/bb/cc', '/aa/', 'bb/cc/'), + array('/aa/bb/cc/', '/aa', 'bb/cc/'), + array('/aa/bb/cc/', '/aa/', 'bb/cc/'), + array('/a/aab/bb', '/a/aa', '../aab/bb/'), + array('/a/aab/bb', '/a/aa/', '../aab/bb/'), + array('/a/aab/bb/', '/a/aa', '../aab/bb/'), + array('/a/aab/bb/', '/a/aa/', '../aab/bb/'), + array('/a/aab/bb/', '/', 'a/aab/bb/'), + array('/a/aab/bb/', '/b/aab', '../../a/aab/bb/'), + array('/aab/bb', '/aa', '../aab/bb/'), + array('/aab', '/aa', '../aab/'), + array('/aa/bb/cc', '/aa/dd/..', 'bb/cc/'), + array('/aa/../bb/cc', '/aa/dd/..', '../bb/cc/'), + array('/aa/bb/../../cc', '/aa/../dd/..', 'cc/'), + array('/../aa/bb/cc', '/aa/dd/..', 'bb/cc/'), + array('/../../aa/../bb/cc', '/aa/dd/..', '../bb/cc/'), + array('C:/aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'), + array('c:/aa/../bb/cc', 'c:/aa/dd/..', '../bb/cc/'), + array('C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'), + array('C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'), + array('C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'), + ); + + if ('\\' === DIRECTORY_SEPARATOR) { + $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/'); + } + + return $paths; + } + + public function testMirrorCopiesFilesAndDirectoriesRecursively() + { + $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; + $directory = $sourcePath.'directory'.DIRECTORY_SEPARATOR; + $file1 = $directory.'file1'; + $file2 = $sourcePath.'file2'; + + mkdir($sourcePath); + mkdir($directory); + file_put_contents($file1, 'FILE1'); + file_put_contents($file2, 'FILE2'); + + $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertTrue(is_dir($targetPath)); + $this->assertTrue(is_dir($targetPath.'directory')); + $this->assertFileEquals($file1, $targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'); + $this->assertFileEquals($file2, $targetPath.'file2'); + + $this->filesystem->remove($file1); + + $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => false)); + $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); + + $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true)); + $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); + + file_put_contents($file1, 'FILE1'); + + $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true)); + $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); + + $this->filesystem->remove($directory); + $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true)); + $this->assertFalse($this->filesystem->exists($targetPath.'directory')); + $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); + } + + public function testMirrorCreatesEmptyDirectory() + { + $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; + + mkdir($sourcePath); + + $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertTrue(is_dir($targetPath)); + + $this->filesystem->remove($sourcePath); + } + + public function testMirrorCopiesLinks() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; + + mkdir($sourcePath); + file_put_contents($sourcePath.'file1', 'FILE1'); + symlink($sourcePath.'file1', $sourcePath.'link1'); + + $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertTrue(is_dir($targetPath)); + $this->assertFileEquals($sourcePath.'file1', $targetPath.'link1'); + $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); + } + + public function testMirrorCopiesLinkedDirectoryContents() + { + $this->markAsSkippedIfSymlinkIsMissing(true); + + $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; + + mkdir($sourcePath.'nested/', 0777, true); + file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1'); + // Note: We symlink directory, not file + symlink($sourcePath.'nested', $sourcePath.'link1'); + + $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertTrue(is_dir($targetPath)); + $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.'link1/file1.txt'); + $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); + } + + public function testMirrorCopiesRelativeLinkedContents() + { + $this->markAsSkippedIfSymlinkIsMissing(true); + + $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; + $oldPath = getcwd(); + + mkdir($sourcePath.'nested/', 0777, true); + file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1'); + // Note: Create relative symlink + chdir($sourcePath); + symlink('nested', 'link1'); + + chdir($oldPath); + + $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertTrue(is_dir($targetPath)); + $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.'link1/file1.txt'); + $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); + $this->assertEquals('\\' === DIRECTORY_SEPARATOR ? realpath($sourcePath.'\nested') : 'nested', readlink($targetPath.DIRECTORY_SEPARATOR.'link1')); + } + + /** + * @dataProvider providePathsForIsAbsolutePath + */ + public function testIsAbsolutePath($path, $expectedResult) + { + $result = $this->filesystem->isAbsolutePath($path); + + $this->assertEquals($expectedResult, $result); + } + + /** + * @return array + */ + public function providePathsForIsAbsolutePath() + { + return array( + array('/var/lib', true), + array('c:\\\\var\\lib', true), + array('\\var\\lib', true), + array('var/lib', false), + array('../var/lib', false), + array('', false), + array(null, false), + ); + } + + public function testTempnam() + { + $dirname = $this->workspace; + + $filename = $this->filesystem->tempnam($dirname, 'foo'); + + $this->assertFileExists($filename); + } + + public function testTempnamWithFileScheme() + { + $scheme = 'file://'; + $dirname = $scheme.$this->workspace; + + $filename = $this->filesystem->tempnam($dirname, 'foo'); + + $this->assertStringStartsWith($scheme, $filename); + $this->assertFileExists($filename); + } + + public function testTempnamWithMockScheme() + { + stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream'); + + $scheme = 'mock://'; + $dirname = $scheme.$this->workspace; + + $filename = $this->filesystem->tempnam($dirname, 'foo'); + + $this->assertStringStartsWith($scheme, $filename); + $this->assertFileExists($filename); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testTempnamWithZlibSchemeFails() + { + $scheme = 'compress.zlib://'; + $dirname = $scheme.$this->workspace; + + // The compress.zlib:// stream does not support mode x: creates the file, errors "failed to open stream: operation failed" and returns false + $this->filesystem->tempnam($dirname, 'bar'); + } + + public function testTempnamWithPHPTempSchemeFails() + { + $scheme = 'php://temp'; + $dirname = $scheme; + + $filename = $this->filesystem->tempnam($dirname, 'bar'); + + $this->assertStringStartsWith($scheme, $filename); + + // The php://temp stream deletes the file after close + $this->assertFileNotExists($filename); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testTempnamWithPharSchemeFails() + { + // Skip test if Phar disabled phar.readonly must be 0 in php.ini + if (!\Phar::canWrite()) { + $this->markTestSkipped('This test cannot run when phar.readonly is 1.'); + } + + $scheme = 'phar://'; + $dirname = $scheme.$this->workspace; + $pharname = 'foo.phar'; + + new \Phar($this->workspace.'/'.$pharname, 0, $pharname); + // The phar:// stream does not support mode x: fails to create file, errors "failed to open stream: phar error: "$filename" is not a file in phar "$pharname"" and returns false + $this->filesystem->tempnam($dirname, $pharname.'/bar'); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testTempnamWithHTTPSchemeFails() + { + $scheme = 'http://'; + $dirname = $scheme.$this->workspace; + + // The http:// scheme is read-only + $this->filesystem->tempnam($dirname, 'bar'); + } + + public function testTempnamOnUnwritableFallsBackToSysTmp() + { + $scheme = 'file://'; + $dirname = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'does_not_exist'; + + $filename = $this->filesystem->tempnam($dirname, 'bar'); + $realTempDir = realpath(sys_get_temp_dir()); + $this->assertStringStartsWith(rtrim($scheme.$realTempDir, DIRECTORY_SEPARATOR), $filename); + $this->assertFileExists($filename); + + // Tear down + @unlink($filename); + } + + public function testDumpFile() + { + $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; + + $this->filesystem->dumpFile($filename, 'bar'); + + $this->assertFileExists($filename); + $this->assertSame('bar', file_get_contents($filename)); + } + + /** + * @group legacy + */ + public function testDumpFileAndSetPermissions() + { + $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; + + $this->filesystem->dumpFile($filename, 'bar', 0753); + + $this->assertFileExists($filename); + $this->assertSame('bar', file_get_contents($filename)); + + // skip mode check on Windows + if ('\\' !== DIRECTORY_SEPARATOR) { + $this->assertFilePermissions(753, $filename); + } + } + + public function testDumpFileWithNullMode() + { + $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; + + $this->filesystem->dumpFile($filename, 'bar', null); + + $this->assertFileExists($filename); + $this->assertSame('bar', file_get_contents($filename)); + + // skip mode check on Windows + if ('\\' !== DIRECTORY_SEPARATOR) { + $this->assertFilePermissions(600, $filename); + } + } + + public function testDumpFileOverwritesAnExistingFile() + { + $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt'; + file_put_contents($filename, 'FOO BAR'); + + $this->filesystem->dumpFile($filename, 'bar'); + + $this->assertFileExists($filename); + $this->assertSame('bar', file_get_contents($filename)); + } + + public function testDumpFileWithFileScheme() + { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM does not handle the file:// scheme correctly'); + } + + $scheme = 'file://'; + $filename = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; + + $this->filesystem->dumpFile($filename, 'bar', null); + + $this->assertFileExists($filename); + $this->assertSame('bar', file_get_contents($filename)); + } + + public function testDumpFileWithZlibScheme() + { + $scheme = 'compress.zlib://'; + $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; + + $this->filesystem->dumpFile($filename, 'bar', null); + + // Zlib stat uses file:// wrapper so remove scheme + $this->assertFileExists(str_replace($scheme, '', $filename)); + $this->assertSame('bar', file_get_contents($filename)); + } + + public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile() + { + $this->markAsSkippedIfChmodIsMissing(); + + $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt'; + file_put_contents($filename, 'FOO BAR'); + chmod($filename, 0745); + + $this->filesystem->dumpFile($filename, 'bar', null); + + $this->assertFilePermissions(745, $filename); + } + + public function testCopyShouldKeepExecutionPermission() + { + $this->markAsSkippedIfChmodIsMissing(); + + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + chmod($sourceFilePath, 0745); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFilePermissions(767, $targetFilePath); + } +} diff --git a/vendor/symfony/filesystem/Tests/FilesystemTestCase.php b/vendor/symfony/filesystem/Tests/FilesystemTestCase.php new file mode 100644 index 000000000..5586a0054 --- /dev/null +++ b/vendor/symfony/filesystem/Tests/FilesystemTestCase.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Filesystem\Filesystem; + +class FilesystemTestCase extends TestCase +{ + private $umask; + + protected $longPathNamesWindows = array(); + + /** + * @var \Symfony\Component\Filesystem\Filesystem + */ + protected $filesystem = null; + + /** + * @var string + */ + protected $workspace = null; + + private static $symlinkOnWindows = null; + + public static function setUpBeforeClass() + { + if ('\\' === DIRECTORY_SEPARATOR && null === self::$symlinkOnWindows) { + $target = tempnam(sys_get_temp_dir(), 'sl'); + $link = sys_get_temp_dir().'/sl'.microtime(true).mt_rand(); + self::$symlinkOnWindows = @symlink($target, $link) && is_link($link); + @unlink($link); + unlink($target); + } + } + + protected function setUp() + { + $this->umask = umask(0); + $this->filesystem = new Filesystem(); + $this->workspace = sys_get_temp_dir().'/'.microtime(true).'.'.mt_rand(); + mkdir($this->workspace, 0777, true); + $this->workspace = realpath($this->workspace); + } + + protected function tearDown() + { + if (!empty($this->longPathNamesWindows)) { + foreach ($this->longPathNamesWindows as $path) { + exec('DEL '.$path); + } + $this->longPathNamesWindows = array(); + } + + $this->filesystem->remove($this->workspace); + umask($this->umask); + } + + /** + * @param int $expectedFilePerms expected file permissions as three digits (i.e. 755) + * @param string $filePath + */ + protected function assertFilePermissions($expectedFilePerms, $filePath) + { + $actualFilePerms = (int) substr(sprintf('%o', fileperms($filePath)), -3); + $this->assertEquals( + $expectedFilePerms, + $actualFilePerms, + sprintf('File permissions for %s must be %s. Actual %s', $filePath, $expectedFilePerms, $actualFilePerms) + ); + } + + protected function getFileOwner($filepath) + { + $this->markAsSkippedIfPosixIsMissing(); + + $infos = stat($filepath); + if ($datas = posix_getpwuid($infos['uid'])) { + return $datas['name']; + } + } + + protected function getFileGroup($filepath) + { + $this->markAsSkippedIfPosixIsMissing(); + + $infos = stat($filepath); + if ($datas = posix_getgrgid($infos['gid'])) { + return $datas['name']; + } + + $this->markTestSkipped('Unable to retrieve file group name'); + } + + protected function markAsSkippedIfSymlinkIsMissing($relative = false) + { + if ('\\' === DIRECTORY_SEPARATOR && false === self::$symlinkOnWindows) { + $this->markTestSkipped('symlink requires "Create symbolic links" privilege on Windows'); + } + + // https://bugs.php.net/bug.php?id=69473 + if ($relative && '\\' === DIRECTORY_SEPARATOR && 1 === PHP_ZTS) { + $this->markTestSkipped('symlink does not support relative paths on thread safe Windows PHP versions'); + } + } + + protected function markAsSkippedIfChmodIsMissing() + { + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('chmod is not supported on Windows'); + } + } + + protected function markAsSkippedIfPosixIsMissing() + { + if (!function_exists('posix_isatty')) { + $this->markTestSkipped('Function posix_isatty is required.'); + } + } +} diff --git a/vendor/symfony/filesystem/Tests/Fixtures/MockStream/MockStream.php b/vendor/symfony/filesystem/Tests/Fixtures/MockStream/MockStream.php new file mode 100644 index 000000000..f14420fb6 --- /dev/null +++ b/vendor/symfony/filesystem/Tests/Fixtures/MockStream/MockStream.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests\Fixtures\MockStream; + +/** + * Mock stream class to be used with stream_wrapper_register. + * stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream'). + */ +class MockStream +{ + /** + * Opens file or URL. + * + * @param string $path Specifies the URL that was passed to the original function + * @param string $mode The mode used to open the file, as detailed for fopen() + * @param int $options Holds additional flags set by the streams API + * @param string $opened_path If the path is opened successfully, and STREAM_USE_PATH is set in options, + * opened_path should be set to the full path of the file/resource that was actually opened + * + * @return bool + */ + public function stream_open($path, $mode, $options, &$opened_path) + { + return true; + } + + /** + * @param string $path The file path or URL to stat + * @param array $flags Holds additional flags set by the streams API + * + * @return array File stats + */ + public function url_stat($path, $flags) + { + return array(); + } +} diff --git a/vendor/symfony/filesystem/Tests/LockHandlerTest.php b/vendor/symfony/filesystem/Tests/LockHandlerTest.php new file mode 100644 index 000000000..0791cebc6 --- /dev/null +++ b/vendor/symfony/filesystem/Tests/LockHandlerTest.php @@ -0,0 +1,141 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Filesystem\LockHandler; + +class LockHandlerTest extends TestCase +{ + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + * @expectedExceptionMessage Failed to create "/a/b/c/d/e": mkdir(): Permission denied. + */ + public function testConstructWhenRepositoryDoesNotExist() + { + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + new LockHandler('lock', '/a/b/c/d/e'); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + * @expectedExceptionMessage The directory "/" is not writable. + */ + public function testConstructWhenRepositoryIsNotWriteable() + { + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + new LockHandler('lock', '/'); + } + + public function testErrorHandlingInLockIfLockPathBecomesUnwritable() + { + // skip test on Windows; PHP can't easily set file as unreadable on Windows + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test cannot run on Windows.'); + } + + $lockPath = sys_get_temp_dir().'/'.uniqid(); + $e = null; + $wrongMessage = null; + + try { + mkdir($lockPath); + + $lockHandler = new LockHandler('lock', $lockPath); + + chmod($lockPath, 0444); + + $lockHandler->lock(); + } catch (IOException $e) { + if (false === strpos($e->getMessage(), 'Permission denied')) { + $wrongMessage = $e->getMessage(); + } else { + $this->addToAssertionCount(1); + } + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + + if (is_dir($lockPath)) { + $fs = new Filesystem(); + $fs->remove($lockPath); + } + + $this->assertInstanceOf('Symfony\Component\Filesystem\Exception\IOException', $e, sprintf('Expected IOException to be thrown, got %s instead.', get_class($e))); + $this->assertNull($wrongMessage, sprintf('Expected exception message to contain "Permission denied", got "%s" instead.', $wrongMessage)); + } + + public function testConstructSanitizeName() + { + $lock = new LockHandler(''); + + $file = sprintf('%s/sf.-php-echo-hello-word-.4b3d9d0d27ddef3a78a64685dda3a963e478659a9e5240feaf7b4173a8f28d5f.lock', sys_get_temp_dir()); + // ensure the file does not exist before the lock + @unlink($file); + + $lock->lock(); + + $this->assertFileExists($file); + + $lock->release(); + } + + public function testLockRelease() + { + $name = 'symfony-test-filesystem.lock'; + + $l1 = new LockHandler($name); + $l2 = new LockHandler($name); + + $this->assertTrue($l1->lock()); + $this->assertFalse($l2->lock()); + + $l1->release(); + + $this->assertTrue($l2->lock()); + $l2->release(); + } + + public function testLockTwice() + { + $name = 'symfony-test-filesystem.lock'; + + $lockHandler = new LockHandler($name); + + $this->assertTrue($lockHandler->lock()); + $this->assertTrue($lockHandler->lock()); + + $lockHandler->release(); + } + + public function testLockIsReleased() + { + $name = 'symfony-test-filesystem.lock'; + + $l1 = new LockHandler($name); + $l2 = new LockHandler($name); + + $this->assertTrue($l1->lock()); + $this->assertFalse($l2->lock()); + + $l1 = null; + + $this->assertTrue($l2->lock()); + $l2->release(); + } +} diff --git a/vendor/symfony/filesystem/phpunit.xml.dist b/vendor/symfony/filesystem/phpunit.xml.dist index d066ed796..7bba6fc2f 100644 --- a/vendor/symfony/filesystem/phpunit.xml.dist +++ b/vendor/symfony/filesystem/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/finder/Iterator/FilterIterator.php b/vendor/symfony/finder/Iterator/FilterIterator.php index 3c3c3fbec..acb98361c 100644 --- a/vendor/symfony/finder/Iterator/FilterIterator.php +++ b/vendor/symfony/finder/Iterator/FilterIterator.php @@ -29,7 +29,7 @@ abstract class FilterIterator extends \FilterIterator */ public function rewind() { - if (PHP_VERSION_ID > 50607 || (PHP_VERSION_ID > 50523 && PHP_VERSION_ID < 50600)) { + if (\PHP_VERSION_ID > 50607 || (\PHP_VERSION_ID > 50523 && \PHP_VERSION_ID < 50600)) { parent::rewind(); return; diff --git a/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php b/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php index 1df2f5014..c87096fc8 100644 --- a/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php +++ b/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php @@ -119,7 +119,7 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator } // @see https://bugs.php.net/68557 - if (PHP_VERSION_ID < 50523 || PHP_VERSION_ID >= 50600 && PHP_VERSION_ID < 50607) { + if (\PHP_VERSION_ID < 50523 || \PHP_VERSION_ID >= 50600 && \PHP_VERSION_ID < 50607) { parent::next(); } diff --git a/vendor/symfony/finder/Tests/BsdFinderTest.php b/vendor/symfony/finder/Tests/BsdFinderTest.php new file mode 100644 index 000000000..a7d800616 --- /dev/null +++ b/vendor/symfony/finder/Tests/BsdFinderTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests; + +use Symfony\Component\Finder\Adapter\BsdFindAdapter; +use Symfony\Component\Finder\Finder; + +/** + * @group legacy + */ +class BsdFinderTest extends FinderTest +{ + protected function buildFinder() + { + $adapter = new BsdFindAdapter(); + + if (!$adapter->isSupported()) { + $this->markTestSkipped(get_class($adapter).' is not supported.'); + } + + return Finder::create() + ->removeAdapters() + ->addAdapter($adapter); + } +} diff --git a/vendor/symfony/finder/Tests/Comparator/ComparatorTest.php b/vendor/symfony/finder/Tests/Comparator/ComparatorTest.php new file mode 100644 index 000000000..656fc57a4 --- /dev/null +++ b/vendor/symfony/finder/Tests/Comparator/ComparatorTest.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Comparator; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Comparator\Comparator; + +class ComparatorTest extends TestCase +{ + public function testGetSetOperator() + { + $comparator = new Comparator(); + try { + $comparator->setOperator('foo'); + $this->fail('->setOperator() throws an \InvalidArgumentException if the operator is not valid.'); + } catch (\Exception $e) { + $this->assertInstanceOf('InvalidArgumentException', $e, '->setOperator() throws an \InvalidArgumentException if the operator is not valid.'); + } + + $comparator = new Comparator(); + $comparator->setOperator('>'); + $this->assertEquals('>', $comparator->getOperator(), '->getOperator() returns the current operator'); + } + + public function testGetSetTarget() + { + $comparator = new Comparator(); + $comparator->setTarget(8); + $this->assertEquals(8, $comparator->getTarget(), '->getTarget() returns the target'); + } + + /** + * @dataProvider getTestData + */ + public function testTest($operator, $target, $match, $noMatch) + { + $c = new Comparator(); + $c->setOperator($operator); + $c->setTarget($target); + + foreach ($match as $m) { + $this->assertTrue($c->test($m), '->test() tests a string against the expression'); + } + + foreach ($noMatch as $m) { + $this->assertFalse($c->test($m), '->test() tests a string against the expression'); + } + } + + public function getTestData() + { + return array( + array('<', '1000', array('500', '999'), array('1000', '1500')), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Comparator/DateComparatorTest.php b/vendor/symfony/finder/Tests/Comparator/DateComparatorTest.php new file mode 100644 index 000000000..8a6c1ddfd --- /dev/null +++ b/vendor/symfony/finder/Tests/Comparator/DateComparatorTest.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Comparator; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Comparator\DateComparator; + +class DateComparatorTest extends TestCase +{ + public function testConstructor() + { + try { + new DateComparator('foobar'); + $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.'); + } catch (\Exception $e) { + $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.'); + } + + try { + new DateComparator(''); + $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.'); + } catch (\Exception $e) { + $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.'); + } + } + + /** + * @dataProvider getTestData + */ + public function testTest($test, $match, $noMatch) + { + $c = new DateComparator($test); + + foreach ($match as $m) { + $this->assertTrue($c->test($m), '->test() tests a string against the expression'); + } + + foreach ($noMatch as $m) { + $this->assertFalse($c->test($m), '->test() tests a string against the expression'); + } + } + + public function getTestData() + { + return array( + array('< 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))), + array('until 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))), + array('before 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))), + array('> 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))), + array('after 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))), + array('since 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))), + array('!= 2005-10-10', array(strtotime('2005-10-11')), array(strtotime('2005-10-10'))), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Comparator/NumberComparatorTest.php b/vendor/symfony/finder/Tests/Comparator/NumberComparatorTest.php new file mode 100644 index 000000000..30a75c738 --- /dev/null +++ b/vendor/symfony/finder/Tests/Comparator/NumberComparatorTest.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Comparator; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Comparator\NumberComparator; + +class NumberComparatorTest extends TestCase +{ + /** + * @dataProvider getConstructorTestData + */ + public function testConstructor($successes, $failures) + { + foreach ($successes as $s) { + new NumberComparator($s); + } + + foreach ($failures as $f) { + try { + new NumberComparator($f); + $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.'); + } catch (\Exception $e) { + $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.'); + } + } + } + + /** + * @dataProvider getTestData + */ + public function testTest($test, $match, $noMatch) + { + $c = new NumberComparator($test); + + foreach ($match as $m) { + $this->assertTrue($c->test($m), '->test() tests a string against the expression'); + } + + foreach ($noMatch as $m) { + $this->assertFalse($c->test($m), '->test() tests a string against the expression'); + } + } + + public function getTestData() + { + return array( + array('< 1000', array('500', '999'), array('1000', '1500')), + + array('< 1K', array('500', '999'), array('1000', '1500')), + array('<1k', array('500', '999'), array('1000', '1500')), + array(' < 1 K ', array('500', '999'), array('1000', '1500')), + array('<= 1K', array('1000'), array('1001')), + array('> 1K', array('1001'), array('1000')), + array('>= 1K', array('1000'), array('999')), + + array('< 1KI', array('500', '1023'), array('1024', '1500')), + array('<= 1KI', array('1024'), array('1025')), + array('> 1KI', array('1025'), array('1024')), + array('>= 1KI', array('1024'), array('1023')), + + array('1KI', array('1024'), array('1023', '1025')), + array('==1KI', array('1024'), array('1023', '1025')), + + array('==1m', array('1000000'), array('999999', '1000001')), + array('==1mi', array(1024 * 1024), array(1024 * 1024 - 1, 1024 * 1024 + 1)), + + array('==1g', array('1000000000'), array('999999999', '1000000001')), + array('==1gi', array(1024 * 1024 * 1024), array(1024 * 1024 * 1024 - 1, 1024 * 1024 * 1024 + 1)), + + array('!= 1000', array('500', '999'), array('1000')), + ); + } + + public function getConstructorTestData() + { + return array( + array( + array( + '1', '0', + '3.5', '33.55', '123.456', '123456.78', + '.1', '.123', + '.0', '0.0', + '1.', '0.', '123.', + '==1', '!=1', '<1', '>1', '<=1', '>=1', + '==1k', '==1ki', '==1m', '==1mi', '==1g', '==1gi', + '1k', '1ki', '1m', '1mi', '1g', '1gi', + ), + array( + false, null, '', + ' ', 'foobar', + '=1', '===1', + '0 . 1', '123 .45', '234. 567', + '..', '.0.', '0.1.2', + ), + ), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Expression/ExpressionTest.php b/vendor/symfony/finder/Tests/Expression/ExpressionTest.php new file mode 100644 index 000000000..a34e37d3c --- /dev/null +++ b/vendor/symfony/finder/Tests/Expression/ExpressionTest.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Expression; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Expression\Expression; + +/** + * @group legacy + */ +class ExpressionTest extends TestCase +{ + /** + * @dataProvider getTypeGuesserData + */ + public function testTypeGuesser($expr, $type) + { + $this->assertEquals($type, Expression::create($expr)->getType()); + } + + /** + * @dataProvider getCaseSensitiveData + */ + public function testCaseSensitive($expr, $isCaseSensitive) + { + $this->assertEquals($isCaseSensitive, Expression::create($expr)->isCaseSensitive()); + } + + /** + * @dataProvider getRegexRenderingData + */ + public function testRegexRendering($expr, $body) + { + $this->assertEquals($body, Expression::create($expr)->renderPattern()); + } + + public function getTypeGuesserData() + { + return array( + array('{foo}', Expression::TYPE_REGEX), + array('/foo/', Expression::TYPE_REGEX), + array('foo', Expression::TYPE_GLOB), + array('foo*', Expression::TYPE_GLOB), + ); + } + + public function getCaseSensitiveData() + { + return array( + array('{foo}m', true), + array('/foo/i', false), + array('foo*', true), + ); + } + + public function getRegexRenderingData() + { + return array( + array('{foo}m', 'foo'), + array('/foo/i', 'foo'), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Expression/GlobTest.php b/vendor/symfony/finder/Tests/Expression/GlobTest.php new file mode 100644 index 000000000..bd4c5f084 --- /dev/null +++ b/vendor/symfony/finder/Tests/Expression/GlobTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Expression; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Expression\Expression; + +/** + * @group legacy + */ +class GlobTest extends TestCase +{ + /** + * @dataProvider getToRegexData + */ + public function testGlobToRegex($glob, $match, $noMatch) + { + foreach ($match as $m) { + $this->assertRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp'); + } + + foreach ($noMatch as $m) { + $this->assertNotRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp'); + } + } + + public function getToRegexData() + { + return array( + array('', array(''), array('f', '/')), + array('*', array('foo'), array('foo/', '/foo')), + array('foo.*', array('foo.php', 'foo.a', 'foo.'), array('fooo.php', 'foo.php/foo')), + array('fo?', array('foo', 'fot'), array('fooo', 'ffoo', 'fo/')), + array('fo{o,t}', array('foo', 'fot'), array('fob', 'fo/')), + array('foo(bar|foo)', array('foo(bar|foo)'), array('foobar', 'foofoo')), + array('foo,bar', array('foo,bar'), array('foo', 'bar')), + array('fo{o,\\,}', array('foo', 'fo,'), array()), + array('fo{o,\\\\}', array('foo', 'fo\\'), array()), + array('/foo', array('/foo'), array('foo')), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Expression/RegexTest.php b/vendor/symfony/finder/Tests/Expression/RegexTest.php new file mode 100644 index 000000000..9c0032173 --- /dev/null +++ b/vendor/symfony/finder/Tests/Expression/RegexTest.php @@ -0,0 +1,147 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Expression; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Expression\Expression; + +/** + * @group legacy + */ +class RegexTest extends TestCase +{ + /** + * @dataProvider getHasFlagsData + */ + public function testHasFlags($regex, $start, $end) + { + $expr = new Expression($regex); + + $this->assertEquals($start, $expr->getRegex()->hasStartFlag()); + $this->assertEquals($end, $expr->getRegex()->hasEndFlag()); + } + + /** + * @dataProvider getHasJokersData + */ + public function testHasJokers($regex, $start, $end) + { + $expr = new Expression($regex); + + $this->assertEquals($start, $expr->getRegex()->hasStartJoker()); + $this->assertEquals($end, $expr->getRegex()->hasEndJoker()); + } + + /** + * @dataProvider getSetFlagsData + */ + public function testSetFlags($regex, $start, $end, $expected) + { + $expr = new Expression($regex); + $expr->getRegex()->setStartFlag($start)->setEndFlag($end); + + $this->assertEquals($expected, $expr->render()); + } + + /** + * @dataProvider getSetJokersData + */ + public function testSetJokers($regex, $start, $end, $expected) + { + $expr = new Expression($regex); + $expr->getRegex()->setStartJoker($start)->setEndJoker($end); + + $this->assertEquals($expected, $expr->render()); + } + + public function testOptions() + { + $expr = new Expression('~abc~is'); + $expr->getRegex()->removeOption('i')->addOption('m'); + + $this->assertEquals('~abc~sm', $expr->render()); + } + + public function testMixFlagsAndJokers() + { + $expr = new Expression('~^.*abc.*$~is'); + + $expr->getRegex()->setStartFlag(false)->setEndFlag(false)->setStartJoker(false)->setEndJoker(false); + $this->assertEquals('~abc~is', $expr->render()); + + $expr->getRegex()->setStartFlag(true)->setEndFlag(true)->setStartJoker(true)->setEndJoker(true); + $this->assertEquals('~^.*abc.*$~is', $expr->render()); + } + + /** + * @dataProvider getReplaceJokersTestData + */ + public function testReplaceJokers($regex, $expected) + { + $expr = new Expression($regex); + $expr = $expr->getRegex()->replaceJokers('@'); + + $this->assertEquals($expected, $expr->renderPattern()); + } + + public function getHasFlagsData() + { + return array( + array('~^abc~', true, false), + array('~abc$~', false, true), + array('~abc~', false, false), + array('~^abc$~', true, true), + array('~^abc\\$~', true, false), + ); + } + + public function getHasJokersData() + { + return array( + array('~.*abc~', true, false), + array('~abc.*~', false, true), + array('~abc~', false, false), + array('~.*abc.*~', true, true), + array('~.*abc\\.*~', true, false), + ); + } + + public function getSetFlagsData() + { + return array( + array('~abc~', true, false, '~^abc~'), + array('~abc~', false, true, '~abc$~'), + array('~abc~', false, false, '~abc~'), + array('~abc~', true, true, '~^abc$~'), + ); + } + + public function getSetJokersData() + { + return array( + array('~abc~', true, false, '~.*abc~'), + array('~abc~', false, true, '~abc.*~'), + array('~abc~', false, false, '~abc~'), + array('~abc~', true, true, '~.*abc.*~'), + ); + } + + public function getReplaceJokersTestData() + { + return array( + array('~.abc~', '@abc'), + array('~\\.abc~', '\\.abc'), + array('~\\\\.abc~', '\\\\@abc'), + array('~\\\\\\.abc~', '\\\\\\.abc'), + ); + } +} diff --git a/vendor/symfony/finder/Tests/FakeAdapter/DummyAdapter.php b/vendor/symfony/finder/Tests/FakeAdapter/DummyAdapter.php new file mode 100644 index 000000000..0cbae14b8 --- /dev/null +++ b/vendor/symfony/finder/Tests/FakeAdapter/DummyAdapter.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\FakeAdapter; + +use Symfony\Component\Finder\Adapter\AbstractAdapter; + +/** + * @author Jean-François Simon + */ +class DummyAdapter extends AbstractAdapter +{ + /** + * @var \Iterator + */ + private $iterator; + + /** + * @param \Iterator $iterator + */ + public function __construct(\Iterator $iterator) + { + $this->iterator = $iterator; + } + + /** + * {@inheritdoc} + */ + public function searchInDirectory($dir) + { + return $this->iterator; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'yes'; + } + + /** + * {@inheritdoc} + */ + protected function canBeUsed() + { + return true; + } +} diff --git a/vendor/symfony/finder/Tests/FakeAdapter/FailingAdapter.php b/vendor/symfony/finder/Tests/FakeAdapter/FailingAdapter.php new file mode 100644 index 000000000..6e6ed24b6 --- /dev/null +++ b/vendor/symfony/finder/Tests/FakeAdapter/FailingAdapter.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\FakeAdapter; + +use Symfony\Component\Finder\Adapter\AbstractAdapter; +use Symfony\Component\Finder\Exception\AdapterFailureException; + +/** + * @author Jean-François Simon + */ +class FailingAdapter extends AbstractAdapter +{ + /** + * {@inheritdoc} + */ + public function searchInDirectory($dir) + { + throw new AdapterFailureException($this); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'failing'; + } + + /** + * {@inheritdoc} + */ + protected function canBeUsed() + { + return true; + } +} diff --git a/vendor/symfony/finder/Tests/FakeAdapter/NamedAdapter.php b/vendor/symfony/finder/Tests/FakeAdapter/NamedAdapter.php new file mode 100644 index 000000000..5a260b0df --- /dev/null +++ b/vendor/symfony/finder/Tests/FakeAdapter/NamedAdapter.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\FakeAdapter; + +use Symfony\Component\Finder\Adapter\AbstractAdapter; + +/** + * @author Jean-François Simon + */ +class NamedAdapter extends AbstractAdapter +{ + /** + * @var string + */ + private $name; + + /** + * @param string $name + */ + public function __construct($name) + { + $this->name = $name; + } + + /** + * {@inheritdoc} + */ + public function searchInDirectory($dir) + { + return new \ArrayIterator(array()); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->name; + } + + /** + * {@inheritdoc} + */ + protected function canBeUsed() + { + return true; + } +} diff --git a/vendor/symfony/finder/Tests/FakeAdapter/UnsupportedAdapter.php b/vendor/symfony/finder/Tests/FakeAdapter/UnsupportedAdapter.php new file mode 100644 index 000000000..1f91b98a6 --- /dev/null +++ b/vendor/symfony/finder/Tests/FakeAdapter/UnsupportedAdapter.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\FakeAdapter; + +use Symfony\Component\Finder\Adapter\AbstractAdapter; + +/** + * @author Jean-François Simon + */ +class UnsupportedAdapter extends AbstractAdapter +{ + /** + * {@inheritdoc} + */ + public function searchInDirectory($dir) + { + return new \ArrayIterator(array()); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'unsupported'; + } + + /** + * {@inheritdoc} + */ + protected function canBeUsed() + { + return false; + } +} diff --git a/vendor/symfony/finder/Tests/FinderTest.php b/vendor/symfony/finder/Tests/FinderTest.php new file mode 100644 index 000000000..859dd5a30 --- /dev/null +++ b/vendor/symfony/finder/Tests/FinderTest.php @@ -0,0 +1,749 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests; + +use Symfony\Component\Finder\Adapter\AdapterInterface; +use Symfony\Component\Finder\Adapter\GnuFindAdapter; +use Symfony\Component\Finder\Adapter\PhpAdapter; +use Symfony\Component\Finder\Finder; + +class FinderTest extends Iterator\RealIteratorTestCase +{ + public function testCreate() + { + $this->assertInstanceOf('Symfony\Component\Finder\Finder', Finder::create()); + } + + public function testDirectories() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->directories()); + $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->directories(); + $finder->files(); + $finder->directories(); + $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testFiles() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->files()); + $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->files(); + $finder->directories(); + $finder->files(); + $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testDepth() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->depth('< 1')); + $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->depth('<= 0')); + $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->depth('>= 1')); + $this->assertIterator($this->toAbsolute(array('foo/bar.tmp')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->depth('< 1')->depth('>= 1'); + $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testName() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->name('*.php')); + $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->name('test.ph*'); + $finder->name('test.py'); + $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->name('~^test~i'); + $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->name('~\\.php$~i'); + $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->name('test.p{hp,y}'); + $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testNotName() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->notName('*.php')); + $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->notName('*.php'); + $finder->notName('*.py'); + $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->name('test.ph*'); + $finder->name('test.py'); + $finder->notName('*.php'); + $finder->notName('*.py'); + $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->name('test.ph*'); + $finder->name('test.py'); + $finder->notName('*.p{hp,y}'); + $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator()); + } + + /** + * @dataProvider getRegexNameTestData + */ + public function testRegexName($regex) + { + $finder = $this->buildFinder(); + $finder->name($regex); + $this->assertIterator($this->toAbsolute(array('test.py', 'test.php')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testSize() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->files()->size('< 1K')->size('> 500')); + $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testDate() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->files()->date('until last month')); + $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testExclude() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->exclude('foo')); + $this->assertIterator($this->toAbsolute(array('test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testIgnoreVCS() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->ignoreVCS(false)->ignoreDotFiles(false)); + $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->ignoreVCS(false)->ignoreVCS(false)->ignoreDotFiles(false); + $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->ignoreVCS(true)->ignoreDotFiles(false)); + $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testIgnoreDotFiles() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->ignoreDotFiles(false)->ignoreVCS(false)); + $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $finder->ignoreDotFiles(false)->ignoreDotFiles(false)->ignoreVCS(false); + $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->ignoreDotFiles(true)->ignoreVCS(false)); + $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testSortByName() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->sortByName()); + $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testSortByType() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->sortByType()); + $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'toto', 'foo/bar.tmp', 'test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testSortByAccessedTime() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->sortByAccessedTime()); + $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testSortByChangedTime() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->sortByChangedTime()); + $this->assertIterator($this->toAbsolute(array('toto', 'test.py', 'test.php', 'foo/bar.tmp', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testSortByModifiedTime() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->sortByModifiedTime()); + $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testSort() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); })); + $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testFilter() + { + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->filter(function (\SplFileInfo $f) { return false !== strpos($f, 'test'); })); + $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testFollowLinks() + { + if ('\\' == DIRECTORY_SEPARATOR) { + $this->markTestSkipped('symlinks are not supported on Windows'); + } + + $finder = $this->buildFinder(); + $this->assertSame($finder, $finder->followLinks()); + $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator()); + } + + public function testIn() + { + $finder = $this->buildFinder(); + $iterator = $finder->files()->name('*.php')->depth('< 1')->in(array(self::$tmpDir, __DIR__))->getIterator(); + + $expected = array( + self::$tmpDir.DIRECTORY_SEPARATOR.'test.php', + __DIR__.DIRECTORY_SEPARATOR.'BsdFinderTest.php', + __DIR__.DIRECTORY_SEPARATOR.'FinderTest.php', + __DIR__.DIRECTORY_SEPARATOR.'GnuFinderTest.php', + __DIR__.DIRECTORY_SEPARATOR.'PhpFinderTest.php', + __DIR__.DIRECTORY_SEPARATOR.'GlobTest.php', + ); + + $this->assertIterator($expected, $iterator); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInWithNonExistentDirectory() + { + $finder = new Finder(); + $finder->in('foobar'); + } + + public function testInWithGlob() + { + $finder = $this->buildFinder(); + $finder->in(array(__DIR__.'/Fixtures/*/B/C', __DIR__.'/Fixtures/*/*/B/C'))->getIterator(); + + $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInWithNonDirectoryGlob() + { + $finder = new Finder(); + $finder->in(__DIR__.'/Fixtures/A/a*'); + } + + public function testInWithGlobBrace() + { + $finder = $this->buildFinder(); + $finder->in(array(__DIR__.'/Fixtures/{A,copy/A}/B/C'))->getIterator(); + + $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder); + } + + /** + * @expectedException \LogicException + */ + public function testGetIteratorWithoutIn() + { + $finder = Finder::create(); + $finder->getIterator(); + } + + public function testGetIterator() + { + $finder = $this->buildFinder(); + $dirs = array(); + foreach ($finder->directories()->in(self::$tmpDir) as $dir) { + $dirs[] = (string) $dir; + } + + $expected = $this->toAbsolute(array('foo', 'toto')); + + sort($dirs); + sort($expected); + + $this->assertEquals($expected, $dirs, 'implements the \IteratorAggregate interface'); + + $finder = $this->buildFinder(); + $this->assertEquals(2, iterator_count($finder->directories()->in(self::$tmpDir)), 'implements the \IteratorAggregate interface'); + + $finder = $this->buildFinder(); + $a = iterator_to_array($finder->directories()->in(self::$tmpDir)); + $a = array_values(array_map('strval', $a)); + sort($a); + $this->assertEquals($expected, $a, 'implements the \IteratorAggregate interface'); + } + + public function testRelativePath() + { + $finder = $this->buildFinder()->in(self::$tmpDir); + + $paths = array(); + + foreach ($finder as $file) { + $paths[] = $file->getRelativePath(); + } + + $ref = array('', '', '', '', 'foo', ''); + + sort($ref); + sort($paths); + + $this->assertEquals($ref, $paths); + } + + public function testRelativePathname() + { + $finder = $this->buildFinder()->in(self::$tmpDir)->sortByName(); + + $paths = array(); + + foreach ($finder as $file) { + $paths[] = $file->getRelativePathname(); + } + + $ref = array('test.php', 'toto', 'test.py', 'foo', 'foo'.DIRECTORY_SEPARATOR.'bar.tmp', 'foo bar'); + + sort($paths); + sort($ref); + + $this->assertEquals($ref, $paths); + } + + public function testAppendWithAFinder() + { + $finder = $this->buildFinder(); + $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo'); + + $finder1 = $this->buildFinder(); + $finder1->directories()->in(self::$tmpDir); + + $finder = $finder->append($finder1); + + $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator()); + } + + public function testAppendWithAnArray() + { + $finder = $this->buildFinder(); + $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo'); + + $finder->append($this->toAbsolute(array('foo', 'toto'))); + + $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator()); + } + + public function testAppendReturnsAFinder() + { + $this->assertInstanceOf('Symfony\\Component\\Finder\\Finder', Finder::create()->append(array())); + } + + public function testAppendDoesNotRequireIn() + { + $finder = $this->buildFinder(); + $finder->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo'); + + $finder1 = Finder::create()->append($finder); + + $this->assertIterator(iterator_to_array($finder->getIterator()), $finder1->getIterator()); + } + + public function testCountDirectories() + { + $directory = Finder::create()->directories()->in(self::$tmpDir); + $i = 0; + + foreach ($directory as $dir) { + ++$i; + } + + $this->assertCount($i, $directory); + } + + public function testCountFiles() + { + $files = Finder::create()->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'); + $i = 0; + + foreach ($files as $file) { + ++$i; + } + + $this->assertCount($i, $files); + } + + /** + * @expectedException \LogicException + */ + public function testCountWithoutIn() + { + $finder = Finder::create()->files(); + count($finder); + } + + /** + * @dataProvider getContainsTestData + */ + public function testContains($matchPatterns, $noMatchPatterns, $expected) + { + $finder = $this->buildFinder(); + $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures') + ->name('*.txt')->sortByName() + ->contains($matchPatterns) + ->notContains($noMatchPatterns); + + $this->assertIterator($this->toAbsoluteFixtures($expected), $finder); + } + + public function testContainsOnDirectory() + { + $finder = $this->buildFinder(); + $finder->in(__DIR__) + ->directories() + ->name('Fixtures') + ->contains('abc'); + $this->assertIterator(array(), $finder); + } + + public function testNotContainsOnDirectory() + { + $finder = $this->buildFinder(); + $finder->in(__DIR__) + ->directories() + ->name('Fixtures') + ->notContains('abc'); + $this->assertIterator(array(), $finder); + } + + /** + * Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator + * with inner FilesystemIterator in an invalid state. + * + * @see https://bugs.php.net/68557 + */ + public function testMultipleLocations() + { + $locations = array( + self::$tmpDir.'/', + self::$tmpDir.'/toto/', + ); + + // it is expected that there are test.py test.php in the tmpDir + $finder = new Finder(); + $finder->in($locations) + // the default flag IGNORE_DOT_FILES fixes the problem indirectly + // so we set it to false for better isolation + ->ignoreDotFiles(false) + ->depth('< 1')->name('test.php'); + + $this->assertCount(1, $finder); + } + + /** + * Searching in multiple locations with sub directories involves + * AppendIterator which does an unnecessary rewind which leaves + * FilterIterator with inner FilesystemIterator in an invalid state. + * + * @see https://bugs.php.net/68557 + */ + public function testMultipleLocationsWithSubDirectories() + { + $locations = array( + __DIR__.'/Fixtures/one', + self::$tmpDir.DIRECTORY_SEPARATOR.'toto', + ); + + $finder = $this->buildFinder(); + $finder->in($locations)->depth('< 10')->name('*.neon'); + + $expected = array( + __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'c.neon', + __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'d.neon', + ); + + $this->assertIterator($expected, $finder); + $this->assertIteratorInForeach($expected, $finder); + } + + /** + * Iterator keys must be the file pathname. + */ + public function testIteratorKeys() + { + $finder = $this->buildFinder()->in(self::$tmpDir); + foreach ($finder as $key => $file) { + $this->assertEquals($file->getPathname(), $key); + } + } + + public function testRegexSpecialCharsLocationWithPathRestrictionContainingStartFlag() + { + $finder = $this->buildFinder(); + $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'r+e.gex[c]a(r)s') + ->path('/^dir/'); + + $expected = array('r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir', 'r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'bar.dat'); + $this->assertIterator($this->toAbsoluteFixtures($expected), $finder); + } + + /** + * @group legacy + */ + public function testAdaptersOrdering() + { + $finder = Finder::create() + ->removeAdapters() + ->addAdapter(new FakeAdapter\NamedAdapter('a'), 0) + ->addAdapter(new FakeAdapter\NamedAdapter('b'), -50) + ->addAdapter(new FakeAdapter\NamedAdapter('c'), 50) + ->addAdapter(new FakeAdapter\NamedAdapter('d'), -25) + ->addAdapter(new FakeAdapter\NamedAdapter('e'), 25); + + $this->assertEquals( + array('c', 'e', 'a', 'd', 'b'), + array_map(function (AdapterInterface $adapter) { + return $adapter->getName(); + }, $finder->getAdapters()) + ); + } + + /** + * @group legacy + */ + public function testAdaptersChaining() + { + $iterator = new \ArrayIterator(array()); + $filenames = $this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')); + foreach ($filenames as $file) { + $iterator->append(new \Symfony\Component\Finder\SplFileInfo($file, null, null)); + } + + $finder = Finder::create() + ->removeAdapters() + ->addAdapter(new FakeAdapter\UnsupportedAdapter(), 3) + ->addAdapter(new FakeAdapter\FailingAdapter(), 2) + ->addAdapter(new FakeAdapter\DummyAdapter($iterator), 1); + + $this->assertIterator($filenames, $finder->in(sys_get_temp_dir())->getIterator()); + } + + public function getContainsTestData() + { + return array( + array('', '', array()), + array('foo', 'bar', array()), + array('', 'foobar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')), + array('lorem ipsum dolor sit amet', 'foobar', array('lorem.txt')), + array('sit', 'bar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')), + array('dolor sit amet', '@^L@m', array('dolor.txt', 'ipsum.txt')), + array('/^lorem ipsum dolor sit amet$/m', 'foobar', array('lorem.txt')), + array('lorem', 'foobar', array('lorem.txt')), + array('', 'lorem', array('dolor.txt', 'ipsum.txt')), + array('ipsum dolor sit amet', '/^IPSUM/m', array('lorem.txt')), + ); + } + + public function getRegexNameTestData() + { + return array( + array('~.+\\.p.+~i'), + array('~t.*s~i'), + ); + } + + /** + * @dataProvider getTestPathData + */ + public function testPath($matchPatterns, $noMatchPatterns, array $expected) + { + $finder = $this->buildFinder(); + $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures') + ->path($matchPatterns) + ->notPath($noMatchPatterns); + + $this->assertIterator($this->toAbsoluteFixtures($expected), $finder); + } + + /** + * @group legacy + */ + public function testAdapterSelection() + { + // test that by default, PhpAdapter is selected + $adapters = Finder::create()->getAdapters(); + $this->assertTrue($adapters[0] instanceof PhpAdapter); + + // test another adapter selection + $adapters = Finder::create()->setAdapter('gnu_find')->getAdapters(); + $this->assertTrue($adapters[0] instanceof GnuFindAdapter); + + // test that useBestAdapter method removes selection + $adapters = Finder::create()->useBestAdapter()->getAdapters(); + $this->assertFalse($adapters[0] instanceof PhpAdapter); + } + + public function getTestPathData() + { + return array( + array('', '', array()), + array('/^A\/B\/C/', '/C$/', + array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat'), + ), + array('/^A\/B/', 'foobar', + array( + 'A'.DIRECTORY_SEPARATOR.'B', + 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C', + 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat', + 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat', + ), + ), + array('A/B/C', 'foobar', + array( + 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C', + 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat', + 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C', + 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy', + ), + ), + array('A/B', 'foobar', + array( + //dirs + 'A'.DIRECTORY_SEPARATOR.'B', + 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C', + 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B', + 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C', + //files + 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat', + 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat', + 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat.copy', + 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy', + ), + ), + array('/^with space\//', 'foobar', + array( + 'with space'.DIRECTORY_SEPARATOR.'foo.txt', + ), + ), + ); + } + + public function testAccessDeniedException() + { + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('chmod is not supported on Windows'); + } + + $finder = $this->buildFinder(); + $finder->files()->in(self::$tmpDir); + + // make 'foo' directory non-readable + $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo'; + chmod($testDir, 0333); + + if (false === $couldRead = is_readable($testDir)) { + try { + $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator()); + $this->fail('Finder should throw an exception when opening a non-readable directory.'); + } catch (\Exception $e) { + $expectedExceptionClass = 'Symfony\\Component\\Finder\\Exception\\AccessDeniedException'; + if ($e instanceof \PHPUnit_Framework_ExpectationFailedException) { + $this->fail(sprintf("Expected exception:\n%s\nGot:\n%s\nWith comparison failure:\n%s", $expectedExceptionClass, 'PHPUnit_Framework_ExpectationFailedException', $e->getComparisonFailure()->getExpectedAsString())); + } + + if ($e instanceof \PHPUnit\Framework\ExpectationFailedException) { + $this->fail(sprintf("Expected exception:\n%s\nGot:\n%s\nWith comparison failure:\n%s", $expectedExceptionClass, '\PHPUnit\Framework\ExpectationFailedException', $e->getComparisonFailure()->getExpectedAsString())); + } + + $this->assertInstanceOf($expectedExceptionClass, $e); + } + } + + // restore original permissions + chmod($testDir, 0777); + clearstatcache($testDir); + + if ($couldRead) { + $this->markTestSkipped('could read test files while test requires unreadable'); + } + } + + public function testIgnoredAccessDeniedException() + { + if ('\\' === DIRECTORY_SEPARATOR) { + $this->markTestSkipped('chmod is not supported on Windows'); + } + + $finder = $this->buildFinder(); + $finder->files()->ignoreUnreadableDirs()->in(self::$tmpDir); + + // make 'foo' directory non-readable + $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo'; + chmod($testDir, 0333); + + if (false === ($couldRead = is_readable($testDir))) { + $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator()); + } + + // restore original permissions + chmod($testDir, 0777); + clearstatcache($testDir); + + if ($couldRead) { + $this->markTestSkipped('could read test files while test requires unreadable'); + } + } + + protected function buildFinder() + { + return Finder::create(); + } +} diff --git a/vendor/symfony/finder/Tests/Fixtures/A/B/C/abc.dat b/vendor/symfony/finder/Tests/Fixtures/A/B/C/abc.dat new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/A/B/ab.dat b/vendor/symfony/finder/Tests/Fixtures/A/B/ab.dat new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/A/a.dat b/vendor/symfony/finder/Tests/Fixtures/A/a.dat new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy b/vendor/symfony/finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/copy/A/B/ab.dat.copy b/vendor/symfony/finder/Tests/Fixtures/copy/A/B/ab.dat.copy new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/copy/A/a.dat.copy b/vendor/symfony/finder/Tests/Fixtures/copy/A/a.dat.copy new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/dolor.txt b/vendor/symfony/finder/Tests/Fixtures/dolor.txt new file mode 100644 index 000000000..658bec698 --- /dev/null +++ b/vendor/symfony/finder/Tests/Fixtures/dolor.txt @@ -0,0 +1,2 @@ +dolor sit amet +DOLOR SIT AMET \ No newline at end of file diff --git a/vendor/symfony/finder/Tests/Fixtures/ipsum.txt b/vendor/symfony/finder/Tests/Fixtures/ipsum.txt new file mode 100644 index 000000000..c7f392d6f --- /dev/null +++ b/vendor/symfony/finder/Tests/Fixtures/ipsum.txt @@ -0,0 +1,2 @@ +ipsum dolor sit amet +IPSUM DOLOR SIT AMET \ No newline at end of file diff --git a/vendor/symfony/finder/Tests/Fixtures/lorem.txt b/vendor/symfony/finder/Tests/Fixtures/lorem.txt new file mode 100644 index 000000000..2991a2cac --- /dev/null +++ b/vendor/symfony/finder/Tests/Fixtures/lorem.txt @@ -0,0 +1,2 @@ +lorem ipsum dolor sit amet +LOREM IPSUM DOLOR SIT AMET \ No newline at end of file diff --git a/vendor/symfony/finder/Tests/Fixtures/one/a b/vendor/symfony/finder/Tests/Fixtures/one/a new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/one/b/c.neon b/vendor/symfony/finder/Tests/Fixtures/one/b/c.neon new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/one/b/d.neon b/vendor/symfony/finder/Tests/Fixtures/one/b/d.neon new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat b/vendor/symfony/finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/Fixtures/with space/foo.txt b/vendor/symfony/finder/Tests/Fixtures/with space/foo.txt new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/symfony/finder/Tests/GlobTest.php b/vendor/symfony/finder/Tests/GlobTest.php new file mode 100644 index 000000000..b81151e1e --- /dev/null +++ b/vendor/symfony/finder/Tests/GlobTest.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Glob; + +class GlobTest extends TestCase +{ + public function testGlobToRegexDelimiters() + { + $this->assertEquals('#^(?=[^\.])\#$#', Glob::toRegex('#')); + $this->assertEquals('#^\.[^/]*$#', Glob::toRegex('.*')); + $this->assertEquals('^\.[^/]*$', Glob::toRegex('.*', true, true, '')); + $this->assertEquals('/^\.[^/]*$/', Glob::toRegex('.*', true, true, '/')); + } +} diff --git a/vendor/symfony/finder/Tests/GnuFinderTest.php b/vendor/symfony/finder/Tests/GnuFinderTest.php new file mode 100644 index 000000000..81b14d302 --- /dev/null +++ b/vendor/symfony/finder/Tests/GnuFinderTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests; + +use Symfony\Component\Finder\Adapter\GnuFindAdapter; +use Symfony\Component\Finder\Finder; + +/** + * @group legacy + */ +class GnuFinderTest extends FinderTest +{ + protected function buildFinder() + { + $adapter = new GnuFindAdapter(); + + if (!$adapter->isSupported()) { + $this->markTestSkipped(get_class($adapter).' is not supported.'); + } + + return Finder::create() + ->removeAdapters() + ->addAdapter($adapter); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/CustomFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/CustomFilterIteratorTest.php new file mode 100644 index 000000000..b036ad13c --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/CustomFilterIteratorTest.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\CustomFilterIterator; + +class CustomFilterIteratorTest extends IteratorTestCase +{ + /** + * @expectedException \InvalidArgumentException + */ + public function testWithInvalidFilter() + { + new CustomFilterIterator(new Iterator(), array('foo')); + } + + /** + * @dataProvider getAcceptData + */ + public function testAccept($filters, $expected) + { + $inner = new Iterator(array('test.php', 'test.py', 'foo.php')); + + $iterator = new CustomFilterIterator($inner, $filters); + + $this->assertIterator($expected, $iterator); + } + + public function getAcceptData() + { + return array( + array(array(function (\SplFileInfo $fileinfo) { return false; }), array()), + array(array(function (\SplFileInfo $fileinfo) { return 0 === strpos($fileinfo, 'test'); }), array('test.php', 'test.py')), + array(array('is_dir'), array()), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/DateRangeFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/DateRangeFilterIteratorTest.php new file mode 100644 index 000000000..1ec705182 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/DateRangeFilterIteratorTest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\DateRangeFilterIterator; +use Symfony\Component\Finder\Comparator\DateComparator; + +class DateRangeFilterIteratorTest extends RealIteratorTestCase +{ + /** + * @dataProvider getAcceptData + */ + public function testAccept($size, $expected) + { + $files = self::$files; + $files[] = self::toAbsolute('doesnotexist'); + $inner = new Iterator($files); + + $iterator = new DateRangeFilterIterator($inner, $size); + + $this->assertIterator($expected, $iterator); + } + + public function getAcceptData() + { + $since20YearsAgo = array( + '.git', + 'test.py', + 'foo', + 'foo/bar.tmp', + 'test.php', + 'toto', + 'toto/.git', + '.bar', + '.foo', + '.foo/.bar', + 'foo bar', + '.foo/bar', + ); + + $since2MonthsAgo = array( + '.git', + 'test.py', + 'foo', + 'toto', + 'toto/.git', + '.bar', + '.foo', + '.foo/.bar', + 'foo bar', + '.foo/bar', + ); + + $untilLastMonth = array( + 'foo/bar.tmp', + 'test.php', + ); + + return array( + array(array(new DateComparator('since 20 years ago')), $this->toAbsolute($since20YearsAgo)), + array(array(new DateComparator('since 2 months ago')), $this->toAbsolute($since2MonthsAgo)), + array(array(new DateComparator('until last month')), $this->toAbsolute($untilLastMonth)), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/DepthRangeFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/DepthRangeFilterIteratorTest.php new file mode 100644 index 000000000..2e9014053 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/DepthRangeFilterIteratorTest.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator; + +class DepthRangeFilterIteratorTest extends RealIteratorTestCase +{ + /** + * @dataProvider getAcceptData + */ + public function testAccept($minDepth, $maxDepth, $expected) + { + $inner = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST); + + $iterator = new DepthRangeFilterIterator($inner, $minDepth, $maxDepth); + + $actual = array_keys(iterator_to_array($iterator)); + sort($expected); + sort($actual); + $this->assertEquals($expected, $actual); + } + + public function getAcceptData() + { + $lessThan1 = array( + '.git', + 'test.py', + 'foo', + 'test.php', + 'toto', + '.foo', + '.bar', + 'foo bar', + ); + + $lessThanOrEqualTo1 = array( + '.git', + 'test.py', + 'foo', + 'foo/bar.tmp', + 'test.php', + 'toto', + 'toto/.git', + '.foo', + '.foo/.bar', + '.bar', + 'foo bar', + '.foo/bar', + ); + + $graterThanOrEqualTo1 = array( + 'toto/.git', + 'foo/bar.tmp', + '.foo/.bar', + '.foo/bar', + ); + + $equalTo1 = array( + 'toto/.git', + 'foo/bar.tmp', + '.foo/.bar', + '.foo/bar', + ); + + return array( + array(0, 0, $this->toAbsolute($lessThan1)), + array(0, 1, $this->toAbsolute($lessThanOrEqualTo1)), + array(2, PHP_INT_MAX, array()), + array(1, PHP_INT_MAX, $this->toAbsolute($graterThanOrEqualTo1)), + array(1, 1, $this->toAbsolute($equalTo1)), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php new file mode 100644 index 000000000..fa192c31f --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator; +use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator; + +class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase +{ + /** + * @dataProvider getAcceptData + */ + public function testAccept($directories, $expected) + { + $inner = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST); + + $iterator = new ExcludeDirectoryFilterIterator($inner, $directories); + + $this->assertIterator($expected, $iterator); + } + + public function getAcceptData() + { + $foo = array( + '.bar', + '.foo', + '.foo/.bar', + '.foo/bar', + '.git', + 'test.py', + 'test.php', + 'toto', + 'toto/.git', + 'foo bar', + ); + + $fo = array( + '.bar', + '.foo', + '.foo/.bar', + '.foo/bar', + '.git', + 'test.py', + 'foo', + 'foo/bar.tmp', + 'test.php', + 'toto', + 'toto/.git', + 'foo bar', + ); + + $toto = array( + '.bar', + '.foo', + '.foo/.bar', + '.foo/bar', + '.git', + 'test.py', + 'foo', + 'foo/bar.tmp', + 'test.php', + 'foo bar', + ); + + return array( + array(array('foo'), $this->toAbsolute($foo)), + array(array('fo'), $this->toAbsolute($fo)), + array(array('toto/'), $this->toAbsolute($toto)), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/FilePathsIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/FilePathsIteratorTest.php new file mode 100644 index 000000000..ab52ccee3 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/FilePathsIteratorTest.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\FilePathsIterator; + +/** + * @group legacy + */ +class FilePathsIteratorTest extends RealIteratorTestCase +{ + /** + * @dataProvider getSubPathData + */ + public function testSubPath($baseDir, array $paths, array $subPaths, array $subPathnames) + { + $iterator = new FilePathsIterator($paths, $baseDir); + + foreach ($iterator as $index => $file) { + $this->assertEquals($paths[$index], $file->getPathname()); + $this->assertEquals($subPaths[$index], $iterator->getSubPath()); + $this->assertEquals($subPathnames[$index], $iterator->getSubPathname()); + } + } + + public function getSubPathData() + { + $tmpDir = sys_get_temp_dir().'/symfony_finder'; + + return array( + array( + $tmpDir, + array( + // paths + $tmpDir.DIRECTORY_SEPARATOR.'.git' => $tmpDir.DIRECTORY_SEPARATOR.'.git', + $tmpDir.DIRECTORY_SEPARATOR.'test.py' => $tmpDir.DIRECTORY_SEPARATOR.'test.py', + $tmpDir.DIRECTORY_SEPARATOR.'foo' => $tmpDir.DIRECTORY_SEPARATOR.'foo', + $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp', + $tmpDir.DIRECTORY_SEPARATOR.'test.php' => $tmpDir.DIRECTORY_SEPARATOR.'test.php', + $tmpDir.DIRECTORY_SEPARATOR.'toto' => $tmpDir.DIRECTORY_SEPARATOR.'toto', + ), + array( + // subPaths + $tmpDir.DIRECTORY_SEPARATOR.'.git' => '', + $tmpDir.DIRECTORY_SEPARATOR.'test.py' => '', + $tmpDir.DIRECTORY_SEPARATOR.'foo' => '', + $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo', + $tmpDir.DIRECTORY_SEPARATOR.'test.php' => '', + $tmpDir.DIRECTORY_SEPARATOR.'toto' => '', + ), + array( + // subPathnames + $tmpDir.DIRECTORY_SEPARATOR.'.git' => '.git', + $tmpDir.DIRECTORY_SEPARATOR.'test.py' => 'test.py', + $tmpDir.DIRECTORY_SEPARATOR.'foo' => 'foo', + $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo'.DIRECTORY_SEPARATOR.'bar.tmp', + $tmpDir.DIRECTORY_SEPARATOR.'test.php' => 'test.php', + $tmpDir.DIRECTORY_SEPARATOR.'toto' => 'toto', + ), + ), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/FileTypeFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/FileTypeFilterIteratorTest.php new file mode 100644 index 000000000..4350b00ca --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/FileTypeFilterIteratorTest.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\FileTypeFilterIterator; + +class FileTypeFilterIteratorTest extends RealIteratorTestCase +{ + /** + * @dataProvider getAcceptData + */ + public function testAccept($mode, $expected) + { + $inner = new InnerTypeIterator(self::$files); + + $iterator = new FileTypeFilterIterator($inner, $mode); + + $this->assertIterator($expected, $iterator); + } + + public function getAcceptData() + { + $onlyFiles = array( + 'test.py', + 'foo/bar.tmp', + 'test.php', + '.bar', + '.foo/.bar', + '.foo/bar', + 'foo bar', + ); + + $onlyDirectories = array( + '.git', + 'foo', + 'toto', + 'toto/.git', + '.foo', + ); + + return array( + array(FileTypeFilterIterator::ONLY_FILES, $this->toAbsolute($onlyFiles)), + array(FileTypeFilterIterator::ONLY_DIRECTORIES, $this->toAbsolute($onlyDirectories)), + ); + } +} + +class InnerTypeIterator extends \ArrayIterator +{ + public function current() + { + return new \SplFileInfo(parent::current()); + } + + public function isFile() + { + return $this->current()->isFile(); + } + + public function isDir() + { + return $this->current()->isDir(); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/FilecontentFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/FilecontentFilterIteratorTest.php new file mode 100644 index 000000000..744bdae12 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/FilecontentFilterIteratorTest.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\FilecontentFilterIterator; + +class FilecontentFilterIteratorTest extends IteratorTestCase +{ + public function testAccept() + { + $inner = new MockFileListIterator(array('test.txt')); + $iterator = new FilecontentFilterIterator($inner, array(), array()); + $this->assertIterator(array('test.txt'), $iterator); + } + + public function testDirectory() + { + $inner = new MockFileListIterator(array('directory')); + $iterator = new FilecontentFilterIterator($inner, array('directory'), array()); + $this->assertIterator(array(), $iterator); + } + + public function testUnreadableFile() + { + $inner = new MockFileListIterator(array('file r-')); + $iterator = new FilecontentFilterIterator($inner, array('file r-'), array()); + $this->assertIterator(array(), $iterator); + } + + /** + * @dataProvider getTestFilterData + */ + public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray) + { + $iterator = new FilecontentFilterIterator($inner, $matchPatterns, $noMatchPatterns); + $this->assertIterator($resultArray, $iterator); + } + + public function getTestFilterData() + { + $inner = new MockFileListIterator(); + + $inner[] = new MockSplFileInfo(array( + 'name' => 'a.txt', + 'contents' => 'Lorem ipsum...', + 'type' => 'file', + 'mode' => 'r+', ) + ); + + $inner[] = new MockSplFileInfo(array( + 'name' => 'b.yml', + 'contents' => 'dolor sit...', + 'type' => 'file', + 'mode' => 'r+', ) + ); + + $inner[] = new MockSplFileInfo(array( + 'name' => 'some/other/dir/third.php', + 'contents' => 'amet...', + 'type' => 'file', + 'mode' => 'r+', ) + ); + + $inner[] = new MockSplFileInfo(array( + 'name' => 'unreadable-file.txt', + 'contents' => false, + 'type' => 'file', + 'mode' => 'r+', ) + ); + + return array( + array($inner, array('.'), array(), array('a.txt', 'b.yml', 'some/other/dir/third.php')), + array($inner, array('ipsum'), array(), array('a.txt')), + array($inner, array('i', 'amet'), array('Lorem', 'amet'), array('b.yml')), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/FilenameFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/FilenameFilterIteratorTest.php new file mode 100644 index 000000000..c4b979591 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/FilenameFilterIteratorTest.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\FilenameFilterIterator; + +class FilenameFilterIteratorTest extends IteratorTestCase +{ + /** + * @dataProvider getAcceptData + */ + public function testAccept($matchPatterns, $noMatchPatterns, $expected) + { + $inner = new InnerNameIterator(array('test.php', 'test.py', 'foo.php')); + + $iterator = new FilenameFilterIterator($inner, $matchPatterns, $noMatchPatterns); + + $this->assertIterator($expected, $iterator); + } + + public function getAcceptData() + { + return array( + array(array('test.*'), array(), array('test.php', 'test.py')), + array(array(), array('test.*'), array('foo.php')), + array(array('*.php'), array('test.*'), array('foo.php')), + array(array('*.php', '*.py'), array('foo.*'), array('test.php', 'test.py')), + array(array('/\.php$/'), array(), array('test.php', 'foo.php')), + array(array(), array('/\.php$/'), array('test.py')), + ); + } +} + +class InnerNameIterator extends \ArrayIterator +{ + public function current() + { + return new \SplFileInfo(parent::current()); + } + + public function getFilename() + { + return parent::current(); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/FilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/FilterIteratorTest.php new file mode 100644 index 000000000..4f12d142e --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/FilterIteratorTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +/** + * @author Alex Bogomazov + */ +class FilterIteratorTest extends RealIteratorTestCase +{ + public function testFilterFilesystemIterators() + { + $i = new \FilesystemIterator($this->toAbsolute()); + + // it is expected that there are test.py test.php in the tmpDir + $i = $this->getMockForAbstractClass('Symfony\Component\Finder\Iterator\FilterIterator', array($i)); + $i->expects($this->any()) + ->method('accept') + ->will($this->returnCallback(function () use ($i) { + return (bool) preg_match('/\.php/', (string) $i->current()); + }) + ); + + $c = 0; + foreach ($i as $item) { + ++$c; + } + + $this->assertEquals(1, $c); + + $i->rewind(); + + $c = 0; + foreach ($i as $item) { + ++$c; + } + + // This would fail in php older than 5.5.23/5.6.7 with \FilterIterator + // but works with Symfony\Component\Finder\Iterator\FilterIterator + // see https://bugs.php.net/68557 + $this->assertEquals(1, $c); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/Iterator.php b/vendor/symfony/finder/Tests/Iterator/Iterator.php new file mode 100644 index 000000000..849bf081e --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/Iterator.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +class Iterator implements \Iterator +{ + protected $values = array(); + + public function __construct(array $values = array()) + { + foreach ($values as $value) { + $this->attach(new \SplFileInfo($value)); + } + $this->rewind(); + } + + public function attach(\SplFileInfo $fileinfo) + { + $this->values[] = $fileinfo; + } + + public function rewind() + { + reset($this->values); + } + + public function valid() + { + return false !== $this->current(); + } + + public function next() + { + next($this->values); + } + + public function current() + { + return current($this->values); + } + + public function key() + { + return key($this->values); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/IteratorTestCase.php b/vendor/symfony/finder/Tests/Iterator/IteratorTestCase.php new file mode 100644 index 000000000..c724a75c6 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/IteratorTestCase.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use PHPUnit\Framework\TestCase; + +abstract class IteratorTestCase extends TestCase +{ + protected function assertIterator($expected, \Traversable $iterator) + { + // set iterator_to_array $use_key to false to avoid values merge + // this made FinderTest::testAppendWithAnArray() fail with GnuFinderAdapter + $values = array_map(function (\SplFileInfo $fileinfo) { return str_replace('/', DIRECTORY_SEPARATOR, $fileinfo->getPathname()); }, iterator_to_array($iterator, false)); + + $expected = array_map(function ($path) { return str_replace('/', DIRECTORY_SEPARATOR, $path); }, $expected); + + sort($values); + sort($expected); + + $this->assertEquals($expected, array_values($values)); + } + + protected function assertOrderedIterator($expected, \Traversable $iterator) + { + $values = array_map(function (\SplFileInfo $fileinfo) { return $fileinfo->getPathname(); }, iterator_to_array($iterator)); + + $this->assertEquals($expected, array_values($values)); + } + + /** + * Same as assertOrderedIterator, but checks the order of groups of + * array elements. + * + * @param array $expected - an array of arrays. For any two subarrays + * $a and $b such that $a goes before $b in $expected, the method + * asserts that any element of $a goes before any element of $b + * in the sequence generated by $iterator + * @param \Traversable $iterator + */ + protected function assertOrderedIteratorForGroups($expected, \Traversable $iterator) + { + $values = array_values(array_map(function (\SplFileInfo $fileinfo) { return $fileinfo->getPathname(); }, iterator_to_array($iterator))); + + foreach ($expected as $subarray) { + $temp = array(); + while (count($values) && count($temp) < count($subarray)) { + $temp[] = array_shift($values); + } + sort($temp); + sort($subarray); + $this->assertEquals($subarray, $temp); + } + } + + /** + * Same as IteratorTestCase::assertIterator with foreach usage. + * + * @param array $expected + * @param \Traversable $iterator + */ + protected function assertIteratorInForeach($expected, \Traversable $iterator) + { + $values = array(); + foreach ($iterator as $file) { + $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file); + $values[] = $file->getPathname(); + } + + sort($values); + sort($expected); + + $this->assertEquals($expected, array_values($values)); + } + + /** + * Same as IteratorTestCase::assertOrderedIterator with foreach usage. + * + * @param array $expected + * @param \Traversable $iterator + */ + protected function assertOrderedIteratorInForeach($expected, \Traversable $iterator) + { + $values = array(); + foreach ($iterator as $file) { + $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file); + $values[] = $file->getPathname(); + } + + $this->assertEquals($expected, array_values($values)); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/MockFileListIterator.php b/vendor/symfony/finder/Tests/Iterator/MockFileListIterator.php new file mode 100644 index 000000000..eb0adfad0 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/MockFileListIterator.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +class MockFileListIterator extends \ArrayIterator +{ + public function __construct(array $filesArray = array()) + { + $files = array_map(function ($file) { return new MockSplFileInfo($file); }, $filesArray); + parent::__construct($files); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/MockSplFileInfo.php b/vendor/symfony/finder/Tests/Iterator/MockSplFileInfo.php new file mode 100644 index 000000000..d03a9ac78 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/MockSplFileInfo.php @@ -0,0 +1,132 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +class MockSplFileInfo extends \SplFileInfo +{ + const TYPE_DIRECTORY = 1; + const TYPE_FILE = 2; + const TYPE_UNKNOWN = 3; + + private $contents = null; + private $mode = null; + private $type = null; + private $relativePath = null; + private $relativePathname = null; + + public function __construct($param) + { + if (is_string($param)) { + parent::__construct($param); + } elseif (is_array($param)) { + $defaults = array( + 'name' => 'file.txt', + 'contents' => null, + 'mode' => null, + 'type' => null, + 'relativePath' => null, + 'relativePathname' => null, + ); + $defaults = array_merge($defaults, $param); + parent::__construct($defaults['name']); + $this->setContents($defaults['contents']); + $this->setMode($defaults['mode']); + $this->setType($defaults['type']); + $this->setRelativePath($defaults['relativePath']); + $this->setRelativePathname($defaults['relativePathname']); + } else { + throw new \RuntimeException(sprintf('Incorrect parameter "%s"', $param)); + } + } + + public function isFile() + { + if (null === $this->type) { + return false !== strpos($this->getFilename(), 'file'); + } + + return self::TYPE_FILE === $this->type; + } + + public function isDir() + { + if (null === $this->type) { + return false !== strpos($this->getFilename(), 'directory'); + } + + return self::TYPE_DIRECTORY === $this->type; + } + + public function isReadable() + { + if (null === $this->mode) { + return preg_match('/r\+/', $this->getFilename()); + } + + return preg_match('/r\+/', $this->mode); + } + + public function getContents() + { + return $this->contents; + } + + public function setContents($contents) + { + $this->contents = $contents; + } + + public function setMode($mode) + { + $this->mode = $mode; + } + + public function setType($type) + { + if (is_string($type)) { + switch ($type) { + case 'directory': + case 'd': + $this->type = self::TYPE_DIRECTORY; + break; + case 'file': + case 'f': + $this->type = self::TYPE_FILE; + break; + default: + $this->type = self::TYPE_UNKNOWN; + } + } else { + $this->type = $type; + } + } + + public function setRelativePath($relativePath) + { + $this->relativePath = $relativePath; + } + + public function setRelativePathname($relativePathname) + { + $this->relativePathname = $relativePathname; + } + + public function getRelativePath() + { + return $this->relativePath; + } + + public function getRelativePathname() + { + return $this->relativePathname; + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php new file mode 100644 index 000000000..f2c1cd241 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Iterator\MultiplePcreFilterIterator; + +class MultiplePcreFilterIteratorTest extends TestCase +{ + /** + * @dataProvider getIsRegexFixtures + */ + public function testIsRegex($string, $isRegex, $message) + { + $testIterator = new TestMultiplePcreFilterIterator(); + $this->assertEquals($isRegex, $testIterator->isRegex($string), $message); + } + + public function getIsRegexFixtures() + { + return array( + array('foo', false, 'string'), + array(' foo ', false, '" " is not a valid delimiter'), + array('\\foo\\', false, '"\\" is not a valid delimiter'), + array('afooa', false, '"a" is not a valid delimiter'), + array('//', false, 'the pattern should contain at least 1 character'), + array('/a/', true, 'valid regex'), + array('/foo/', true, 'valid regex'), + array('/foo/i', true, 'valid regex with a single modifier'), + array('/foo/imsxu', true, 'valid regex with multiple modifiers'), + array('#foo#', true, '"#" is a valid delimiter'), + array('{foo}', true, '"{,}" is a valid delimiter pair'), + array('[foo]', true, '"[,]" is a valid delimiter pair'), + array('(foo)', true, '"(,)" is a valid delimiter pair'), + array('', true, '"<,>" is a valid delimiter pair'), + array('*foo.*', false, '"*" is not considered as a valid delimiter'), + array('?foo.?', false, '"?" is not considered as a valid delimiter'), + ); + } +} + +class TestMultiplePcreFilterIterator extends MultiplePcreFilterIterator +{ + public function __construct() + { + } + + public function accept() + { + throw new \BadFunctionCallException('Not implemented'); + } + + public function isRegex($str) + { + return parent::isRegex($str); + } + + public function toRegex($str) + { + throw new \BadFunctionCallException('Not implemented'); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/PathFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/PathFilterIteratorTest.php new file mode 100644 index 000000000..6e10550c0 --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/PathFilterIteratorTest.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\PathFilterIterator; + +class PathFilterIteratorTest extends IteratorTestCase +{ + /** + * @dataProvider getTestFilterData + */ + public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray) + { + $iterator = new PathFilterIterator($inner, $matchPatterns, $noMatchPatterns); + $this->assertIterator($resultArray, $iterator); + } + + public function getTestFilterData() + { + $inner = new MockFileListIterator(); + + //PATH: A/B/C/abc.dat + $inner[] = new MockSplFileInfo(array( + 'name' => 'abc.dat', + 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat', + )); + + //PATH: A/B/ab.dat + $inner[] = new MockSplFileInfo(array( + 'name' => 'ab.dat', + 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat', + )); + + //PATH: A/a.dat + $inner[] = new MockSplFileInfo(array( + 'name' => 'a.dat', + 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'a.dat', + )); + + //PATH: copy/A/B/C/abc.dat.copy + $inner[] = new MockSplFileInfo(array( + 'name' => 'abc.dat.copy', + 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat', + )); + + //PATH: copy/A/B/ab.dat.copy + $inner[] = new MockSplFileInfo(array( + 'name' => 'ab.dat.copy', + 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat', + )); + + //PATH: copy/A/a.dat.copy + $inner[] = new MockSplFileInfo(array( + 'name' => 'a.dat.copy', + 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'a.dat', + )); + + return array( + array($inner, array('/^A/'), array(), array('abc.dat', 'ab.dat', 'a.dat')), + array($inner, array('/^A\/B/'), array(), array('abc.dat', 'ab.dat')), + array($inner, array('/^A\/B\/C/'), array(), array('abc.dat')), + array($inner, array('/A\/B\/C/'), array(), array('abc.dat', 'abc.dat.copy')), + + array($inner, array('A'), array(), array('abc.dat', 'ab.dat', 'a.dat', 'abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')), + array($inner, array('A/B'), array(), array('abc.dat', 'ab.dat', 'abc.dat.copy', 'ab.dat.copy')), + array($inner, array('A/B/C'), array(), array('abc.dat', 'abc.dat.copy')), + + array($inner, array('copy/A'), array(), array('abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')), + array($inner, array('copy/A/B'), array(), array('abc.dat.copy', 'ab.dat.copy')), + array($inner, array('copy/A/B/C'), array(), array('abc.dat.copy')), + ); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/RealIteratorTestCase.php b/vendor/symfony/finder/Tests/Iterator/RealIteratorTestCase.php new file mode 100644 index 000000000..94253c7ee --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/RealIteratorTestCase.php @@ -0,0 +1,110 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +abstract class RealIteratorTestCase extends IteratorTestCase +{ + protected static $tmpDir; + protected static $files; + + public static function setUpBeforeClass() + { + self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony_finder'; + + self::$files = array( + '.git/', + '.foo/', + '.foo/.bar', + '.foo/bar', + '.bar', + 'test.py', + 'foo/', + 'foo/bar.tmp', + 'test.php', + 'toto/', + 'toto/.git/', + 'foo bar', + ); + + self::$files = self::toAbsolute(self::$files); + + if (is_dir(self::$tmpDir)) { + self::tearDownAfterClass(); + } else { + mkdir(self::$tmpDir); + } + + foreach (self::$files as $file) { + if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) { + mkdir($file); + } else { + touch($file); + } + } + + file_put_contents(self::toAbsolute('test.php'), str_repeat(' ', 800)); + file_put_contents(self::toAbsolute('test.py'), str_repeat(' ', 2000)); + + touch(self::toAbsolute('foo/bar.tmp'), strtotime('2005-10-15')); + touch(self::toAbsolute('test.php'), strtotime('2005-10-15')); + } + + public static function tearDownAfterClass() + { + foreach (array_reverse(self::$files) as $file) { + if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) { + @rmdir($file); + } else { + @unlink($file); + } + } + } + + protected static function toAbsolute($files = null) + { + /* + * Without the call to setUpBeforeClass() property can be null. + */ + if (!self::$tmpDir) { + self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony_finder'; + } + + if (is_array($files)) { + $f = array(); + foreach ($files as $file) { + if (is_array($file)) { + $f[] = self::toAbsolute($file); + } else { + $f[] = self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $file); + } + } + + return $f; + } + + if (is_string($files)) { + return self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $files); + } + + return self::$tmpDir; + } + + protected static function toAbsoluteFixtures($files) + { + $f = array(); + foreach ($files as $file) { + $f[] = realpath(__DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$file); + } + + return $f; + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php new file mode 100644 index 000000000..3a3ddc4dd --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator; + +class RecursiveDirectoryIteratorTest extends IteratorTestCase +{ + /** + * @group network + */ + public function testRewindOnFtp() + { + try { + $i = new RecursiveDirectoryIterator('ftp://speedtest.tele2.net/', \RecursiveDirectoryIterator::SKIP_DOTS); + } catch (\UnexpectedValueException $e) { + $this->markTestSkipped('Unsupported stream "ftp".'); + } + + $i->rewind(); + + $this->assertTrue(true); + } + + /** + * @group network + */ + public function testSeekOnFtp() + { + try { + $i = new RecursiveDirectoryIterator('ftp://speedtest.tele2.net/', \RecursiveDirectoryIterator::SKIP_DOTS); + } catch (\UnexpectedValueException $e) { + $this->markTestSkipped('Unsupported stream "ftp".'); + } + + $contains = array( + 'ftp://speedtest.tele2.net'.DIRECTORY_SEPARATOR.'1000GB.zip', + 'ftp://speedtest.tele2.net'.DIRECTORY_SEPARATOR.'100GB.zip', + ); + $actual = array(); + + $i->seek(0); + $actual[] = $i->getPathname(); + + $i->seek(1); + $actual[] = $i->getPathname(); + + $this->assertEquals($contains, $actual); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/SizeRangeFilterIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/SizeRangeFilterIteratorTest.php new file mode 100644 index 000000000..6d75b0f2f --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/SizeRangeFilterIteratorTest.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator; +use Symfony\Component\Finder\Comparator\NumberComparator; + +class SizeRangeFilterIteratorTest extends RealIteratorTestCase +{ + /** + * @dataProvider getAcceptData + */ + public function testAccept($size, $expected) + { + $inner = new InnerSizeIterator(self::$files); + + $iterator = new SizeRangeFilterIterator($inner, $size); + + $this->assertIterator($expected, $iterator); + } + + public function getAcceptData() + { + $lessThan1KGreaterThan05K = array( + '.foo', + '.git', + 'foo', + 'test.php', + 'toto', + 'toto/.git', + ); + + return array( + array(array(new NumberComparator('< 1K'), new NumberComparator('> 0.5K')), $this->toAbsolute($lessThan1KGreaterThan05K)), + ); + } +} + +class InnerSizeIterator extends \ArrayIterator +{ + public function current() + { + return new \SplFileInfo(parent::current()); + } + + public function getFilename() + { + return parent::current(); + } + + public function isFile() + { + return $this->current()->isFile(); + } + + public function getSize() + { + return $this->current()->getSize(); + } +} diff --git a/vendor/symfony/finder/Tests/Iterator/SortableIteratorTest.php b/vendor/symfony/finder/Tests/Iterator/SortableIteratorTest.php new file mode 100644 index 000000000..4750f250d --- /dev/null +++ b/vendor/symfony/finder/Tests/Iterator/SortableIteratorTest.php @@ -0,0 +1,183 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Iterator; + +use Symfony\Component\Finder\Iterator\SortableIterator; + +class SortableIteratorTest extends RealIteratorTestCase +{ + public function testConstructor() + { + try { + new SortableIterator(new Iterator(array()), 'foobar'); + $this->fail('__construct() throws an \InvalidArgumentException exception if the mode is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException exception if the mode is not valid'); + } + } + + /** + * @dataProvider getAcceptData + */ + public function testAccept($mode, $expected) + { + if (!is_callable($mode)) { + switch ($mode) { + case SortableIterator::SORT_BY_ACCESSED_TIME: + if ('\\' === DIRECTORY_SEPARATOR) { + touch(self::toAbsolute('.git')); + } else { + file_get_contents(self::toAbsolute('.git')); + } + sleep(1); + file_get_contents(self::toAbsolute('.bar')); + break; + case SortableIterator::SORT_BY_CHANGED_TIME: + file_put_contents(self::toAbsolute('test.php'), 'foo'); + sleep(1); + file_put_contents(self::toAbsolute('test.py'), 'foo'); + break; + case SortableIterator::SORT_BY_MODIFIED_TIME: + file_put_contents(self::toAbsolute('test.php'), 'foo'); + sleep(1); + file_put_contents(self::toAbsolute('test.py'), 'foo'); + break; + } + } + + $inner = new Iterator(self::$files); + + $iterator = new SortableIterator($inner, $mode); + + if ($mode === SortableIterator::SORT_BY_ACCESSED_TIME + || $mode === SortableIterator::SORT_BY_CHANGED_TIME + || $mode === SortableIterator::SORT_BY_MODIFIED_TIME + ) { + if ('\\' === DIRECTORY_SEPARATOR && SortableIterator::SORT_BY_MODIFIED_TIME !== $mode) { + $this->markTestSkipped('Sorting by atime or ctime is not supported on Windows'); + } + $this->assertOrderedIteratorForGroups($expected, $iterator); + } else { + $this->assertOrderedIterator($expected, $iterator); + } + } + + public function getAcceptData() + { + $sortByName = array( + '.bar', + '.foo', + '.foo/.bar', + '.foo/bar', + '.git', + 'foo', + 'foo bar', + 'foo/bar.tmp', + 'test.php', + 'test.py', + 'toto', + 'toto/.git', + ); + + $sortByType = array( + '.foo', + '.git', + 'foo', + 'toto', + 'toto/.git', + '.bar', + '.foo/.bar', + '.foo/bar', + 'foo bar', + 'foo/bar.tmp', + 'test.php', + 'test.py', + ); + + $customComparison = array( + '.bar', + '.foo', + '.foo/.bar', + '.foo/bar', + '.git', + 'foo', + 'foo bar', + 'foo/bar.tmp', + 'test.php', + 'test.py', + 'toto', + 'toto/.git', + ); + + $sortByAccessedTime = array( + // For these two files the access time was set to 2005-10-15 + array('foo/bar.tmp', 'test.php'), + // These files were created more or less at the same time + array( + '.git', + '.foo', + '.foo/.bar', + '.foo/bar', + 'test.py', + 'foo', + 'toto', + 'toto/.git', + 'foo bar', + ), + // This file was accessed after sleeping for 1 sec + array('.bar'), + ); + + $sortByChangedTime = array( + array( + '.git', + '.foo', + '.foo/.bar', + '.foo/bar', + '.bar', + 'foo', + 'foo/bar.tmp', + 'toto', + 'toto/.git', + 'foo bar', + ), + array('test.php'), + array('test.py'), + ); + + $sortByModifiedTime = array( + array( + '.git', + '.foo', + '.foo/.bar', + '.foo/bar', + '.bar', + 'foo', + 'foo/bar.tmp', + 'toto', + 'toto/.git', + 'foo bar', + ), + array('test.php'), + array('test.py'), + ); + + return array( + array(SortableIterator::SORT_BY_NAME, $this->toAbsolute($sortByName)), + array(SortableIterator::SORT_BY_TYPE, $this->toAbsolute($sortByType)), + array(SortableIterator::SORT_BY_ACCESSED_TIME, $this->toAbsolute($sortByAccessedTime)), + array(SortableIterator::SORT_BY_CHANGED_TIME, $this->toAbsolute($sortByChangedTime)), + array(SortableIterator::SORT_BY_MODIFIED_TIME, $this->toAbsolute($sortByModifiedTime)), + array(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); }, $this->toAbsolute($customComparison)), + ); + } +} diff --git a/vendor/symfony/finder/Tests/PhpFinderTest.php b/vendor/symfony/finder/Tests/PhpFinderTest.php new file mode 100644 index 000000000..b188340ef --- /dev/null +++ b/vendor/symfony/finder/Tests/PhpFinderTest.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests; + +use Symfony\Component\Finder\Adapter\PhpAdapter; +use Symfony\Component\Finder\Finder; + +/** + * @group legacy + */ +class PhpFinderTest extends FinderTest +{ + public function testImplementationsAreSynchronized() + { + $adapterReflector = new \ReflectionMethod('Symfony\Component\Finder\Adapter\PhpAdapter', 'searchInDirectory'); + $finderReflector = new \ReflectionMethod('Symfony\Component\Finder\Finder', 'searchInDirectory'); + + $adapterSource = array_slice(file($adapterReflector->getFileName()), $adapterReflector->getStartLine() + 1, $adapterReflector->getEndLine() - $adapterReflector->getStartLine() - 1); + $adapterSource = implode('', $adapterSource); + $adapterSource = str_replace(array('$this->minDepth', '$this->maxDepth'), array('$minDepth', '$maxDepth'), $adapterSource); + + $finderSource = array_slice(file($finderReflector->getFileName()), $finderReflector->getStartLine() + 1, $finderReflector->getEndLine() - $finderReflector->getStartLine() - 1); + $finderSource = implode('', $finderSource); + + $this->assertStringEndsWith($adapterSource, $finderSource); + } + + protected function buildFinder() + { + $adapter = new PhpAdapter(); + + return Finder::create() + ->removeAdapters() + ->addAdapter($adapter); + } +} diff --git a/vendor/symfony/finder/Tests/Shell/CommandTest.php b/vendor/symfony/finder/Tests/Shell/CommandTest.php new file mode 100644 index 000000000..9ac275655 --- /dev/null +++ b/vendor/symfony/finder/Tests/Shell/CommandTest.php @@ -0,0 +1,166 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests\Shell; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Finder\Shell\Command; + +/** + * @group legacy + */ +class CommandTest extends TestCase +{ + public function testCreate() + { + $this->assertInstanceOf('Symfony\Component\Finder\Shell\Command', Command::create()); + } + + public function testAdd() + { + $cmd = Command::create()->add('--force'); + $this->assertSame('--force', $cmd->join()); + } + + public function testAddAsFirst() + { + $cmd = Command::create()->add('--force'); + + $cmd->addAtIndex(Command::create()->add('-F'), 0); + $this->assertSame('-F --force', $cmd->join()); + } + + public function testAddAsLast() + { + $cmd = Command::create()->add('--force'); + + $cmd->addAtIndex(Command::create()->add('-F'), 1); + $this->assertSame('--force -F', $cmd->join()); + } + + public function testAddInBetween() + { + $cmd = Command::create()->add('--force'); + $cmd->addAtIndex(Command::create()->add('-F'), 0); + + $cmd->addAtIndex(Command::create()->add('-X'), 1); + $this->assertSame('-F -X --force', $cmd->join()); + } + + public function testCount() + { + $cmd = Command::create(); + $this->assertSame(0, $cmd->length()); + + $cmd->add('--force'); + $this->assertSame(1, $cmd->length()); + + $cmd->add('--run'); + $this->assertSame(2, $cmd->length()); + } + + public function testTop() + { + $cmd = Command::create()->add('--force'); + + $cmd->top('--run'); + $this->assertSame('--run --force', $cmd->join()); + } + + public function testTopLabeled() + { + $cmd = Command::create()->add('--force'); + + $cmd->top('--run'); + $cmd->ins('--something'); + $cmd->top('--something'); + $this->assertSame('--something --run --force ', $cmd->join()); + } + + public function testArg() + { + $cmd = Command::create()->add('--force'); + + $cmd->arg('--run'); + $this->assertSame('--force '.escapeshellarg('--run'), $cmd->join()); + } + + public function testCmd() + { + $cmd = Command::create()->add('--force'); + + $cmd->cmd('run'); + $this->assertSame('--force run', $cmd->join()); + } + + public function testInsDuplicateLabelException() + { + $cmd = Command::create()->add('--force'); + + $cmd->ins('label'); + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('RuntimeException'); + $cmd->ins('label'); + } + + public function testEnd() + { + $parent = Command::create(); + $cmd = Command::create($parent); + + $this->assertSame($parent, $cmd->end()); + } + + public function testEndNoParentException() + { + $cmd = Command::create(); + + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('RuntimeException'); + $cmd->end(); + } + + public function testGetMissingLabelException() + { + $cmd = Command::create(); + + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('RuntimeException'); + $cmd->get('invalid'); + } + + public function testErrorHandler() + { + $cmd = Command::create(); + $handler = function () { return 'error-handler'; }; + $cmd->setErrorHandler($handler); + + $this->assertSame($handler, $cmd->getErrorHandler()); + } + + public function testExecute() + { + $cmd = Command::create(); + $cmd->add('php'); + $cmd->add('--version'); + $result = $cmd->execute(); + + $this->assertInternalType('array', $result); + $this->assertNotEmpty($result); + $this->assertRegExp('/PHP|HipHop/', $result[0]); + } + + public function testCastToString() + { + $cmd = Command::create(); + $cmd->add('--force'); + $cmd->add('--run'); + + $this->assertSame('--force --run', (string) $cmd); + } +} diff --git a/vendor/symfony/finder/phpunit.xml.dist b/vendor/symfony/finder/phpunit.xml.dist index 631e570b9..0e1a8669b 100644 --- a/vendor/symfony/finder/phpunit.xml.dist +++ b/vendor/symfony/finder/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/http-foundation/FileBag.php b/vendor/symfony/http-foundation/FileBag.php index 197eab42f..e17a9057b 100644 --- a/vendor/symfony/http-foundation/FileBag.php +++ b/vendor/symfony/http-foundation/FileBag.php @@ -69,7 +69,7 @@ class FileBag extends ParameterBag * * @param array|UploadedFile $file A (multi-dimensional) array of uploaded file information * - * @return array A (multi-dimensional) array of UploadedFile instances + * @return UploadedFile|UploadedFile[] A (multi-dimensional) array of UploadedFile instances */ protected function convertFileInformation($file) { diff --git a/vendor/symfony/http-foundation/JsonResponse.php b/vendor/symfony/http-foundation/JsonResponse.php index 2412b5e2b..a83d0077a 100644 --- a/vendor/symfony/http-foundation/JsonResponse.php +++ b/vendor/symfony/http-foundation/JsonResponse.php @@ -121,7 +121,7 @@ class JsonResponse extends Response $data = json_encode($data, $this->encodingOptions); } else { try { - if (PHP_VERSION_ID < 50400) { + if (\PHP_VERSION_ID < 50400) { // PHP 5.3 triggers annoying warnings for some // types that can't be serialized as JSON (INF, resources, etc.) // but doesn't provide the JsonSerializable interface. @@ -131,7 +131,7 @@ class JsonResponse extends Response // PHP 5.4 and up wrap exceptions thrown by JsonSerializable // objects in a new exception that needs to be removed. // Fortunately, PHP 5.5 and up do not trigger any warning anymore. - if (PHP_VERSION_ID < 50500) { + if (\PHP_VERSION_ID < 50500) { // Clear json_last_error() json_encode(null); $errorHandler = set_error_handler('var_dump'); @@ -146,14 +146,14 @@ class JsonResponse extends Response $data = json_encode($data, $this->encodingOptions); } - if (PHP_VERSION_ID < 50500) { + if (\PHP_VERSION_ID < 50500) { restore_error_handler(); } } catch (\Exception $e) { - if (PHP_VERSION_ID < 50500) { + if (\PHP_VERSION_ID < 50500) { restore_error_handler(); } - if (PHP_VERSION_ID >= 50400 && 'Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { + if (\PHP_VERSION_ID >= 50400 && 'Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { throw $e->getPrevious() ?: $e; } throw $e; diff --git a/vendor/symfony/http-foundation/ParameterBag.php b/vendor/symfony/http-foundation/ParameterBag.php index ef13494ee..7b56af11a 100644 --- a/vendor/symfony/http-foundation/ParameterBag.php +++ b/vendor/symfony/http-foundation/ParameterBag.php @@ -135,7 +135,7 @@ class ParameterBag implements \IteratorAggregate, \Countable } if (null !== $currentKey) { - throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".')); + throw new \InvalidArgumentException('Malformed path. Path must end with "]".'); } return $value; diff --git a/vendor/symfony/http-foundation/Request.php b/vendor/symfony/http-foundation/Request.php index 78dc20235..2f3b84e7e 100644 --- a/vendor/symfony/http-foundation/Request.php +++ b/vendor/symfony/http-foundation/Request.php @@ -837,7 +837,7 @@ class Request * ("Client-Ip" for instance), configure it via "setTrustedHeaderName()" with * the "client-ip" key. * - * @return string The client IP address + * @return string|null The client IP address * * @see getClientIps() * @see http://en.wikipedia.org/wiki/X-Forwarded-For @@ -943,7 +943,7 @@ class Request * If your reverse proxy uses a different header name than "X-Forwarded-Port", * configure it via "setTrustedHeaderName()" with the "client-port" key. * - * @return string + * @return int|string can be a string if fetched from the server bag */ public function getPort() { @@ -1481,7 +1481,7 @@ class Request public function getContent($asResource = false) { $currentContentIsResource = is_resource($this->content); - if (PHP_VERSION_ID < 50600 && false === $this->content) { + if (\PHP_VERSION_ID < 50600 && false === $this->content) { throw new \LogicException('getContent() can only be called once when using the resource return type and PHP below 5.6.'); } diff --git a/vendor/symfony/http-foundation/Response.php b/vendor/symfony/http-foundation/Response.php index 3eb8bd289..65c5fce23 100644 --- a/vendor/symfony/http-foundation/Response.php +++ b/vendor/symfony/http-foundation/Response.php @@ -179,7 +179,7 @@ class Response 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', - 506 => 'Variant Also Negotiates (Experimental)', // RFC2295 + 506 => 'Variant Also Negotiates', // RFC2295 507 => 'Insufficient Storage', // RFC4918 508 => 'Loop Detected', // RFC5842 510 => 'Not Extended', // RFC2774 @@ -204,7 +204,7 @@ class Response /* RFC2616 - 14.18 says all Responses need to have a Date */ if (!$this->headers->has('Date')) { - $this->setDate(new \DateTime(null, new \DateTimeZone('UTC'))); + $this->setDate(\DateTime::createFromFormat('U', time())); } } diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php index 95d5cdbf5..03acbd94e 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php @@ -13,7 +13,7 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; // Adds SessionHandler functionality if available. // @see http://php.net/sessionhandler -if (PHP_VERSION_ID >= 50400) { +if (\PHP_VERSION_ID >= 50400) { class NativeSessionHandler extends \SessionHandler { } diff --git a/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php b/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php index 274b0df6b..b8acebe6d 100644 --- a/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php +++ b/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php @@ -81,6 +81,7 @@ class NativeSessionStorage implements SessionStorageInterface * name, "PHPSESSID" * referer_check, "" * serialize_handler, "php" + * use_strict_mode, "0" * use_cookies, "1" * use_only_cookies, "1" * use_trans_sid, "0" @@ -127,11 +128,11 @@ class NativeSessionStorage implements SessionStorageInterface return true; } - if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE === session_status()) { + if (\PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE === session_status()) { throw new \RuntimeException('Failed to start the session: already started by PHP.'); } - if (PHP_VERSION_ID < 50400 && !$this->closed && isset($_SESSION) && session_id()) { + if (\PHP_VERSION_ID < 50400 && !$this->closed && isset($_SESSION) && session_id()) { // not 100% fool-proof, but is the most reliable way to determine if a session is active in PHP 5.3 throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).'); } @@ -192,12 +193,12 @@ class NativeSessionStorage implements SessionStorageInterface public function regenerate($destroy = false, $lifetime = null) { // Cannot regenerate the session ID for non-active sessions. - if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE !== session_status()) { + if (\PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE !== session_status()) { return false; } // Check if session ID exists in PHP 5.3 - if (PHP_VERSION_ID < 50400 && '' === session_id()) { + if (\PHP_VERSION_ID < 50400 && '' === session_id()) { return false; } @@ -331,7 +332,7 @@ class NativeSessionStorage implements SessionStorageInterface 'entropy_file', 'entropy_length', 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', 'hash_function', 'name', 'referer_check', - 'serialize_handler', 'use_cookies', + 'serialize_handler', 'use_strict_mode', 'use_cookies', 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags', @@ -379,13 +380,13 @@ class NativeSessionStorage implements SessionStorageInterface if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { $saveHandler = new SessionHandlerProxy($saveHandler); } elseif (!$saveHandler instanceof AbstractProxy) { - $saveHandler = PHP_VERSION_ID >= 50400 ? + $saveHandler = \PHP_VERSION_ID >= 50400 ? new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy(); } $this->saveHandler = $saveHandler; if ($this->saveHandler instanceof \SessionHandlerInterface) { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { session_set_save_handler($this->saveHandler, false); } else { session_set_save_handler( diff --git a/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php b/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php index 463677b55..405e60b2f 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php +++ b/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php @@ -72,7 +72,7 @@ abstract class AbstractProxy */ public function isActive() { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { return $this->active = \PHP_SESSION_ACTIVE === session_status(); } @@ -93,7 +93,7 @@ abstract class AbstractProxy */ public function setActive($flag) { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { throw new \LogicException('This method is disabled in PHP 5.4.0+'); } diff --git a/vendor/symfony/http-foundation/Tests/RequestTest.php b/vendor/symfony/http-foundation/Tests/RequestTest.php index fa3fc3ef8..b1d69b64c 100644 --- a/vendor/symfony/http-foundation/Tests/RequestTest.php +++ b/vendor/symfony/http-foundation/Tests/RequestTest.php @@ -1008,7 +1008,7 @@ class RequestTest extends TestCase $req = new Request(array(), array(), array(), array(), array(), array(), 'MyContent'); $resource = $req->getContent(true); - $this->assertTrue(is_resource($resource)); + $this->assertInternalType('resource', $resource); $this->assertEquals('MyContent', stream_get_contents($resource)); } @@ -1029,7 +1029,7 @@ class RequestTest extends TestCase */ public function testGetContentCantBeCalledTwiceWithResources($first, $second) { - if (PHP_VERSION_ID >= 50600) { + if (\PHP_VERSION_ID >= 50600) { $this->markTestSkipped('PHP >= 5.6 allows to open php://input several times.'); } diff --git a/vendor/symfony/http-foundation/Tests/ResponseTest.php b/vendor/symfony/http-foundation/Tests/ResponseTest.php index 453a05a9b..13600ea66 100644 --- a/vendor/symfony/http-foundation/Tests/ResponseTest.php +++ b/vendor/symfony/http-foundation/Tests/ResponseTest.php @@ -884,6 +884,67 @@ class ResponseTest extends ResponseTestCase { return new Response(); } + + /** + * @see http://github.com/zendframework/zend-diactoros for the canonical source repository + * + * @author Fábio Pacheco + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) + * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License + */ + public function ianaCodesReasonPhrasesProvider() + { + if (!in_array('https', stream_get_wrappers(), true)) { + $this->markTestSkipped('The "https" wrapper is not available'); + } + + $ianaHttpStatusCodes = new \DOMDocument(); + + libxml_set_streams_context(stream_context_create(array( + 'http' => array( + 'method' => 'GET', + 'timeout' => 30, + ), + ))); + + $ianaHttpStatusCodes->load('https://www.iana.org/assignments/http-status-codes/http-status-codes.xml'); + if (!$ianaHttpStatusCodes->relaxNGValidate(__DIR__.'/schema/http-status-codes.rng')) { + self::fail('Invalid IANA\'s HTTP status code list.'); + } + + $ianaCodesReasonPhrases = array(); + + $xpath = new \DomXPath($ianaHttpStatusCodes); + $xpath->registerNamespace('ns', 'http://www.iana.org/assignments'); + + $records = $xpath->query('//ns:record'); + foreach ($records as $record) { + $value = $xpath->query('.//ns:value', $record)->item(0)->nodeValue; + $description = $xpath->query('.//ns:description', $record)->item(0)->nodeValue; + + if (in_array($description, array('Unassigned', '(Unused)'), true)) { + continue; + } + + if (preg_match('/^([0-9]+)\s*\-\s*([0-9]+)$/', $value, $matches)) { + for ($value = $matches[1]; $value <= $matches[2]; ++$value) { + $ianaCodesReasonPhrases[] = array($value, $description); + } + } else { + $ianaCodesReasonPhrases[] = array($value, $description); + } + } + + return $ianaCodesReasonPhrases; + } + + /** + * @dataProvider ianaCodesReasonPhrasesProvider + */ + public function testReasonPhraseDefaultsAgainstIana($code, $reasonPhrase) + { + $this->assertEquals($reasonPhrase, Response::$statusTexts[$code]); + } } class StringableObject diff --git a/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php b/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php index f23161c10..128b9b52f 100644 --- a/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php +++ b/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php @@ -31,7 +31,11 @@ class MongoDbSessionHandlerTest extends TestCase { parent::setUp(); - if (!extension_loaded('mongo') && !extension_loaded('mongodb')) { + if (extension_loaded('mongodb')) { + if (!class_exists('MongoDB\Client')) { + $this->markTestSkipped('The mongodb/mongodb package is required.'); + } + } elseif (!extension_loaded('mongo')) { $this->markTestSkipped('The Mongo or MongoDB extension is required.'); } @@ -109,7 +113,7 @@ class MongoDbSessionHandlerTest extends TestCase if (phpversion('mongodb')) { $that->assertInstanceOf('MongoDB\BSON\UTCDateTime', $criteria[$that->options['expiry_field']]['$gte']); - $that->assertGreaterThanOrEqual(round(((int) $criteria[$that->options['expiry_field']]['$gte']) / 1000), $testTimeout); + $that->assertGreaterThanOrEqual(round((string) $criteria[$that->options['expiry_field']]['$gte'] / 1000), $testTimeout); } else { $that->assertInstanceOf('MongoDate', $criteria[$that->options['expiry_field']]['$gte']); $that->assertGreaterThanOrEqual($criteria[$that->options['expiry_field']]['$gte']->sec, $testTimeout); @@ -168,7 +172,7 @@ class MongoDbSessionHandlerTest extends TestCase $that->assertEquals('bar', $data[$that->options['data_field']]->getData()); $that->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$that->options['time_field']]); $that->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$that->options['expiry_field']]); - $that->assertGreaterThanOrEqual($expectedExpiry, round(((int) $data[$that->options['expiry_field']]) / 1000)); + $that->assertGreaterThanOrEqual($expectedExpiry, round((string) $data[$that->options['expiry_field']] / 1000)); } else { $that->assertEquals('bar', $data[$that->options['data_field']]->bin); $that->assertInstanceOf('MongoDate', $data[$that->options['time_field']]); @@ -294,7 +298,7 @@ class MongoDbSessionHandlerTest extends TestCase ->will($this->returnCallback(function ($criteria) use ($that) { if (phpversion('mongodb')) { $that->assertInstanceOf('MongoDB\BSON\UTCDateTime', $criteria[$that->options['expiry_field']]['$lt']); - $that->assertGreaterThanOrEqual(time() - 1, round(((int) $criteria[$that->options['expiry_field']]['$lt']) / 1000)); + $that->assertGreaterThanOrEqual(time() - 1, round((string) $criteria[$that->options['expiry_field']]['$lt'] / 1000)); } else { $that->assertInstanceOf('MongoDate', $criteria[$that->options['expiry_field']]['$lt']); $that->assertGreaterThanOrEqual(time() - 1, $criteria[$that->options['expiry_field']]['$lt']->sec); diff --git a/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php b/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php index 947502f7b..67336f68d 100644 --- a/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php +++ b/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php @@ -29,7 +29,7 @@ class NativeFileSessionHandlerTest extends TestCase { $storage = new NativeSessionStorage(array('name' => 'TESTING'), new NativeFileSessionHandler(sys_get_temp_dir())); - if (PHP_VERSION_ID < 50400) { + if (\PHP_VERSION_ID < 50400) { $this->assertEquals('files', $storage->getSaveHandler()->getSaveHandlerName()); $this->assertEquals('files', ini_get('session.save_handler')); } else { diff --git a/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php b/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php index bd335b3b4..021d8c0f9 100644 --- a/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php +++ b/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php @@ -30,7 +30,7 @@ class NativeSessionHandlerTest extends TestCase // note for PHPUnit optimisers - the use of assertTrue/False // here is deliberate since the tests do not require the classes to exist - drak - if (PHP_VERSION_ID < 50400) { + if (\PHP_VERSION_ID < 50400) { $this->assertFalse($handler instanceof \SessionHandler); $this->assertTrue($handler instanceof NativeSessionHandler); } else { diff --git a/vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php b/vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php index 4da9a1bc5..20f9ca060 100644 --- a/vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php +++ b/vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php @@ -196,7 +196,7 @@ class NativeSessionStorageTest extends TestCase public function testSetSaveHandler53() { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $this->markTestSkipped('Test skipped, for PHP 5.3 only.'); } @@ -249,7 +249,7 @@ class NativeSessionStorageTest extends TestCase session_start(); $this->assertTrue(isset($_SESSION)); - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { // this only works in PHP >= 5.4 where session_status is available $this->assertTrue($storage->getSaveHandler()->isActive()); } diff --git a/vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php b/vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php index 99491ce86..5cfb328d3 100644 --- a/vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php +++ b/vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php @@ -62,7 +62,7 @@ class PhpBridgeSessionStorageTest extends TestCase public function testPhpSession53() { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $this->markTestSkipped('Test skipped, for PHP 5.3 only.'); } diff --git a/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php b/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php index efd8d80d3..f21bcc963 100644 --- a/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php +++ b/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php @@ -88,7 +88,7 @@ class AbstractProxyTest extends TestCase public function testIsActivePhp53() { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $this->markTestSkipped('Test skipped, for PHP 5.3 only.'); } @@ -109,7 +109,7 @@ class AbstractProxyTest extends TestCase public function testSetActivePhp53() { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $this->markTestSkipped('Test skipped, for PHP 5.3 only.'); } @@ -147,7 +147,7 @@ class AbstractProxyTest extends TestCase */ public function testNameExceptionPhp53() { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $this->markTestSkipped('Test skipped, for PHP 5.3 only.'); } @@ -184,7 +184,7 @@ class AbstractProxyTest extends TestCase */ public function testIdExceptionPhp53() { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $this->markTestSkipped('Test skipped, for PHP 5.3 only.'); } diff --git a/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php b/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php index 243f850b5..df277ac5a 100644 --- a/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php +++ b/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php @@ -54,7 +54,7 @@ class SessionHandlerProxyTest extends TestCase $this->assertFalse($this->proxy->isActive()); $this->proxy->open('name', 'id'); - if (PHP_VERSION_ID < 50400) { + if (\PHP_VERSION_ID < 50400) { $this->assertTrue($this->proxy->isActive()); } else { $this->assertFalse($this->proxy->isActive()); diff --git a/vendor/symfony/http-foundation/Tests/schema/http-status-codes.rng b/vendor/symfony/http-foundation/Tests/schema/http-status-codes.rng new file mode 100644 index 000000000..73708ca68 --- /dev/null +++ b/vendor/symfony/http-foundation/Tests/schema/http-status-codes.rng @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/http-foundation/Tests/schema/iana-registry.rng b/vendor/symfony/http-foundation/Tests/schema/iana-registry.rng new file mode 100644 index 000000000..b9c3ca9d9 --- /dev/null +++ b/vendor/symfony/http-foundation/Tests/schema/iana-registry.rng @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + uri + + + + rfc + + + (rfc|bcp|std)\d+ + + + + + rfc-errata + + + + draft + + + (draft|RFC)(-[a-zA-Z0-9]+)+ + + + + + registry + + + + person + + + + text + + + note + + + + unicode + + + ucd\d+\.\d+\.\d+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (\d+|0x[\da-fA-F]+)(\s*-\s*(\d+|0x[\da-fA-F]+))? + + + + + + + + + + + + + 0x[0-9]{8} + + + + + + [0-1]+ + + + + + + + + + + + + + + + + + + + + + + legacy + mib + template + json + + + + + + + + + + diff --git a/vendor/symfony/http-foundation/phpunit.xml.dist b/vendor/symfony/http-foundation/phpunit.xml.dist index 9ffdb43a2..c1d61f8bf 100644 --- a/vendor/symfony/http-foundation/phpunit.xml.dist +++ b/vendor/symfony/http-foundation/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/http-kernel/Bundle/Bundle.php b/vendor/symfony/http-kernel/Bundle/Bundle.php index bd8f51ecb..13c2d941d 100644 --- a/vendor/symfony/http-kernel/Bundle/Bundle.php +++ b/vendor/symfony/http-kernel/Bundle/Bundle.php @@ -141,7 +141,7 @@ abstract class Bundle implements BundleInterface /** * Returns the bundle parent name. * - * @return string The Bundle parent name it overrides or null if no parent + * @return string|null The Bundle parent name it overrides or null if no parent */ public function getParent() { diff --git a/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php b/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php index 6df03fa31..60a62e2e9 100644 --- a/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php +++ b/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php @@ -20,6 +20,7 @@ use Symfony\Component\VarDumper\Cloner\VarCloner; use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\Dumper\HtmlDumper; use Symfony\Component\VarDumper\Dumper\DataDumperInterface; +use Twig\Template; /** * @author Nicolas Grekas @@ -71,7 +72,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface } $trace = DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS; - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $trace = debug_backtrace($trace, 7); } else { $trace = debug_backtrace($trace); @@ -96,7 +97,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface $line = $trace[$i]['line']; break; - } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof \Twig_Template) { + } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof Template) { $template = $trace[$i]['object']; $name = $template->getTemplateName(); $src = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : false); @@ -263,7 +264,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface private function doDump($data, $name, $file, $line) { - if (PHP_VERSION_ID >= 50400 && $this->dumper instanceof CliDumper) { + if (\PHP_VERSION_ID >= 50400 && $this->dumper instanceof CliDumper) { $contextDumper = function ($name, $file, $line, $fileLinkFormat) { if ($this instanceof HtmlDumper) { if ($file) { diff --git a/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php b/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php index 27051cfb7..e7d4aedb1 100644 --- a/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php +++ b/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php @@ -16,6 +16,9 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Templating\EngineInterface; use Symfony\Component\HttpKernel\Controller\ControllerReference; use Symfony\Component\HttpKernel\UriSigner; +use Twig\Environment; +use Twig\Error\LoaderError; +use Twig\Loader\ExistsLoaderInterface; /** * Implements the Hinclude rendering strategy. @@ -32,10 +35,10 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer /** * Constructor. * - * @param EngineInterface|\Twig_Environment $templating An EngineInterface or a \Twig_Environment instance - * @param UriSigner $signer A UriSigner instance - * @param string $globalDefaultTemplate The global default content (it can be a template name or the content) - * @param string $charset + * @param EngineInterface|Environment $templating An EngineInterface or a Twig instance + * @param UriSigner $signer A UriSigner instance + * @param string $globalDefaultTemplate The global default content (it can be a template name or the content) + * @param string $charset */ public function __construct($templating = null, UriSigner $signer = null, $globalDefaultTemplate = null, $charset = 'utf-8') { @@ -48,14 +51,14 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer /** * Sets the templating engine to use to render the default content. * - * @param EngineInterface|\Twig_Environment|null $templating An EngineInterface or a \Twig_Environment instance + * @param EngineInterface|Environment|null $templating An EngineInterface or an Environment instance * * @throws \InvalidArgumentException */ public function setTemplating($templating) { - if (null !== $templating && !$templating instanceof EngineInterface && !$templating instanceof \Twig_Environment) { - throw new \InvalidArgumentException('The hinclude rendering strategy needs an instance of \Twig_Environment or Symfony\Component\Templating\EngineInterface'); + if (null !== $templating && !$templating instanceof EngineInterface && !$templating instanceof Environment) { + throw new \InvalidArgumentException('The hinclude rendering strategy needs an instance of Twig\Environment or Symfony\Component\Templating\EngineInterface'); } $this->templating = $templating; @@ -107,7 +110,7 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer } $renderedAttributes = ''; if (count($attributes) > 0) { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $flags = ENT_QUOTES | ENT_SUBSTITUTE; } else { $flags = ENT_QUOTES; @@ -140,7 +143,7 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer } $loader = $this->templating->getLoader(); - if ($loader instanceof \Twig_ExistsLoaderInterface || method_exists($loader, 'exists')) { + if ($loader instanceof ExistsLoaderInterface || method_exists($loader, 'exists')) { return $loader->exists($template); } @@ -152,7 +155,7 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer } return true; - } catch (\Twig_Error_Loader $e) { + } catch (LoaderError $e) { } return false; diff --git a/vendor/symfony/http-kernel/Kernel.php b/vendor/symfony/http-kernel/Kernel.php index b871a8ebd..97e83f8d5 100644 --- a/vendor/symfony/http-kernel/Kernel.php +++ b/vendor/symfony/http-kernel/Kernel.php @@ -59,11 +59,11 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.19'; - const VERSION_ID = 20819; + const VERSION = '2.8.22'; + const VERSION_ID = 20822; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; - const RELEASE_VERSION = 19; + const RELEASE_VERSION = 22; const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2018'; @@ -755,7 +755,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface $output .= $rawChunk; - if (PHP_VERSION_ID >= 70000) { + if (\PHP_VERSION_ID >= 70000) { // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 unset($tokens, $rawChunk); gc_mem_caches(); diff --git a/vendor/symfony/http-kernel/Profiler/Profile.php b/vendor/symfony/http-kernel/Profiler/Profile.php index d6be0c7db..9e0c9fb7d 100644 --- a/vendor/symfony/http-kernel/Profiler/Profile.php +++ b/vendor/symfony/http-kernel/Profiler/Profile.php @@ -156,7 +156,7 @@ class Profile /** * Returns the time. * - * @return string The time + * @return int The time */ public function getTime() { @@ -167,6 +167,9 @@ class Profile return $this->time; } + /** + * @param int The time + */ public function setTime($time) { $this->time = $time; diff --git a/vendor/symfony/http-kernel/Tests/Controller/ControllerResolverTest.php b/vendor/symfony/http-kernel/Tests/Controller/ControllerResolverTest.php index 046b71ac0..58ca07fc5 100644 --- a/vendor/symfony/http-kernel/Tests/Controller/ControllerResolverTest.php +++ b/vendor/symfony/http-kernel/Tests/Controller/ControllerResolverTest.php @@ -184,7 +184,7 @@ class ControllerResolverTest extends TestCase $request->attributes->set('foobar', 'foobar'); $controller = array(new self(), 'controllerMethod3'); - if (PHP_VERSION_ID === 50316) { + if (\PHP_VERSION_ID === 50316) { $this->markTestSkipped('PHP 5.3.16 has a major bug in the Reflection sub-system'); } else { try { diff --git a/vendor/symfony/http-kernel/Tests/DataCollector/DumpDataCollectorTest.php b/vendor/symfony/http-kernel/Tests/DataCollector/DumpDataCollectorTest.php index 48b46efad..91f4b2e6f 100644 --- a/vendor/symfony/http-kernel/Tests/DataCollector/DumpDataCollectorTest.php +++ b/vendor/symfony/http-kernel/Tests/DataCollector/DumpDataCollectorTest.php @@ -68,7 +68,7 @@ class DumpDataCollectorTest extends TestCase $collector->collect(new Request(), new Response()); $output = ob_get_clean(); - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n123\n", $output); } else { $this->assertSame("\"DumpDataCollectorTest.php on line {$line}:\"\n123\n", $output); @@ -86,7 +86,7 @@ class DumpDataCollectorTest extends TestCase $collector->dump($data); $line = __LINE__ - 1; $file = __FILE__; - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $xOutput = <<DumpDataCollectorTest.php on line {$line}: 123 @@ -124,7 +124,7 @@ EOTXT; ob_start(); $collector->__destruct(); - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $this->assertSame("DumpDataCollectorTest.php on line {$line}:\n456\n", ob_get_clean()); } else { $this->assertSame("\"DumpDataCollectorTest.php on line {$line}:\"\n456\n", ob_get_clean()); diff --git a/vendor/symfony/http-kernel/Tests/EventListener/RouterListenerTest.php b/vendor/symfony/http-kernel/Tests/EventListener/RouterListenerTest.php index 86c5471e9..fbd60c75f 100644 --- a/vendor/symfony/http-kernel/Tests/EventListener/RouterListenerTest.php +++ b/vendor/symfony/http-kernel/Tests/EventListener/RouterListenerTest.php @@ -33,14 +33,14 @@ class RouterListenerTest extends TestCase public function testPort($defaultHttpPort, $defaultHttpsPort, $uri, $expectedHttpPort, $expectedHttpsPort) { $urlMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\UrlMatcherInterface') - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $context = new RequestContext(); $context->setHttpPort($defaultHttpPort); $context->setHttpsPort($defaultHttpsPort); $urlMatcher->expects($this->any()) - ->method('getContext') - ->will($this->returnValue($context)); + ->method('getContext') + ->will($this->returnValue($context)); $listener = new RouterListener($urlMatcher, $this->requestStack); $event = $this->createGetResponseEventForUri($uri); @@ -133,13 +133,13 @@ class RouterListenerTest extends TestCase { $requestMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock(); $requestMatcher->expects($this->once()) - ->method('matchRequest') - ->will($this->returnValue($parameter)); + ->method('matchRequest') + ->will($this->returnValue($parameter)); $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); $logger->expects($this->once()) - ->method('info') - ->with($this->equalTo($log)); + ->method('info') + ->with($this->equalTo($log)); $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(); $request = Request::create('http://localhost/'); diff --git a/vendor/symfony/http-kernel/composer.json b/vendor/symfony/http-kernel/composer.json index 14a36bbd4..ac8d3de84 100644 --- a/vendor/symfony/http-kernel/composer.json +++ b/vendor/symfony/http-kernel/composer.json @@ -40,7 +40,8 @@ "symfony/var-dumper": "~2.6|~3.0.0" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.7", + "twig/twig": "<1.34|<2.4,>=2" }, "suggest": { "symfony/browser-kit": "", diff --git a/vendor/symfony/http-kernel/phpunit.xml.dist b/vendor/symfony/http-kernel/phpunit.xml.dist index b29969b36..e0de769dd 100644 --- a/vendor/symfony/http-kernel/phpunit.xml.dist +++ b/vendor/symfony/http-kernel/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/polyfill-apcu/README.md b/vendor/symfony/polyfill-apcu/README.md new file mode 100644 index 000000000..e614bcab5 --- /dev/null +++ b/vendor/symfony/polyfill-apcu/README.md @@ -0,0 +1,12 @@ +Symfony Polyfill / APCu +======================== + +This component provides `apcu_*` functions and the `APCUIterator` class to users of the legacy APC extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-apcu/bootstrap.php b/vendor/symfony/polyfill-apcu/bootstrap.php index a5682af55..9433f6f42 100644 --- a/vendor/symfony/polyfill-apcu/bootstrap.php +++ b/vendor/symfony/polyfill-apcu/bootstrap.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -if (!extension_loaded('apc')) { +if (!extension_loaded('apc') && !extension_loaded('apcu')) { return; } diff --git a/vendor/symfony/polyfill-apcu/composer.json b/vendor/symfony/polyfill-apcu/composer.json index cb8df8bdb..6a12198b6 100644 --- a/vendor/symfony/polyfill-apcu/composer.json +++ b/vendor/symfony/polyfill-apcu/composer.json @@ -24,7 +24,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } } } diff --git a/vendor/symfony/polyfill-iconv/composer.json b/vendor/symfony/polyfill-iconv/composer.json index 7ea72cf35..f83afbd5f 100644 --- a/vendor/symfony/polyfill-iconv/composer.json +++ b/vendor/symfony/polyfill-iconv/composer.json @@ -28,7 +28,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } } } diff --git a/vendor/symfony/polyfill-mbstring/Mbstring.php b/vendor/symfony/polyfill-mbstring/Mbstring.php index 934cfcff0..97e8c9b46 100644 --- a/vendor/symfony/polyfill-mbstring/Mbstring.php +++ b/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -147,6 +147,9 @@ final class Mbstring if ('UTF-8' === $encoding) { $encoding = null; + if (!preg_match('//u', $s)) { + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + } } else { $s = iconv($encoding, 'UTF-8//IGNORE', $s); } @@ -336,10 +339,9 @@ final class Mbstring public static function mb_strlen($s, $encoding = null) { - switch ($encoding = self::getEncoding($encoding)) { - case 'ASCII': - case 'CP850': - return strlen($s); + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return strlen($s); } return @iconv_strlen($s, $encoding); @@ -348,6 +350,9 @@ final class Mbstring public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return strpos($haystack, $needle, $offset); + } if ('' === $needle .= '') { trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING); @@ -361,6 +366,9 @@ final class Mbstring public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return strrpos($haystack, $needle, $offset); + } if ($offset != (int) $offset) { $offset = 0; @@ -400,6 +408,9 @@ final class Mbstring public static function mb_substr($s, $start, $length = null, $encoding = null) { $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return substr($s, $start, null === $length ? 2147483647 : $length); + } if ($start < 0) { $start = iconv_strlen($s, $encoding) + $start; @@ -438,6 +449,9 @@ final class Mbstring public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null) { $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return strrchr($haystack, $needle, $part); + } $needle = self::mb_substr($needle, 0, 1, $encoding); $pos = iconv_strrpos($haystack, $needle, $encoding); diff --git a/vendor/symfony/polyfill-mbstring/composer.json b/vendor/symfony/polyfill-mbstring/composer.json index 24eefbde1..48fc3ddf3 100644 --- a/vendor/symfony/polyfill-mbstring/composer.json +++ b/vendor/symfony/polyfill-mbstring/composer.json @@ -28,7 +28,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } } } diff --git a/vendor/symfony/polyfill-php54/composer.json b/vendor/symfony/polyfill-php54/composer.json index 327f46c38..c659b58e3 100644 --- a/vendor/symfony/polyfill-php54/composer.json +++ b/vendor/symfony/polyfill-php54/composer.json @@ -26,7 +26,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } } } diff --git a/vendor/symfony/polyfill-php55/composer.json b/vendor/symfony/polyfill-php55/composer.json index 49deca9e9..8f1159b0c 100644 --- a/vendor/symfony/polyfill-php55/composer.json +++ b/vendor/symfony/polyfill-php55/composer.json @@ -26,7 +26,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } } } diff --git a/vendor/symfony/process/Tests/ProcessTest.php b/vendor/symfony/process/Tests/ProcessTest.php index e034aeb28..a1112b92a 100644 --- a/vendor/symfony/process/Tests/ProcessTest.php +++ b/vendor/symfony/process/Tests/ProcessTest.php @@ -725,8 +725,8 @@ class ProcessTest extends TestCase // Ensure that both processed finished and the output is numeric $this->assertFalse($process1->isRunning()); $this->assertFalse($process2->isRunning()); - $this->assertTrue(is_numeric($process1->getOutput())); - $this->assertTrue(is_numeric($process2->getOutput())); + $this->assertInternalType('numeric', $process1->getOutput()); + $this->assertInternalType('numeric', $process2->getOutput()); // Ensure that restart returned a new process by check that the output is different $this->assertNotEquals($process1->getOutput(), $process2->getOutput()); diff --git a/vendor/symfony/process/phpunit.xml.dist b/vendor/symfony/process/phpunit.xml.dist index 788500084..d38846730 100644 --- a/vendor/symfony/process/phpunit.xml.dist +++ b/vendor/symfony/process/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/routing/Loader/AnnotationFileLoader.php b/vendor/symfony/routing/Loader/AnnotationFileLoader.php index b8fc03615..d98e02464 100644 --- a/vendor/symfony/routing/Loader/AnnotationFileLoader.php +++ b/vendor/symfony/routing/Loader/AnnotationFileLoader.php @@ -64,7 +64,7 @@ class AnnotationFileLoader extends FileLoader $collection->addResource(new FileResource($path)); $collection->addCollection($this->loader->load($class, $type)); } - if (PHP_VERSION_ID >= 70000) { + if (\PHP_VERSION_ID >= 70000) { // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 gc_mem_caches(); } diff --git a/vendor/symfony/routing/phpunit.xml.dist b/vendor/symfony/routing/phpunit.xml.dist index b69f066ac..bcc095952 100644 --- a/vendor/symfony/routing/phpunit.xml.dist +++ b/vendor/symfony/routing/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/serializer/Encoder/JsonDecode.php b/vendor/symfony/serializer/Encoder/JsonDecode.php index 8925ec36f..9acb2bc5a 100644 --- a/vendor/symfony/serializer/Encoder/JsonDecode.php +++ b/vendor/symfony/serializer/Encoder/JsonDecode.php @@ -101,7 +101,7 @@ class JsonDecode implements DecoderInterface $recursionDepth = $context['json_decode_recursion_depth']; $options = $context['json_decode_options']; - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $decodedData = json_decode($data, $associative, $recursionDepth, $options); } else { $decodedData = json_decode($data, $associative, $recursionDepth); diff --git a/vendor/symfony/serializer/Encoder/XmlEncoder.php b/vendor/symfony/serializer/Encoder/XmlEncoder.php index 40f61167b..e8a24a39d 100644 --- a/vendor/symfony/serializer/Encoder/XmlEncoder.php +++ b/vendor/symfony/serializer/Encoder/XmlEncoder.php @@ -301,11 +301,19 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec $data = array(); foreach ($node->attributes as $attr) { - if (ctype_digit($attr->nodeValue)) { - $data['@'.$attr->nodeName] = (int) $attr->nodeValue; - } else { + if (!is_numeric($attr->nodeValue)) { $data['@'.$attr->nodeName] = $attr->nodeValue; + + continue; + } + + if (false !== $val = filter_var($attr->nodeValue, FILTER_VALIDATE_INT)) { + $data['@'.$attr->nodeName] = $val; + + continue; } + + $data['@'.$attr->nodeName] = (float) $attr->nodeValue; } return $data; @@ -460,7 +468,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec */ private function needsCdataWrapping($val) { - return preg_match('/[<>&]/', $val); + return 0 < preg_match('/[<>&]/', $val); } /** diff --git a/vendor/symfony/serializer/Normalizer/ObjectNormalizer.php b/vendor/symfony/serializer/Normalizer/ObjectNormalizer.php index 0fde26975..c31ba36a7 100644 --- a/vendor/symfony/serializer/Normalizer/ObjectNormalizer.php +++ b/vendor/symfony/serializer/Normalizer/ObjectNormalizer.php @@ -208,10 +208,22 @@ class ObjectNormalizer extends AbstractNormalizer if (0 === strpos($name, 'get') || 0 === strpos($name, 'has')) { // getters and hassers - $attributes[lcfirst(substr($name, 3))] = true; + $propertyName = substr($name, 3); + + if (!$reflClass->hasProperty($propertyName)) { + $propertyName = lcfirst($propertyName); + } + + $attributes[$propertyName] = true; } elseif (strpos($name, 'is') === 0) { // issers - $attributes[lcfirst(substr($name, 2))] = true; + $propertyName = substr($name, 2); + + if (!$reflClass->hasProperty($propertyName)) { + $propertyName = lcfirst($propertyName); + } + + $attributes[$propertyName] = true; } } diff --git a/vendor/symfony/serializer/Tests/Encoder/XmlEncoderTest.php b/vendor/symfony/serializer/Tests/Encoder/XmlEncoderTest.php index e036fbbaf..b8ec8fd0d 100644 --- a/vendor/symfony/serializer/Tests/Encoder/XmlEncoderTest.php +++ b/vendor/symfony/serializer/Tests/Encoder/XmlEncoderTest.php @@ -222,6 +222,46 @@ XML; $this->assertEquals('foo', $this->encoder->decode($source, 'xml')); } + public function testDecodeBigDigitAttributes() + { + $source = << +Name +XML; + + $this->assertSame(array('@index' => 182077241760011681341821060401202210011000045913000000017100, '#' => 'Name'), $this->encoder->decode($source, 'xml')); + } + + public function testDecodeNegativeIntAttribute() + { + $source = << +Name +XML; + + $this->assertSame(array('@index' => -1234, '#' => 'Name'), $this->encoder->decode($source, 'xml')); + } + + public function testDecodeFloatAttribute() + { + $source = << +Name +XML; + + $this->assertSame(array('@index' => -12.11, '#' => 'Name'), $this->encoder->decode($source, 'xml')); + } + + public function testDecodeNegativeFloatAttribute() + { + $source = << +Name +XML; + + $this->assertSame(array('@index' => -12.11, '#' => 'Name'), $this->encoder->decode($source, 'xml')); + } + public function testEncode() { $source = $this->getXmlSource(); diff --git a/vendor/symfony/serializer/Tests/Normalizer/ObjectNormalizerTest.php b/vendor/symfony/serializer/Tests/Normalizer/ObjectNormalizerTest.php index c0483180d..1f735cc24 100644 --- a/vendor/symfony/serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/vendor/symfony/serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -488,6 +488,11 @@ class ObjectNormalizerTest extends TestCase $this->assertEquals(array('foo' => 'K'), $this->normalizer->normalize(new ObjectWithStaticPropertiesAndMethods())); } + public function testNormalizeUpperCaseAttributes() + { + $this->assertEquals(array('Foo' => 'Foo', 'Bar' => 'BarBar'), $this->normalizer->normalize(new ObjectWithUpperCaseAttributeNames())); + } + public function testNormalizeNotSerializableContext() { $objectDummy = new ObjectDummy(); @@ -662,3 +667,14 @@ class ObjectWithStaticPropertiesAndMethods return 'L'; } } + +class ObjectWithUpperCaseAttributeNames +{ + private $Foo = 'Foo'; + public $Bar = 'BarBar'; + + public function getFoo() + { + return $this->Foo; + } +} diff --git a/vendor/symfony/serializer/phpunit.xml.dist b/vendor/symfony/serializer/phpunit.xml.dist index 4799e3cf2..ce9af71d9 100644 --- a/vendor/symfony/serializer/phpunit.xml.dist +++ b/vendor/symfony/serializer/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php b/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php index 3496567d1..62084d217 100644 --- a/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php +++ b/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php @@ -19,7 +19,7 @@ class JsonFileDumperTest extends TestCase { public function testFormatCatalogue() { - if (PHP_VERSION_ID < 50400) { + if (\PHP_VERSION_ID < 50400) { $this->markTestIncomplete('PHP below 5.4 doesn\'t support JSON pretty printing'); } diff --git a/vendor/symfony/translation/Tests/TranslatorCacheTest.php b/vendor/symfony/translation/Tests/TranslatorCacheTest.php index 5bd0d34e6..a60690f85 100644 --- a/vendor/symfony/translation/Tests/TranslatorCacheTest.php +++ b/vendor/symfony/translation/Tests/TranslatorCacheTest.php @@ -149,6 +149,17 @@ class TranslatorCacheTest extends TestCase $this->assertEquals('OK', $translator->trans($msgid), '-> the cache was overwritten by another translator instance in '.($debug ? 'debug' : 'production')); } + public function testGeneratedCacheFilesAreOnlyBelongRequestedLocales() + { + $translator = new Translator('a', null, $this->tmpDir); + $translator->setFallbackLocales(array('b')); + $translator->trans('bar'); + + $cachedFiles = glob($this->tmpDir.'/*.php'); + + $this->assertCount(1, $cachedFiles); + } + public function testDifferentCacheFilesAreUsedForDifferentSetsOfFallbackLocales() { /* diff --git a/vendor/symfony/translation/Translator.php b/vendor/symfony/translation/Translator.php index ac0d757a9..0e3dd06c5 100644 --- a/vendor/symfony/translation/Translator.php +++ b/vendor/symfony/translation/Translator.php @@ -424,7 +424,7 @@ EOF foreach ($this->computeFallbackLocales($locale) as $fallback) { if (!isset($this->catalogues[$fallback])) { - $this->loadCatalogue($fallback); + $this->initializeCatalogue($fallback); } $fallbackCatalogue = new MessageCatalogue($fallback, $this->catalogues[$fallback]->all()); diff --git a/vendor/symfony/translation/phpunit.xml.dist b/vendor/symfony/translation/phpunit.xml.dist index c25ec5eda..1fafa4691 100644 --- a/vendor/symfony/translation/phpunit.xml.dist +++ b/vendor/symfony/translation/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/validator/Constraints/EmailValidator.php b/vendor/symfony/validator/Constraints/EmailValidator.php index 6ae25e016..cdd162d81 100644 --- a/vendor/symfony/validator/Constraints/EmailValidator.php +++ b/vendor/symfony/validator/Constraints/EmailValidator.php @@ -93,7 +93,7 @@ class EmailValidator extends ConstraintValidator return; } - $host = substr($value, strrpos($value, '@') + 1); + $host = (string) substr($value, strrpos($value, '@') + 1); // Check for host DNS resource records if ($constraint->checkMX) { @@ -138,7 +138,7 @@ class EmailValidator extends ConstraintValidator */ private function checkMX($host) { - return checkdnsrr($host, 'MX'); + return '' !== $host && checkdnsrr($host, 'MX'); } /** @@ -150,6 +150,6 @@ class EmailValidator extends ConstraintValidator */ private function checkHost($host) { - return $this->checkMX($host) || (checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA')); + return '' !== $host && ($this->checkMX($host) || (checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA'))); } } diff --git a/vendor/symfony/validator/Constraints/UrlValidator.php b/vendor/symfony/validator/Constraints/UrlValidator.php index 7ab72bcff..c84f46c44 100644 --- a/vendor/symfony/validator/Constraints/UrlValidator.php +++ b/vendor/symfony/validator/Constraints/UrlValidator.php @@ -82,7 +82,7 @@ class UrlValidator extends ConstraintValidator if ($constraint->checkDNS) { $host = parse_url($value, PHP_URL_HOST); - if (!checkdnsrr($host, 'ANY')) { + if (!is_string($host) || !checkdnsrr($host, 'ANY')) { if ($this->context instanceof ExecutionContextInterface) { $this->context->buildViolation($constraint->dnsMessage) ->setParameter('{{ value }}', $this->formatValue($host)) diff --git a/vendor/symfony/validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php b/vendor/symfony/validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php index 2c1876347..fe0e25e6e 100644 --- a/vendor/symfony/validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php +++ b/vendor/symfony/validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php @@ -36,7 +36,7 @@ abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintVal { protected static function addPhp5Dot5Comparisons(array $comparisons) { - if (PHP_VERSION_ID < 50500) { + if (\PHP_VERSION_ID < 50500) { return $comparisons; } @@ -130,7 +130,7 @@ abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintVal if ($dirtyValue instanceof \DateTime || $dirtyValue instanceof \DateTimeInterface) { IntlTestHelper::requireIntl($this, '57.1'); - if (PHP_VERSION_ID < 50304 && !(extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) { + if (\PHP_VERSION_ID < 50304 && !(extension_loaded('intl') && method_exists('IntlDateFormatter', 'setTimeZone'))) { $this->markTestSkipped('Intl supports formatting DateTime objects since 5.3.4'); } } diff --git a/vendor/symfony/validator/Tests/Constraints/EmailValidatorTest.php b/vendor/symfony/validator/Tests/Constraints/EmailValidatorTest.php index cfa0e99c9..5933bd5ed 100644 --- a/vendor/symfony/validator/Tests/Constraints/EmailValidatorTest.php +++ b/vendor/symfony/validator/Tests/Constraints/EmailValidatorTest.php @@ -159,4 +159,32 @@ class EmailValidatorTest extends AbstractConstraintValidatorTest $this->assertNoViolation(); } + + /** + * @dataProvider provideCheckTypes + */ + public function testEmptyHostIsNotValid($checkType, $violation) + { + $this->validator->validate( + 'foo@bar.fr@', + new Email(array( + 'message' => 'myMessage', + $checkType => true, + )) + ); + + $this + ->buildViolation('myMessage') + ->setParameter('{{ value }}', '"foo@bar.fr@"') + ->setCode($violation) + ->assertRaised(); + } + + public function provideCheckTypes() + { + return array( + array('checkMX', Email::MX_CHECK_FAILED_ERROR), + array('checkHost', Email::HOST_CHECK_FAILED_ERROR), + ); + } } diff --git a/vendor/symfony/validator/Tests/Constraints/IdenticalToValidatorTest.php b/vendor/symfony/validator/Tests/Constraints/IdenticalToValidatorTest.php index 9ce3f32fc..a83af3d5c 100644 --- a/vendor/symfony/validator/Tests/Constraints/IdenticalToValidatorTest.php +++ b/vendor/symfony/validator/Tests/Constraints/IdenticalToValidatorTest.php @@ -69,7 +69,7 @@ class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase array(null, 1), ); - if (PHP_VERSION_ID >= 50500) { + if (\PHP_VERSION_ID >= 50500) { $immutableDate = new \DateTimeImmutable('2000-01-01'); $comparisons[] = array($immutableDate, $immutableDate); } diff --git a/vendor/symfony/validator/Tests/Constraints/RangeValidatorTest.php b/vendor/symfony/validator/Tests/Constraints/RangeValidatorTest.php index ed7d0c816..1093fa446 100644 --- a/vendor/symfony/validator/Tests/Constraints/RangeValidatorTest.php +++ b/vendor/symfony/validator/Tests/Constraints/RangeValidatorTest.php @@ -194,7 +194,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest array(new \DateTime('March 20, 2014')), ); - if (PHP_VERSION_ID >= 50500) { + if (\PHP_VERSION_ID >= 50500) { $tests[] = array(new \DateTimeImmutable('March 10, 2014')); $tests[] = array(new \DateTimeImmutable('March 15, 2014')); $tests[] = array(new \DateTimeImmutable('March 20, 2014')); @@ -216,7 +216,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest array(new \DateTime('March 9, 2014'), 'Mar 9, 2014, 12:00 AM'), ); - if (PHP_VERSION_ID >= 50500) { + if (\PHP_VERSION_ID >= 50500) { $tests[] = array(new \DateTimeImmutable('March 20, 2013'), 'Mar 20, 2013, 12:00 AM'); $tests[] = array(new \DateTimeImmutable('March 9, 2014'), 'Mar 9, 2014, 12:00 AM'); } @@ -237,7 +237,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest array(new \DateTime('March 9, 2015'), 'Mar 9, 2015, 12:00 AM'), ); - if (PHP_VERSION_ID >= 50500) { + if (\PHP_VERSION_ID >= 50500) { $tests[] = array(new \DateTimeImmutable('March 21, 2014'), 'Mar 21, 2014, 12:00 AM'); $tests[] = array(new \DateTimeImmutable('March 9, 2015'), 'Mar 9, 2015, 12:00 AM'); } diff --git a/vendor/symfony/validator/Tests/Constraints/UrlValidatorTest.php b/vendor/symfony/validator/Tests/Constraints/UrlValidatorTest.php index 57c00c2b8..9b89a9255 100644 --- a/vendor/symfony/validator/Tests/Constraints/UrlValidatorTest.php +++ b/vendor/symfony/validator/Tests/Constraints/UrlValidatorTest.php @@ -172,6 +172,7 @@ class UrlValidatorTest extends AbstractConstraintValidatorTest array('http://example.com/exploit.html?'), array('http://example.com/exploit.html?hel lo'), array('http://example.com/exploit.html?not_a%hex'), + array('http://'), ); } diff --git a/vendor/symfony/validator/Tests/Mapping/Loader/LoaderChainTest.php b/vendor/symfony/validator/Tests/Mapping/Loader/LoaderChainTest.php index 49a8b5256..0d28b0a39 100644 --- a/vendor/symfony/validator/Tests/Mapping/Loader/LoaderChainTest.php +++ b/vendor/symfony/validator/Tests/Mapping/Loader/LoaderChainTest.php @@ -23,13 +23,13 @@ class LoaderChainTest extends TestCase $loader1 = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock(); $loader1->expects($this->once()) - ->method('loadClassMetadata') - ->with($this->equalTo($metadata)); + ->method('loadClassMetadata') + ->with($this->equalTo($metadata)); $loader2 = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock(); $loader2->expects($this->once()) - ->method('loadClassMetadata') - ->with($this->equalTo($metadata)); + ->method('loadClassMetadata') + ->with($this->equalTo($metadata)); $chain = new LoaderChain(array( $loader1, @@ -45,13 +45,13 @@ class LoaderChainTest extends TestCase $loader1 = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock(); $loader1->expects($this->any()) - ->method('loadClassMetadata') - ->will($this->returnValue(true)); + ->method('loadClassMetadata') + ->will($this->returnValue(true)); $loader2 = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock(); $loader2->expects($this->any()) - ->method('loadClassMetadata') - ->will($this->returnValue(false)); + ->method('loadClassMetadata') + ->will($this->returnValue(false)); $chain = new LoaderChain(array( $loader1, @@ -67,13 +67,13 @@ class LoaderChainTest extends TestCase $loader1 = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock(); $loader1->expects($this->any()) - ->method('loadClassMetadata') - ->will($this->returnValue(false)); + ->method('loadClassMetadata') + ->will($this->returnValue(false)); $loader2 = $this->getMockBuilder('Symfony\Component\Validator\Mapping\Loader\LoaderInterface')->getMock(); $loader2->expects($this->any()) - ->method('loadClassMetadata') - ->will($this->returnValue(false)); + ->method('loadClassMetadata') + ->will($this->returnValue(false)); $chain = new LoaderChain(array( $loader1, diff --git a/vendor/symfony/validator/Validator.php b/vendor/symfony/validator/Validator.php index 4da27e7b3..feaec0d40 100644 --- a/vendor/symfony/validator/Validator.php +++ b/vendor/symfony/validator/Validator.php @@ -151,7 +151,7 @@ class Validator implements ValidatorInterface, Mapping\Factory\MetadataFactoryIn ? '"'.$containingValue.'"' : 'the value of type '.gettype($containingValue); - throw new ValidatorException(sprintf('The metadata for '.$valueAsString.' does not support properties.')); + throw new ValidatorException(sprintf('The metadata for %s does not support properties.', $valueAsString)); } // If $containingValue is passed as class name, take $value as root diff --git a/vendor/symfony/validator/phpunit.xml.dist b/vendor/symfony/validator/phpunit.xml.dist index cf8c34386..0e82129d7 100644 --- a/vendor/symfony/validator/phpunit.xml.dist +++ b/vendor/symfony/validator/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/var-dumper/Caster/ExceptionCaster.php b/vendor/symfony/var-dumper/Caster/ExceptionCaster.php index c0c60a421..3554becae 100644 --- a/vendor/symfony/var-dumper/Caster/ExceptionCaster.php +++ b/vendor/symfony/var-dumper/Caster/ExceptionCaster.php @@ -148,7 +148,7 @@ class ExceptionCaster if (file_exists($f['file']) && 0 <= self::$srcContext) { $src[$f['file'].':'.$f['line']] = self::extractSource(explode("\n", file_get_contents($f['file'])), $f['line'], self::$srcContext); - if (!empty($f['class']) && is_subclass_of($f['class'], 'Twig_Template') && method_exists($f['class'], 'getDebugInfo')) { + if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) { $template = isset($f['object']) ? $f['object'] : unserialize(sprintf('O:%d:"%s":0:{}', strlen($f['class']), $f['class'])); $templateName = $template->getTemplateName(); diff --git a/vendor/symfony/var-dumper/Caster/StubCaster.php b/vendor/symfony/var-dumper/Caster/StubCaster.php index 7556a19bd..45e0022d1 100644 --- a/vendor/symfony/var-dumper/Caster/StubCaster.php +++ b/vendor/symfony/var-dumper/Caster/StubCaster.php @@ -29,8 +29,10 @@ class StubCaster $stub->handle = $c->handle; $stub->cut = $c->cut; - return array(); + $a = array(); } + + return $a; } public static function castCutArray(CutArrayStub $c, array $a, Stub $stub, $isNested) diff --git a/vendor/symfony/var-dumper/Cloner/VarCloner.php b/vendor/symfony/var-dumper/Cloner/VarCloner.php index 753d6e04d..9c9717ce1 100644 --- a/vendor/symfony/var-dumper/Cloner/VarCloner.php +++ b/vendor/symfony/var-dumper/Cloner/VarCloner.php @@ -308,7 +308,7 @@ class VarCloner extends AbstractCloner } else { // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below $obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush'); - foreach (debug_backtrace(PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) { + foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) { if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && in_array($frame['function'], $obFuncs)) { $frame['line'] = 0; break; diff --git a/vendor/symfony/var-dumper/Dumper/AbstractDumper.php b/vendor/symfony/var-dumper/Dumper/AbstractDumper.php index ec8189b64..4e72c1887 100644 --- a/vendor/symfony/var-dumper/Dumper/AbstractDumper.php +++ b/vendor/symfony/var-dumper/Dumper/AbstractDumper.php @@ -167,6 +167,9 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface */ protected function utf8Encode($s) { + if (!function_exists('iconv')) { + throw new \RuntimeException('Unable to convert a non-UTF-8 string to UTF-8: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.'); + } if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) { return $c; } diff --git a/vendor/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php index 1614f58a9..4a3ece22a 100644 --- a/vendor/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php +++ b/vendor/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php @@ -17,7 +17,7 @@ use Symfony\Component\VarDumper\Test\VarDumperTestCase; class ExceptionCasterTest extends VarDumperTestCase { /** - * @requires function Twig_Template::getSourceContext + * @requires function Twig\Template::getSourceContext */ public function testFrameWithTwig() { diff --git a/vendor/symfony/var-dumper/Tests/CliDumperTest.php b/vendor/symfony/var-dumper/Tests/CliDumperTest.php index 90045958a..5ee3a6c11 100644 --- a/vendor/symfony/var-dumper/Tests/CliDumperTest.php +++ b/vendor/symfony/var-dumper/Tests/CliDumperTest.php @@ -14,6 +14,8 @@ namespace Symfony\Component\VarDumper\Tests; use Symfony\Component\VarDumper\Cloner\VarCloner; use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\Test\VarDumperTestCase; +use Twig\Environment; +use Twig\Loader\FilesystemLoader; /** * @author Nicolas Grekas @@ -45,7 +47,7 @@ class CliDumperTest extends VarDumperTestCase $closure54 = ''; $r = defined('HHVM_VERSION') ? '' : '#%d'; - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $closure54 = <<setColors(false); @@ -225,12 +227,11 @@ EOTXT ':stream' => eval('return function () use ($twig) { try { $twig->render(array()); - } catch (\Twig_Error_Runtime $e) { + } catch (\Twig\Error\RuntimeError $e) { throw $e->getPrevious(); } };'), )); - $line = __LINE__ - 2; $ref = (int) $out; $data = $cloner->cloneVar($out); @@ -266,16 +267,16 @@ stream resource {@{$ref} """ } } - %d. Twig_Template->displayWithErrorHandling() ==> __TwigTemplate_VarDumperFixture_u75a09->doDisplay(): { + %d. Twig%cTemplate->displayWithErrorHandling() ==> __TwigTemplate_VarDumperFixture_u75a09->doDisplay(): { src: { %sTemplate.php:%d: """ try {\\n \$this->doDisplay(\$context, \$blocks);\\n - } catch (Twig_Error \$e) {\\n + } catch (Twig%sError \$e) {\\n """ } } - %d. Twig_Template->display() ==> Twig_Template->displayWithErrorHandling(): { + %d. Twig%cTemplate->display() ==> Twig%cTemplate->displayWithErrorHandling(): { src: { %sTemplate.php:%d: """ {\\n @@ -284,7 +285,7 @@ stream resource {@{$ref} """ } } - %d. Twig_Template->render() ==> Twig_Template->display(): { + %d. Twig%cTemplate->render() ==> Twig%cTemplate->display(): { src: { %sTemplate.php:%d: """ try {\\n @@ -293,12 +294,10 @@ stream resource {@{$ref} """ } } - %d. %slosure%s() ==> Twig_Template->render(): { + %d. %slosure%s() ==> Twig%cTemplate->render(): { src: { - %sCliDumperTest.php:{$line}: """ - }\\n - };'),\\n - ));\\n + %sCliDumperTest.php:%d: """ +%A """ } } @@ -419,7 +418,7 @@ EOTXT */ public function testBuggyRefs() { - if (PHP_VERSION_ID >= 50600) { + if (\PHP_VERSION_ID >= 50600) { $this->markTestSkipped('PHP 5.6 fixed refs counting'); } diff --git a/vendor/symfony/var-dumper/Tests/Fixtures/Twig.php b/vendor/symfony/var-dumper/Tests/Fixtures/Twig.php index 9eaa39c88..6abc58155 100644 --- a/vendor/symfony/var-dumper/Tests/Fixtures/Twig.php +++ b/vendor/symfony/var-dumper/Tests/Fixtures/Twig.php @@ -1,11 +1,11 @@ filename ? null : ($this->filename ?: 'bar.twig')); + return new Twig\Source(" foo bar\n twig source\n\n", 'foo.twig', false === $this->filename ? null : ($this->filename ?: 'bar.twig')); } } diff --git a/vendor/symfony/var-dumper/Tests/HtmlDumperTest.php b/vendor/symfony/var-dumper/Tests/HtmlDumperTest.php index 0e494a7eb..47c7e20a9 100644 --- a/vendor/symfony/var-dumper/Tests/HtmlDumperTest.php +++ b/vendor/symfony/var-dumper/Tests/HtmlDumperTest.php @@ -49,7 +49,7 @@ class HtmlDumperTest extends TestCase $closure54 = ''; $r = defined('HHVM_VERSION') ? '' : '#%d'; - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $closure54 = <<class: "Symfony\Component\VarDumper\Tests\HtmlDumperTest" diff --git a/vendor/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php b/vendor/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php index a87476be7..81d1a0cf1 100644 --- a/vendor/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php +++ b/vendor/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php @@ -10,6 +10,6 @@ */ // Skipping trait tests for PHP < 5.4 -if (PHP_VERSION_ID >= 50400) { +if (\PHP_VERSION_ID >= 50400) { require __DIR__.'/VarDumperTestTraitRequire54.php'; } diff --git a/vendor/symfony/var-dumper/composer.json b/vendor/symfony/var-dumper/composer.json index 8213966c5..acc426804 100644 --- a/vendor/symfony/var-dumper/composer.json +++ b/vendor/symfony/var-dumper/composer.json @@ -20,12 +20,14 @@ "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "twig/twig": "~1.20|~2.0" + "ext-iconv": "*", + "twig/twig": "~1.34|~2.4" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", "ext-symfony_debug": "" }, "autoload": { diff --git a/vendor/symfony/var-dumper/phpunit.xml.dist b/vendor/symfony/var-dumper/phpunit.xml.dist index bb16a3a4e..1c03ff68d 100644 --- a/vendor/symfony/var-dumper/phpunit.xml.dist +++ b/vendor/symfony/var-dumper/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/yaml/Escaper.php b/vendor/symfony/yaml/Escaper.php index a74f14dd9..94bb3924b 100644 --- a/vendor/symfony/yaml/Escaper.php +++ b/vendor/symfony/yaml/Escaper.php @@ -33,13 +33,15 @@ class Escaper "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", - "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9"); + "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9", + ); private static $escaped = array('\\\\', '\\"', '\\\\', '\\"', '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a', '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f', '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f', - '\\N', '\\_', '\\L', '\\P'); + '\\N', '\\_', '\\L', '\\P', + ); /** * Determines if a PHP value would require double quoting in YAML. @@ -50,7 +52,7 @@ class Escaper */ public static function requiresDoubleQuoting($value) { - return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); + return 0 < preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); } /** @@ -82,7 +84,7 @@ class Escaper // Determines if the PHP value contains any single characters that would // cause it to require single quoting in YAML. - return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value); + return 0 < preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value); } /** diff --git a/vendor/symfony/yaml/Exception/ParseException.php b/vendor/symfony/yaml/Exception/ParseException.php index b74eb9132..ef36cfbad 100644 --- a/vendor/symfony/yaml/Exception/ParseException.php +++ b/vendor/symfony/yaml/Exception/ParseException.php @@ -26,11 +26,11 @@ class ParseException extends RuntimeException /** * Constructor. * - * @param string $message The error message - * @param int $parsedLine The line where the error occurred - * @param int $snippet The snippet of code near the problem - * @param string $parsedFile The file name where the error occurred - * @param \Exception $previous The previous exception + * @param string $message The error message + * @param int $parsedLine The line where the error occurred + * @param string|null $snippet The snippet of code near the problem + * @param string|null $parsedFile The file name where the error occurred + * @param \Exception|null $previous The previous exception */ public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null) { @@ -123,7 +123,7 @@ class ParseException extends RuntimeException } if (null !== $this->parsedFile) { - if (PHP_VERSION_ID >= 50400) { + if (\PHP_VERSION_ID >= 50400) { $jsonOptions = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; } else { $jsonOptions = 0; diff --git a/vendor/symfony/yaml/Inline.php b/vendor/symfony/yaml/Inline.php index a2674369c..dade755e6 100644 --- a/vendor/symfony/yaml/Inline.php +++ b/vendor/symfony/yaml/Inline.php @@ -212,12 +212,12 @@ class Inline /** * Parses a YAML scalar. * - * @param string $scalar - * @param string $delimiters - * @param array $stringDelimiters - * @param int &$i - * @param bool $evaluate - * @param array $references + * @param string $scalar + * @param string[] $delimiters + * @param string[] $stringDelimiters + * @param int &$i + * @param bool $evaluate + * @param array $references * * @return string * @@ -453,7 +453,7 @@ class Inline * @param string $scalar * @param array $references * - * @return string A YAML string + * @return mixed The evaluated YAML string * * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved */ diff --git a/vendor/symfony/yaml/Parser.php b/vendor/symfony/yaml/Parser.php index 25da4e9f2..96a85a8fe 100644 --- a/vendor/symfony/yaml/Parser.php +++ b/vendor/symfony/yaml/Parser.php @@ -64,23 +64,57 @@ class Parser if (false === preg_match('//u', $value)) { throw new ParseException('The YAML value does not appear to be valid UTF-8.'); } + + $this->refs = array(); + + $mbEncoding = null; + $e = null; + $data = null; + + if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('UTF-8'); + } + + try { + $data = $this->doParse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap); + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + + if (null !== $mbEncoding) { + mb_internal_encoding($mbEncoding); + } + + $this->lines = array(); + $this->currentLine = ''; + $this->refs = array(); + $this->skippedLineNumbers = array(); + $this->locallySkippedLineNumbers = array(); + + if (null !== $e) { + throw $e; + } + + return $data; + } + + private function doParse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false) + { $this->currentLineNb = -1; $this->currentLine = ''; $value = $this->cleanup($value); $this->lines = explode("\n", $value); + $this->locallySkippedLineNumbers = array(); if (null === $this->totalNumberOfLines) { $this->totalNumberOfLines = count($this->lines); } - if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { - $mbEncoding = mb_internal_encoding(); - mb_internal_encoding('UTF-8'); - } - $data = array(); $context = null; $allowOverwrite = false; + while ($this->moveToNextLine()) { if ($this->isCurrentLineEmpty()) { continue; @@ -246,10 +280,6 @@ class Parser throw $e; } - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - return $value; } @@ -257,10 +287,6 @@ class Parser } } - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - if ($objectForMap && !is_object($data) && 'mapping' === $context) { $object = new \stdClass(); @@ -289,7 +315,7 @@ class Parser $parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers); $parser->refs = &$this->refs; - return $parser->parse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap); + return $parser->doParse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap); } /** diff --git a/vendor/symfony/yaml/Tests/DumperTest.php b/vendor/symfony/yaml/Tests/DumperTest.php new file mode 100644 index 000000000..6a1b3ac3d --- /dev/null +++ b/vendor/symfony/yaml/Tests/DumperTest.php @@ -0,0 +1,257 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Dumper; + +class DumperTest extends TestCase +{ + protected $parser; + protected $dumper; + protected $path; + + protected $array = array( + '' => 'bar', + 'foo' => '#bar', + 'foo\'bar' => array(), + 'bar' => array(1, 'foo'), + 'foobar' => array( + 'foo' => 'bar', + 'bar' => array(1, 'foo'), + 'foobar' => array( + 'foo' => 'bar', + 'bar' => array(1, 'foo'), + ), + ), + ); + + protected function setUp() + { + $this->parser = new Parser(); + $this->dumper = new Dumper(); + $this->path = __DIR__.'/Fixtures'; + } + + protected function tearDown() + { + $this->parser = null; + $this->dumper = null; + $this->path = null; + $this->array = null; + } + + public function testSetIndentation() + { + $this->dumper->setIndentation(7); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: + - 1 + - foo + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 4, 0)); + } + + public function testSpecifications() + { + $files = $this->parser->parse(file_get_contents($this->path.'/index.yml')); + foreach ($files as $file) { + $yamls = file_get_contents($this->path.'/'.$file.'.yml'); + + // split YAMLs documents + foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) { + if (!$yaml) { + continue; + } + + $test = $this->parser->parse($yaml); + if (isset($test['dump_skip']) && $test['dump_skip']) { + continue; + } elseif (isset($test['todo']) && $test['todo']) { + // TODO + } else { + eval('$expected = '.trim($test['php']).';'); + $this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']); + } + } + } + } + + public function testInlineLevel() + { + $expected = <<<'EOF' +{ '': bar, foo: '#bar', 'foo''bar': { }, bar: [1, foo], foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } } +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, -10), '->dump() takes an inline level argument'); + $this->assertEquals($expected, $this->dumper->dump($this->array, 0), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: [1, foo] +foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 1), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: [1, foo] + foobar: { foo: bar, bar: [1, foo] } + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 2), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: [1, foo] + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 3), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: + - 1 + - foo + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 4), '->dump() takes an inline level argument'); + $this->assertEquals($expected, $this->dumper->dump($this->array, 10), '->dump() takes an inline level argument'); + } + + public function testObjectSupportEnabled() + { + $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, true); + + $this->assertEquals('{ foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects'); + } + + public function testObjectSupportDisabledButNoExceptions() + { + $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1)); + + $this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\DumpException + */ + public function testObjectSupportDisabledWithExceptions() + { + $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, true, false); + } + + /** + * @dataProvider getEscapeSequences + */ + public function testEscapedEscapeSequencesInQuotedScalar($input, $expected) + { + $this->assertEquals($expected, $this->dumper->dump($input)); + } + + public function getEscapeSequences() + { + return array( + 'empty string' => array('', "''"), + 'null' => array("\x0", '"\\0"'), + 'bell' => array("\x7", '"\\a"'), + 'backspace' => array("\x8", '"\\b"'), + 'horizontal-tab' => array("\t", '"\\t"'), + 'line-feed' => array("\n", '"\\n"'), + 'vertical-tab' => array("\v", '"\\v"'), + 'form-feed' => array("\xC", '"\\f"'), + 'carriage-return' => array("\r", '"\\r"'), + 'escape' => array("\x1B", '"\\e"'), + 'space' => array(' ', "' '"), + 'double-quote' => array('"', "'\"'"), + 'slash' => array('/', '/'), + 'backslash' => array('\\', '\\'), + 'next-line' => array("\xC2\x85", '"\\N"'), + 'non-breaking-space' => array("\xc2\xa0", '"\\_"'), + 'line-separator' => array("\xE2\x80\xA8", '"\\L"'), + 'paragraph-separator' => array("\xE2\x80\xA9", '"\\P"'), + 'colon' => array(':', "':'"), + ); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The indentation must be greater than zero + */ + public function testZeroIndentationThrowsException() + { + $this->dumper->setIndentation(0); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The indentation must be greater than zero + */ + public function testNegativeIndentationThrowsException() + { + $this->dumper->setIndentation(-4); + } +} + +class A +{ + public $a = 'foo'; +} diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml new file mode 100644 index 000000000..5f9c94275 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml @@ -0,0 +1,31 @@ +--- %YAML:1.0 +test: Simple Alias Example +brief: > + If you need to refer to the same item of data twice, + you can give that item an alias. The alias is a plain + string, starting with an ampersand. The item may then + be referred to by the alias throughout your document + by using an asterisk before the name of the alias. + This is called an anchor. +yaml: | + - &showell Steve + - Clark + - Brian + - Oren + - *showell +php: | + array('Steve', 'Clark', 'Brian', 'Oren', 'Steve') + +--- +test: Alias of a Mapping +brief: > + An alias can be used on any item of data, including + sequences, mappings, and other complex data types. +yaml: | + - &hello + Meat: pork + Starch: potato + - banana + - *hello +php: | + array(array('Meat'=>'pork', 'Starch'=>'potato'), 'banana', array('Meat'=>'pork', 'Starch'=>'potato')) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml new file mode 100644 index 000000000..dfd93021d --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml @@ -0,0 +1,202 @@ +--- %YAML:1.0 +test: Simple Sequence +brief: | + You can specify a list in YAML by placing each + member of the list on a new line with an opening + dash. These lists are called sequences. +yaml: | + - apple + - banana + - carrot +php: | + array('apple', 'banana', 'carrot') +--- +test: Sequence With Item Being Null In The Middle +brief: | + You can specify a list in YAML by placing each + member of the list on a new line with an opening + dash. These lists are called sequences. +yaml: | + - apple + - + - carrot +php: | + array('apple', null, 'carrot') +--- +test: Sequence With Last Item Being Null +brief: | + You can specify a list in YAML by placing each + member of the list on a new line with an opening + dash. These lists are called sequences. +yaml: | + - apple + - banana + - +php: | + array('apple', 'banana', null) +--- +test: Nested Sequences +brief: | + You can include a sequence within another + sequence by giving the sequence an empty + dash, followed by an indented list. +yaml: | + - + - foo + - bar + - baz +php: | + array(array('foo', 'bar', 'baz')) +--- +test: Mixed Sequences +brief: | + Sequences can contain any YAML data, + including strings and other sequences. +yaml: | + - apple + - + - foo + - bar + - x123 + - banana + - carrot +php: | + array('apple', array('foo', 'bar', 'x123'), 'banana', 'carrot') +--- +test: Deeply Nested Sequences +brief: | + Sequences can be nested even deeper, with each + level of indentation representing a level of + depth. +yaml: | + - + - + - uno + - dos +php: | + array(array(array('uno', 'dos'))) +--- +test: Simple Mapping +brief: | + You can add a keyed list (also known as a dictionary or + hash) to your document by placing each member of the + list on a new line, with a colon separating the key + from its value. In YAML, this type of list is called + a mapping. +yaml: | + foo: whatever + bar: stuff +php: | + array('foo' => 'whatever', 'bar' => 'stuff') +--- +test: Sequence in a Mapping +brief: | + A value in a mapping can be a sequence. +yaml: | + foo: whatever + bar: + - uno + - dos +php: | + array('foo' => 'whatever', 'bar' => array('uno', 'dos')) +--- +test: Nested Mappings +brief: | + A value in a mapping can be another mapping. +yaml: | + foo: whatever + bar: + fruit: apple + name: steve + sport: baseball +php: | + array( + 'foo' => 'whatever', + 'bar' => array( + 'fruit' => 'apple', + 'name' => 'steve', + 'sport' => 'baseball' + ) + ) +--- +test: Mixed Mapping +brief: | + A mapping can contain any assortment + of mappings and sequences as values. +yaml: | + foo: whatever + bar: + - + fruit: apple + name: steve + sport: baseball + - more + - + python: rocks + perl: papers + ruby: scissorses +php: | + array( + 'foo' => 'whatever', + 'bar' => array( + array( + 'fruit' => 'apple', + 'name' => 'steve', + 'sport' => 'baseball' + ), + 'more', + array( + 'python' => 'rocks', + 'perl' => 'papers', + 'ruby' => 'scissorses' + ) + ) + ) +--- +test: Mapping-in-Sequence Shortcut +todo: true +brief: | + If you are adding a mapping to a sequence, you + can place the mapping on the same line as the + dash as a shortcut. +yaml: | + - work on YAML.py: + - work on Store +php: | + array(array('work on YAML.py' => array('work on Store'))) +--- +test: Sequence-in-Mapping Shortcut +todo: true +brief: | + The dash in a sequence counts as indentation, so + you can add a sequence inside of a mapping without + needing spaces as indentation. +yaml: | + allow: + - 'localhost' + - '%.sourceforge.net' + - '%.freepan.org' +php: | + array('allow' => array('localhost', '%.sourceforge.net', '%.freepan.org')) +--- +todo: true +test: Merge key +brief: | + A merge key ('<<') can be used in a mapping to insert other mappings. If + the value associated with the merge key is a mapping, each of its key/value + pairs is inserted into the current mapping. +yaml: | + mapping: + name: Joe + job: Accountant + <<: + age: 38 +php: | + array( + 'mapping' => + array( + 'name' => 'Joe', + 'job' => 'Accountant', + 'age' => 38 + ) + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml new file mode 100644 index 000000000..f7ca469b4 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml @@ -0,0 +1,51 @@ +--- +test: One Element Mapping +brief: | + A mapping with one key/value pair +yaml: | + foo: bar +php: | + array('foo' => 'bar') +--- +test: Multi Element Mapping +brief: | + More than one key/value pair +yaml: | + red: baron + white: walls + blue: berries +php: | + array( + 'red' => 'baron', + 'white' => 'walls', + 'blue' => 'berries', + ) +--- +test: Values aligned +brief: | + Often times human editors of documents will align the values even + though YAML emitters generally don't. +yaml: | + red: baron + white: walls + blue: berries +php: | + array( + 'red' => 'baron', + 'white' => 'walls', + 'blue' => 'berries', + ) +--- +test: Colons aligned +brief: | + Spaces can come before the ': ' key/value separator. +yaml: | + red : baron + white : walls + blue : berries +php: | + array( + 'red' => 'baron', + 'white' => 'walls', + 'blue' => 'berries', + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml new file mode 100644 index 000000000..d98810256 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml @@ -0,0 +1,85 @@ +--- %YAML:1.0 +test: Trailing Document Separator +todo: true +brief: > + You can separate YAML documents + with a string of three dashes. +yaml: | + - foo: 1 + bar: 2 + --- + more: stuff +python: | + [ + [ { 'foo': 1, 'bar': 2 } ], + { 'more': 'stuff' } + ] +ruby: | + [ { 'foo' => 1, 'bar' => 2 } ] + +--- +test: Leading Document Separator +todo: true +brief: > + You can explicitly give an opening + document separator to your YAML stream. +yaml: | + --- + - foo: 1 + bar: 2 + --- + more: stuff +python: | + [ + [ {'foo': 1, 'bar': 2}], + {'more': 'stuff'} + ] +ruby: | + [ { 'foo' => 1, 'bar' => 2 } ] + +--- +test: YAML Header +todo: true +brief: > + The opening separator can contain directives + to the YAML parser, such as the version + number. +yaml: | + --- %YAML:1.0 + foo: 1 + bar: 2 +php: | + array('foo' => 1, 'bar' => 2) +documents: 1 + +--- +test: Red Herring Document Separator +brief: > + Separators included in blocks or strings + are treated as blocks or strings, as the + document separator should have no indentation + preceding it. +yaml: | + foo: | + --- +php: | + array('foo' => "---\n") + +--- +test: Multiple Document Separators in Block +brief: > + This technique allows you to embed other YAML + documents within literal blocks. +yaml: | + foo: | + --- + foo: bar + --- + yo: baz + bar: | + fooness +php: | + array( + 'foo' => "---\nfoo: bar\n---\nyo: baz\n", + 'bar' => "fooness\n" + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml new file mode 100644 index 000000000..e8506fcb6 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml @@ -0,0 +1,25 @@ +--- +test: Missing value for hash item +todo: true +brief: | + Third item in this hash doesn't have a value +yaml: | + okay: value + also okay: ~ + causes error because no value specified + last key: value okay here too +python-error: causes error because no value specified + +--- +test: Not indenting enough +brief: | + There was a bug in PyYaml where it was off by one + in the indentation check. It was allowing the YAML + below. +# This is actually valid YAML now. Someone should tell showell. +yaml: | + foo: + firstline: 1 + secondline: 2 +php: | + array('foo' => null, 'firstline' => 1, 'secondline' => 2) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml new file mode 100644 index 000000000..03090e4ab --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml @@ -0,0 +1,60 @@ +--- +test: Simple Inline Array +brief: > + Sequences can be contained on a + single line, using the inline syntax. + Separate each entry with commas and + enclose in square brackets. +yaml: | + seq: [ a, b, c ] +php: | + array('seq' => array('a', 'b', 'c')) +--- +test: Simple Inline Hash +brief: > + Mapping can also be contained on + a single line, using the inline + syntax. Each key-value pair is + separated by a colon, with a comma + between each entry in the mapping. + Enclose with curly braces. +yaml: | + hash: { name: Steve, foo: bar } +php: | + array('hash' => array('name' => 'Steve', 'foo' => 'bar')) +--- +test: Multi-line Inline Collections +todo: true +brief: > + Both inline sequences and inline mappings + can span multiple lines, provided that you + indent the additional lines. +yaml: | + languages: [ Ruby, + Perl, + Python ] + websites: { YAML: yaml.org, + Ruby: ruby-lang.org, + Python: python.org, + Perl: use.perl.org } +php: | + array( + 'languages' => array('Ruby', 'Perl', 'Python'), + 'websites' => array( + 'YAML' => 'yaml.org', + 'Ruby' => 'ruby-lang.org', + 'Python' => 'python.org', + 'Perl' => 'use.perl.org' + ) + ) +--- +test: Commas in Values (not in the spec!) +todo: true +brief: > + List items in collections are delimited by commas, but + there must be a space after each comma. This allows you + to add numbers without quoting. +yaml: | + attendances: [ 45,123, 70,000, 17,222 ] +php: | + array('attendances' => array(45123, 70000, 17222)) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml new file mode 100644 index 000000000..a14735a55 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml @@ -0,0 +1,176 @@ +--- %YAML:1.0 +test: Single ending newline +brief: > + A pipe character, followed by an indented + block of text is treated as a literal + block, in which newlines are preserved + throughout the block, including the final + newline. +yaml: | + --- + this: | + Foo + Bar +php: | + array('this' => "Foo\nBar\n") +--- +test: The '+' indicator +brief: > + The '+' indicator says to keep newlines at the end of text + blocks. +yaml: | + normal: | + extra new lines not kept + + preserving: |+ + extra new lines are kept + + + dummy: value +php: | + array( + 'normal' => "extra new lines not kept\n", + 'preserving' => "extra new lines are kept\n\n\n", + 'dummy' => 'value' + ) +--- +test: Three trailing newlines in literals +brief: > + To give you more control over how space + is preserved in text blocks, YAML has + the keep '+' and chomp '-' indicators. + The keep indicator will preserve all + ending newlines, while the chomp indicator + will strip all ending newlines. +yaml: | + clipped: | + This has one newline. + + + + same as "clipped" above: "This has one newline.\n" + + stripped: |- + This has no newline. + + + + same as "stripped" above: "This has no newline." + + kept: |+ + This has four newlines. + + + + same as "kept" above: "This has four newlines.\n\n\n\n" +php: | + array( + 'clipped' => "This has one newline.\n", + 'same as "clipped" above' => "This has one newline.\n", + 'stripped' => 'This has no newline.', + 'same as "stripped" above' => 'This has no newline.', + 'kept' => "This has four newlines.\n\n\n\n", + 'same as "kept" above' => "This has four newlines.\n\n\n\n" + ) +--- +test: Extra trailing newlines with spaces +todo: true +brief: > + Normally, only a single newline is kept + from the end of a literal block, unless the + keep '+' character is used in combination + with the pipe. The following example + will preserve all ending whitespace + since the last line of both literal blocks + contains spaces which extend past the indentation + level. +yaml: | + --- + this: | + Foo + + + kept: |+ + Foo + + +php: | + array('this' => "Foo\n\n \n", + 'kept' => "Foo\n\n \n" ) + +--- +test: Folded Block in a Sequence +brief: > + A greater-then character, followed by an indented + block of text is treated as a folded block, in + which lines of text separated by a single newline + are concatenated as a single line. +yaml: | + --- + - apple + - banana + - > + can't you see + the beauty of yaml? + hmm + - dog +php: | + array( + 'apple', + 'banana', + "can't you see the beauty of yaml? hmm\n", + 'dog' + ) +--- +test: Folded Block as a Mapping Value +brief: > + Both literal and folded blocks can be + used in collections, as values in a + sequence or a mapping. +yaml: | + --- + quote: > + Mark McGwire's + year was crippled + by a knee injury. + source: espn +php: | + array( + 'quote' => "Mark McGwire's year was crippled by a knee injury.\n", + 'source' => 'espn' + ) +--- +test: Three trailing newlines in folded blocks +brief: > + The keep and chomp indicators can also + be applied to folded blocks. +yaml: | + clipped: > + This has one newline. + + + + same as "clipped" above: "This has one newline.\n" + + stripped: >- + This has no newline. + + + + same as "stripped" above: "This has no newline." + + kept: >+ + This has four newlines. + + + + same as "kept" above: "This has four newlines.\n\n\n\n" +php: | + array( + 'clipped' => "This has one newline.\n", + 'same as "clipped" above' => "This has one newline.\n", + 'stripped' => 'This has no newline.', + 'same as "stripped" above' => 'This has no newline.', + 'kept' => "This has four newlines.\n\n\n\n", + 'same as "kept" above' => "This has four newlines.\n\n\n\n" + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml new file mode 100644 index 000000000..9a5300f2e --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml @@ -0,0 +1,45 @@ +--- %YAML:1.0 +test: Empty Sequence +brief: > + You can represent the empty sequence + with an empty inline sequence. +yaml: | + empty: [] +php: | + array('empty' => array()) +--- +test: Empty Mapping +brief: > + You can represent the empty mapping + with an empty inline mapping. +yaml: | + empty: {} +php: | + array('empty' => array()) +--- +test: Empty Sequence as Entire Document +yaml: | + [] +php: | + array() +--- +test: Empty Mapping as Entire Document +yaml: | + {} +php: | + array() +--- +test: Null as Document +yaml: | + ~ +php: | + null +--- +test: Empty String +brief: > + You can represent an empty string + with a pair of quotes. +yaml: | + '' +php: | + '' diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml new file mode 100644 index 000000000..ec1c4c3a1 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml @@ -0,0 +1,1697 @@ +--- %YAML:1.0 +test: Sequence of scalars +spec: 2.1 +yaml: | + - Mark McGwire + - Sammy Sosa + - Ken Griffey +php: | + array('Mark McGwire', 'Sammy Sosa', 'Ken Griffey') +--- +test: Mapping of scalars to scalars +spec: 2.2 +yaml: | + hr: 65 + avg: 0.278 + rbi: 147 +php: | + array('hr' => 65, 'avg' => 0.278, 'rbi' => 147) +--- +test: Mapping of scalars to sequences +spec: 2.3 +yaml: | + american: + - Boston Red Sox + - Detroit Tigers + - New York Yankees + national: + - New York Mets + - Chicago Cubs + - Atlanta Braves +php: | + array('american' => + array( 'Boston Red Sox', 'Detroit Tigers', + 'New York Yankees' ), + 'national' => + array( 'New York Mets', 'Chicago Cubs', + 'Atlanta Braves' ) + ) +--- +test: Sequence of mappings +spec: 2.4 +yaml: | + - + name: Mark McGwire + hr: 65 + avg: 0.278 + - + name: Sammy Sosa + hr: 63 + avg: 0.288 +php: | + array( + array('name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278), + array('name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288) + ) +--- +test: Legacy A5 +todo: true +spec: legacy_A5 +yaml: | + ? + - New York Yankees + - Atlanta Braves + : + - 2001-07-02 + - 2001-08-12 + - 2001-08-14 + ? + - Detroit Tigers + - Chicago Cubs + : + - 2001-07-23 +perl-busted: > + YAML.pm will be able to emulate this behavior soon. In this regard + it may be somewhat more correct than Python's native behaviour which + can only use tuples as mapping keys. PyYAML will also need to figure + out some clever way to roundtrip structured keys. +python: | + [ + { + ('New York Yankees', 'Atlanta Braves'): + [yaml.timestamp('2001-07-02'), + yaml.timestamp('2001-08-12'), + yaml.timestamp('2001-08-14')], + ('Detroit Tigers', 'Chicago Cubs'): + [yaml.timestamp('2001-07-23')] + } + ] +ruby: | + { + [ 'New York Yankees', 'Atlanta Braves' ] => + [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ], + [ 'Detroit Tigers', 'Chicago Cubs' ] => + [ Date.new( 2001, 7, 23 ) ] + } +syck: | + struct test_node seq1[] = { + { T_STR, 0, "New York Yankees" }, + { T_STR, 0, "Atlanta Braves" }, + end_node + }; + struct test_node seq2[] = { + { T_STR, 0, "2001-07-02" }, + { T_STR, 0, "2001-08-12" }, + { T_STR, 0, "2001-08-14" }, + end_node + }; + struct test_node seq3[] = { + { T_STR, 0, "Detroit Tigers" }, + { T_STR, 0, "Chicago Cubs" }, + end_node + }; + struct test_node seq4[] = { + { T_STR, 0, "2001-07-23" }, + end_node + }; + struct test_node map[] = { + { T_SEQ, 0, 0, seq1 }, + { T_SEQ, 0, 0, seq2 }, + { T_SEQ, 0, 0, seq3 }, + { T_SEQ, 0, 0, seq4 }, + end_node + }; + struct test_node stream[] = { + { T_MAP, 0, 0, map }, + end_node + }; + +--- +test: Sequence of sequences +spec: 2.5 +yaml: | + - [ name , hr , avg ] + - [ Mark McGwire , 65 , 0.278 ] + - [ Sammy Sosa , 63 , 0.288 ] +php: | + array( + array( 'name', 'hr', 'avg' ), + array( 'Mark McGwire', 65, 0.278 ), + array( 'Sammy Sosa', 63, 0.288 ) + ) +--- +test: Mapping of mappings +todo: true +spec: 2.6 +yaml: | + Mark McGwire: {hr: 65, avg: 0.278} + Sammy Sosa: { + hr: 63, + avg: 0.288 + } +php: | + array( + 'Mark McGwire' => + array( 'hr' => 65, 'avg' => 0.278 ), + 'Sammy Sosa' => + array( 'hr' => 63, 'avg' => 0.288 ) + ) +--- +test: Two documents in a stream each with a leading comment +todo: true +spec: 2.7 +yaml: | + # Ranking of 1998 home runs + --- + - Mark McGwire + - Sammy Sosa + - Ken Griffey + + # Team ranking + --- + - Chicago Cubs + - St Louis Cardinals +ruby: | + y = YAML::Stream.new + y.add( [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] ) + y.add( [ 'Chicago Cubs', 'St Louis Cardinals' ] ) +documents: 2 + +--- +test: Play by play feed from a game +todo: true +spec: 2.8 +yaml: | + --- + time: 20:03:20 + player: Sammy Sosa + action: strike (miss) + ... + --- + time: 20:03:47 + player: Sammy Sosa + action: grand slam + ... +perl: | + [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] +documents: 2 + +--- +test: Single document with two comments +spec: 2.9 +yaml: | + hr: # 1998 hr ranking + - Mark McGwire + - Sammy Sosa + rbi: + # 1998 rbi ranking + - Sammy Sosa + - Ken Griffey +php: | + array( + 'hr' => array( 'Mark McGwire', 'Sammy Sosa' ), + 'rbi' => array( 'Sammy Sosa', 'Ken Griffey' ) + ) +--- +test: Node for Sammy Sosa appears twice in this document +spec: 2.10 +yaml: | + --- + hr: + - Mark McGwire + # Following node labeled SS + - &SS Sammy Sosa + rbi: + - *SS # Subsequent occurrence + - Ken Griffey +php: | + array( + 'hr' => + array('Mark McGwire', 'Sammy Sosa'), + 'rbi' => + array('Sammy Sosa', 'Ken Griffey') + ) +--- +test: Mapping between sequences +todo: true +spec: 2.11 +yaml: | + ? # PLAY SCHEDULE + - Detroit Tigers + - Chicago Cubs + : + - 2001-07-23 + + ? [ New York Yankees, + Atlanta Braves ] + : [ 2001-07-02, 2001-08-12, + 2001-08-14 ] +ruby: | + { + [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ], + [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ] + } +syck: | + struct test_node seq1[] = { + { T_STR, 0, "New York Yankees" }, + { T_STR, 0, "Atlanta Braves" }, + end_node + }; + struct test_node seq2[] = { + { T_STR, 0, "2001-07-02" }, + { T_STR, 0, "2001-08-12" }, + { T_STR, 0, "2001-08-14" }, + end_node + }; + struct test_node seq3[] = { + { T_STR, 0, "Detroit Tigers" }, + { T_STR, 0, "Chicago Cubs" }, + end_node + }; + struct test_node seq4[] = { + { T_STR, 0, "2001-07-23" }, + end_node + }; + struct test_node map[] = { + { T_SEQ, 0, 0, seq3 }, + { T_SEQ, 0, 0, seq4 }, + { T_SEQ, 0, 0, seq1 }, + { T_SEQ, 0, 0, seq2 }, + end_node + }; + struct test_node stream[] = { + { T_MAP, 0, 0, map }, + end_node + }; + +--- +test: Sequence key shortcut +spec: 2.12 +yaml: | + --- + # products purchased + - item : Super Hoop + quantity: 1 + - item : Basketball + quantity: 4 + - item : Big Shoes + quantity: 1 +php: | + array ( + array ( + 'item' => 'Super Hoop', + 'quantity' => 1, + ), + array ( + 'item' => 'Basketball', + 'quantity' => 4, + ), + array ( + 'item' => 'Big Shoes', + 'quantity' => 1, + ) + ) +perl: | + [ + { item => 'Super Hoop', quantity => 1 }, + { item => 'Basketball', quantity => 4 }, + { item => 'Big Shoes', quantity => 1 } + ] + +ruby: | + [ + { 'item' => 'Super Hoop', 'quantity' => 1 }, + { 'item' => 'Basketball', 'quantity' => 4 }, + { 'item' => 'Big Shoes', 'quantity' => 1 } + ] +python: | + [ + { 'item': 'Super Hoop', 'quantity': 1 }, + { 'item': 'Basketball', 'quantity': 4 }, + { 'item': 'Big Shoes', 'quantity': 1 } + ] +syck: | + struct test_node map1[] = { + { T_STR, 0, "item" }, + { T_STR, 0, "Super Hoop" }, + { T_STR, 0, "quantity" }, + { T_STR, 0, "1" }, + end_node + }; + struct test_node map2[] = { + { T_STR, 0, "item" }, + { T_STR, 0, "Basketball" }, + { T_STR, 0, "quantity" }, + { T_STR, 0, "4" }, + end_node + }; + struct test_node map3[] = { + { T_STR, 0, "item" }, + { T_STR, 0, "Big Shoes" }, + { T_STR, 0, "quantity" }, + { T_STR, 0, "1" }, + end_node + }; + struct test_node seq[] = { + { T_MAP, 0, 0, map1 }, + { T_MAP, 0, 0, map2 }, + { T_MAP, 0, 0, map3 }, + end_node + }; + struct test_node stream[] = { + { T_SEQ, 0, 0, seq }, + end_node + }; + + +--- +test: Literal perserves newlines +todo: true +spec: 2.13 +yaml: | + # ASCII Art + --- | + \//||\/|| + // || ||_ +perl: | + "\\//||\\/||\n// || ||_\n" +ruby: | + "\\//||\\/||\n// || ||_\n" +python: | + [ + flushLeft( + """ + \//||\/|| + // || ||_ + """ + ) + ] +syck: | + struct test_node stream[] = { + { T_STR, 0, "\\//||\\/||\n// || ||_\n" }, + end_node + }; + +--- +test: Folded treats newlines as a space +todo: true +spec: 2.14 +yaml: | + --- + Mark McGwire's + year was crippled + by a knee injury. +perl: | + "Mark McGwire's year was crippled by a knee injury." +ruby: | + "Mark McGwire's year was crippled by a knee injury." +python: | + [ "Mark McGwire's year was crippled by a knee injury." ] +syck: | + struct test_node stream[] = { + { T_STR, 0, "Mark McGwire's year was crippled by a knee injury." }, + end_node + }; + +--- +test: Newlines preserved for indented and blank lines +todo: true +spec: 2.15 +yaml: | + --- > + Sammy Sosa completed another + fine season with great stats. + + 63 Home Runs + 0.288 Batting Average + + What a year! +perl: | + "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" +ruby: | + "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" +python: | + [ + flushLeft( + """ + Sammy Sosa completed another fine season with great stats. + + 63 Home Runs + 0.288 Batting Average + + What a year! + """ + ) + ] +syck: | + struct test_node stream[] = { + { T_STR, 0, "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" }, + end_node + }; + + +--- +test: Indentation determines scope +spec: 2.16 +yaml: | + name: Mark McGwire + accomplishment: > + Mark set a major league + home run record in 1998. + stats: | + 65 Home Runs + 0.278 Batting Average +php: | + array( + 'name' => 'Mark McGwire', + 'accomplishment' => "Mark set a major league home run record in 1998.\n", + 'stats' => "65 Home Runs\n0.278 Batting Average\n" + ) +--- +test: Quoted scalars +todo: true +spec: 2.17 +yaml: | + unicode: "Sosa did fine.\u263A" + control: "\b1998\t1999\t2000\n" + hexesc: "\x0D\x0A is \r\n" + + single: '"Howdy!" he cried.' + quoted: ' # not a ''comment''.' + tie-fighter: '|\-*-/|' +ruby: | + { + "tie-fighter" => "|\\-*-/|", + "control"=>"\0101998\t1999\t2000\n", + "unicode"=>"Sosa did fine." + ["263A".hex ].pack('U*'), + "quoted"=>" # not a 'comment'.", + "single"=>"\"Howdy!\" he cried.", + "hexesc"=>"\r\n is \r\n" + } +--- +test: Multiline flow scalars +todo: true +spec: 2.18 +yaml: | + plain: + This unquoted scalar + spans many lines. + + quoted: "So does this + quoted scalar.\n" +ruby: | + { + 'plain' => 'This unquoted scalar spans many lines.', + 'quoted' => "So does this quoted scalar.\n" + } +--- +test: Integers +spec: 2.19 +yaml: | + canonical: 12345 + decimal: +12,345 + octal: 014 + hexadecimal: 0xC +php: | + array( + 'canonical' => 12345, + 'decimal' => 12345.0, + 'octal' => 014, + 'hexadecimal' => 0xC + ) +--- +# FIX: spec shows parens around -inf and NaN +test: Floating point +spec: 2.20 +yaml: | + canonical: 1.23015e+3 + exponential: 12.3015e+02 + fixed: 1,230.15 + negative infinity: -.inf + not a number: .NaN + float as whole number: !!float 1 +php: | + array( + 'canonical' => 1230.15, + 'exponential' => 1230.15, + 'fixed' => 1230.15, + 'negative infinity' => log(0), + 'not a number' => -log(0), + 'float as whole number' => (float) 1 + ) +--- +test: Miscellaneous +spec: 2.21 +yaml: | + null: ~ + true: true + false: false + string: '12345' +php: | + array( + '' => null, + 1 => true, + 0 => false, + 'string' => '12345' + ) +--- +test: Timestamps +todo: true +spec: 2.22 +yaml: | + canonical: 2001-12-15T02:59:43.1Z + iso8601: 2001-12-14t21:59:43.10-05:00 + spaced: 2001-12-14 21:59:43.10 -05:00 + date: 2002-12-14 # Time is noon UTC +php: | + array( + 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ), + 'iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'date' => Date.new( 2002, 12, 14 ) + ) +--- +test: legacy Timestamps test +todo: true +spec: legacy D4 +yaml: | + canonical: 2001-12-15T02:59:43.00Z + iso8601: 2001-02-28t21:59:43.00-05:00 + spaced: 2001-12-14 21:59:43.00 -05:00 + date: 2002-12-14 +php: | + array( + 'canonical' => Time::utc( 2001, 12, 15, 2, 59, 43, 0 ), + 'iso8601' => YAML::mktime( 2001, 2, 28, 21, 59, 43, 0, "-05:00" ), + 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0, "-05:00" ), + 'date' => Date.new( 2002, 12, 14 ) + ) +--- +test: Various explicit families +todo: true +spec: 2.23 +yaml: | + not-date: !str 2002-04-28 + picture: !binary | + R0lGODlhDAAMAIQAAP//9/X + 17unp5WZmZgAAAOfn515eXv + Pz7Y6OjuDg4J+fn5OTk6enp + 56enmleECcgggoBADs= + + application specific tag: !!something | + The semantics of the tag + above may be different for + different documents. + +ruby-setup: | + YAML.add_private_type( "something" ) do |type, val| + "SOMETHING: #{val}" + end +ruby: | + { + 'not-date' => '2002-04-28', + 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;", + 'application specific tag' => "SOMETHING: The semantics of the tag\nabove may be different for\ndifferent documents.\n" + } +--- +test: Application specific family +todo: true +spec: 2.24 +yaml: | + # Establish a tag prefix + --- !clarkevans.com,2002/graph/^shape + # Use the prefix: shorthand for + # !clarkevans.com,2002/graph/circle + - !^circle + center: &ORIGIN {x: 73, 'y': 129} + radius: 7 + - !^line # !clarkevans.com,2002/graph/line + start: *ORIGIN + finish: { x: 89, 'y': 102 } + - !^label + start: *ORIGIN + color: 0xFFEEBB + value: Pretty vector drawing. +ruby-setup: | + YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val| + if Array === val + val << "Shape Container" + val + else + raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect + end + } + one_shape_proc = Proc.new { |type, val| + scheme, domain, type = type.split( /:/, 3 ) + if val.is_a? ::Hash + val['TYPE'] = "Shape: #{type}" + val + else + raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect + end + } + YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc ) + YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc ) + YAML.add_domain_type( "clarkevans.com,2002", 'graph/label', &one_shape_proc ) +ruby: | + [ + { + "radius" => 7, + "center"=> + { + "x" => 73, + "y" => 129 + }, + "TYPE" => "Shape: graph/circle" + }, { + "finish" => + { + "x" => 89, + "y" => 102 + }, + "TYPE" => "Shape: graph/line", + "start" => + { + "x" => 73, + "y" => 129 + } + }, { + "TYPE" => "Shape: graph/label", + "value" => "Pretty vector drawing.", + "start" => + { + "x" => 73, + "y" => 129 + }, + "color" => 16772795 + }, + "Shape Container" + ] +# --- +# test: Unordered set +# spec: 2.25 +# yaml: | +# # sets are represented as a +# # mapping where each key is +# # associated with the empty string +# --- !set +# ? Mark McGwire +# ? Sammy Sosa +# ? Ken Griff +--- +test: Ordered mappings +todo: true +spec: 2.26 +yaml: | + # ordered maps are represented as + # a sequence of mappings, with + # each mapping having one key + --- !omap + - Mark McGwire: 65 + - Sammy Sosa: 63 + - Ken Griffy: 58 +ruby: | + YAML::Omap[ + 'Mark McGwire', 65, + 'Sammy Sosa', 63, + 'Ken Griffy', 58 + ] +--- +test: Invoice +dump_skip: true +spec: 2.27 +yaml: | + --- !clarkevans.com,2002/^invoice + invoice: 34843 + date : 2001-01-23 + bill-to: &id001 + given : Chris + family : Dumars + address: + lines: | + 458 Walkman Dr. + Suite #292 + city : Royal Oak + state : MI + postal : 48046 + ship-to: *id001 + product: + - + sku : BL394D + quantity : 4 + description : Basketball + price : 450.00 + - + sku : BL4438H + quantity : 1 + description : Super Hoop + price : 2392.00 + tax : 251.42 + total: 4443.52 + comments: > + Late afternoon is best. + Backup contact is Nancy + Billsmer @ 338-4338. +php: | + array( + 'invoice' => 34843, 'date' => gmmktime(0, 0, 0, 1, 23, 2001), + 'bill-to' => + array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) ) + , 'ship-to' => + array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) ) + , 'product' => + array( + array( 'sku' => 'BL394D', 'quantity' => 4, 'description' => 'Basketball', 'price' => 450.00 ), + array( 'sku' => 'BL4438H', 'quantity' => 1, 'description' => 'Super Hoop', 'price' => 2392.00 ) + ), + 'tax' => 251.42, 'total' => 4443.52, + 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n" + ) +--- +test: Log file +todo: true +spec: 2.28 +yaml: | + --- + Time: 2001-11-23 15:01:42 -05:00 + User: ed + Warning: > + This is an error message + for the log file + --- + Time: 2001-11-23 15:02:31 -05:00 + User: ed + Warning: > + A slightly different error + message. + --- + Date: 2001-11-23 15:03:17 -05:00 + User: ed + Fatal: > + Unknown variable "bar" + Stack: + - file: TopClass.py + line: 23 + code: | + x = MoreObject("345\n") + - file: MoreClass.py + line: 58 + code: |- + foo = bar +ruby: | + y = YAML::Stream.new + y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ), + 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } ) + y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ), + 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } ) + y.add( { 'Date' => YAML::mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ), + 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n", + 'Stack' => [ + { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" }, + { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } ) +documents: 3 + +--- +test: Throwaway comments +yaml: | + ### These are four throwaway comment ### + + ### lines (the second line is empty). ### + this: | # Comments may trail lines. + contains three lines of text. + The third one starts with a + # character. This isn't a comment. + + # These are three throwaway comment + # lines (the first line is empty). +php: | + array( + 'this' => "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n" + ) +--- +test: Document with a single value +todo: true +yaml: | + --- > + This YAML stream contains a single text value. + The next stream is a log file - a sequence of + log entries. Adding an entry to the log is a + simple matter of appending it at the end. +ruby: | + "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n" +--- +test: Document stream +todo: true +yaml: | + --- + at: 2001-08-12 09:25:00.00 Z + type: GET + HTTP: '1.0' + url: '/index.html' + --- + at: 2001-08-12 09:25:10.00 Z + type: GET + HTTP: '1.0' + url: '/toc.html' +ruby: | + y = YAML::Stream.new + y.add( { + 'at' => Time::utc( 2001, 8, 12, 9, 25, 00 ), + 'type' => 'GET', + 'HTTP' => '1.0', + 'url' => '/index.html' + } ) + y.add( { + 'at' => Time::utc( 2001, 8, 12, 9, 25, 10 ), + 'type' => 'GET', + 'HTTP' => '1.0', + 'url' => '/toc.html' + } ) +documents: 2 + +--- +test: Top level mapping +yaml: | + # This stream is an example of a top-level mapping. + invoice : 34843 + date : 2001-01-23 + total : 4443.52 +php: | + array( + 'invoice' => 34843, + 'date' => gmmktime(0, 0, 0, 1, 23, 2001), + 'total' => 4443.52 + ) +--- +test: Single-line documents +todo: true +yaml: | + # The following is a sequence of three documents. + # The first contains an empty mapping, the second + # an empty sequence, and the last an empty string. + --- {} + --- [ ] + --- '' +ruby: | + y = YAML::Stream.new + y.add( {} ) + y.add( [] ) + y.add( '' ) +documents: 3 + +--- +test: Document with pause +todo: true +yaml: | + # A communication channel based on a YAML stream. + --- + sent at: 2002-06-06 11:46:25.10 Z + payload: Whatever + # Receiver can process this as soon as the following is sent: + ... + # Even if the next message is sent long after: + --- + sent at: 2002-06-06 12:05:53.47 Z + payload: Whatever + ... +ruby: | + y = YAML::Stream.new + y.add( + { 'sent at' => YAML::mktime( 2002, 6, 6, 11, 46, 25, 0.10 ), + 'payload' => 'Whatever' } + ) + y.add( + { "payload" => "Whatever", "sent at" => YAML::mktime( 2002, 6, 6, 12, 5, 53, 0.47 ) } + ) +documents: 2 + +--- +test: Explicit typing +yaml: | + integer: 12 + also int: ! "12" + string: !str 12 +php: | + array( 'integer' => 12, 'also int' => 12, 'string' => '12' ) +--- +test: Private types +todo: true +yaml: | + # Both examples below make use of the 'x-private:ball' + # type family URI, but with different semantics. + --- + pool: !!ball + number: 8 + color: black + --- + bearing: !!ball + material: steel +ruby: | + y = YAML::Stream.new + y.add( { 'pool' => + YAML::PrivateType.new( 'ball', + { 'number' => 8, 'color' => 'black' } ) } + ) + y.add( { 'bearing' => + YAML::PrivateType.new( 'ball', + { 'material' => 'steel' } ) } + ) +documents: 2 + +--- +test: Type family under yaml.org +yaml: | + # The URI is 'tag:yaml.org,2002:str' + - !str a Unicode string +php: | + array( 'a Unicode string' ) +--- +test: Type family under perl.yaml.org +todo: true +yaml: | + # The URI is 'tag:perl.yaml.org,2002:Text::Tabs' + - !perl/Text::Tabs {} +ruby: | + [ YAML::DomainType.new( 'perl.yaml.org,2002', 'Text::Tabs', {} ) ] +--- +test: Type family under clarkevans.com +todo: true +yaml: | + # The URI is 'tag:clarkevans.com,2003-02:timesheet' + - !clarkevans.com,2003-02/timesheet {} +ruby: | + [ YAML::DomainType.new( 'clarkevans.com,2003-02', 'timesheet', {} ) ] +--- +test: URI Escaping +todo: true +yaml: | + same: + - !domain.tld,2002/type\x30 value + - !domain.tld,2002/type0 value + different: # As far as the YAML parser is concerned + - !domain.tld,2002/type%30 value + - !domain.tld,2002/type0 value +ruby-setup: | + YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val| + "ONE: #{val}" + } + YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val| + "TWO: #{val}" + } +ruby: | + { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value', 'ONE: value' ] } +--- +test: URI Prefixing +todo: true +yaml: | + # 'tag:domain.tld,2002:invoice' is some type family. + invoice: !domain.tld,2002/^invoice + # 'seq' is shorthand for 'tag:yaml.org,2002:seq'. + # This does not effect '^customer' below + # because it is does not specify a prefix. + customers: !seq + # '^customer' is shorthand for the full + # notation 'tag:domain.tld,2002:customer'. + - !^customer + given : Chris + family : Dumars +ruby-setup: | + YAML.add_domain_type( "domain.tld,2002", /(invoice|customer)/ ) { |type, val| + if val.is_a? ::Hash + scheme, domain, type = type.split( /:/, 3 ) + val['type'] = "domain #{type}" + val + else + raise YAML::Error, "Not a Hash in domain.tld/invoice: " + val.inspect + end + } +ruby: | + { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } } + +--- +test: Overriding anchors +yaml: | + anchor : &A001 This scalar has an anchor. + override : &A001 > + The alias node below is a + repeated use of this value. + alias : *A001 +php: | + array( 'anchor' => 'This scalar has an anchor.', + 'override' => "The alias node below is a repeated use of this value.\n", + 'alias' => "The alias node below is a repeated use of this value.\n" ) +--- +test: Flow and block formatting +todo: true +yaml: | + empty: [] + flow: [ one, two, three # May span lines, + , four, # indentation is + five ] # mostly ignored. + block: + - First item in top sequence + - + - Subordinate sequence entry + - > + A folded sequence entry + - Sixth item in top sequence +ruby: | + { 'empty' => [], 'flow' => [ 'one', 'two', 'three', 'four', 'five' ], + 'block' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ], + "A folded sequence entry\n", 'Sixth item in top sequence' ] } +--- +test: Complete mapping test +todo: true +yaml: | + empty: {} + flow: { one: 1, two: 2 } + spanning: { one: 1, + two: 2 } + block: + first : First entry + second: + key: Subordinate mapping + third: + - Subordinate sequence + - { } + - Previous mapping is empty. + - A key: value pair in a sequence. + A second: key:value pair. + - The previous entry is equal to the following one. + - + A key: value pair in a sequence. + A second: key:value pair. + !float 12 : This key is a float. + ? > + ? + : This key had to be protected. + "\a" : This key had to be escaped. + ? > + This is a + multi-line + folded key + : Whose value is + also multi-line. + ? this also works as a key + : with a value at the next line. + ? + - This key + - is a sequence + : + - With a sequence value. + ? + This: key + is a: mapping + : + with a: mapping value. +ruby: | + { 'empty' => {}, 'flow' => { 'one' => 1, 'two' => 2 }, + 'spanning' => { 'one' => 1, 'two' => 2 }, + 'block' => { 'first' => 'First entry', 'second' => + { 'key' => 'Subordinate mapping' }, 'third' => + [ 'Subordinate sequence', {}, 'Previous mapping is empty.', + { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' }, + 'The previous entry is equal to the following one.', + { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ], + 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.', + "\a" => 'This key had to be escaped.', + "This is a multi-line folded key\n" => "Whose value is also multi-line.", + 'this also works as a key' => 'with a value at the next line.', + [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } } + # Couldn't recreate map exactly, so we'll do a detailed check to be sure it's entact + obj_y['block'].keys.each { |k| + if Hash === k + v = obj_y['block'][k] + if k['This'] == 'key' and k['is a'] == 'mapping' and v['with a'] == 'mapping value.' + obj_r['block'][k] = v + end + end + } +--- +test: Literal explicit indentation +yaml: | + # Explicit indentation must + # be given in all the three + # following cases. + leading spaces: |2 + This value starts with four spaces. + + leading line break: |2 + + This value starts with a line break. + + leading comment indicator: |2 + # first line starts with a + # character. + + # Explicit indentation may + # also be given when it is + # not required. + redundant: |2 + This value is indented 2 spaces. +php: | + array( + 'leading spaces' => " This value starts with four spaces.\n", + 'leading line break' => "\nThis value starts with a line break.\n", + 'leading comment indicator' => "# first line starts with a\n# character.\n", + 'redundant' => "This value is indented 2 spaces.\n" + ) +--- +test: Chomping and keep modifiers +yaml: | + clipped: | + This has one newline. + + same as "clipped" above: "This has one newline.\n" + + stripped: |- + This has no newline. + + same as "stripped" above: "This has no newline." + + kept: |+ + This has two newlines. + + same as "kept" above: "This has two newlines.\n\n" +php: | + array( + 'clipped' => "This has one newline.\n", + 'same as "clipped" above' => "This has one newline.\n", + 'stripped' => 'This has no newline.', + 'same as "stripped" above' => 'This has no newline.', + 'kept' => "This has two newlines.\n\n", + 'same as "kept" above' => "This has two newlines.\n\n" + ) +--- +test: Literal combinations +todo: true +yaml: | + empty: | + + literal: | + The \ ' " characters may be + freely used. Leading white + space is significant. + + Line breaks are significant. + Thus this value contains one + empty line and ends with a + single line break, but does + not start with one. + + is equal to: "The \\ ' \" characters may \ + be\nfreely used. Leading white\n space \ + is significant.\n\nLine breaks are \ + significant.\nThus this value contains \ + one\nempty line and ends with a\nsingle \ + line break, but does\nnot start with one.\n" + + # Comments may follow a block + # scalar value. They must be + # less indented. + + # Modifiers may be combined in any order. + indented and chomped: |2- + This has no newline. + + also written as: |-2 + This has no newline. + + both are equal to: " This has no newline." +php: | + array( + 'empty' => '', + 'literal' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " + + "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" + + "empty line and ends with a\nsingle line break, but does\nnot start with one.\n", + 'is equal to' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " + + "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" + + "empty line and ends with a\nsingle line break, but does\nnot start with one.\n", + 'indented and chomped' => ' This has no newline.', + 'also written as' => ' This has no newline.', + 'both are equal to' => ' This has no newline.' + ) +--- +test: Folded combinations +todo: true +yaml: | + empty: > + + one paragraph: > + Line feeds are converted + to spaces, so this value + contains no line breaks + except for the final one. + + multiple paragraphs: >2 + + An empty line, either + at the start or in + the value: + + Is interpreted as a + line break. Thus this + value contains three + line breaks. + + indented text: > + This is a folded + paragraph followed + by a list: + * first entry + * second entry + Followed by another + folded paragraph, + another list: + + * first entry + + * second entry + + And a final folded + paragraph. + + above is equal to: | + This is a folded paragraph followed by a list: + * first entry + * second entry + Followed by another folded paragraph, another list: + + * first entry + + * second entry + + And a final folded paragraph. + + # Explicit comments may follow + # but must be less indented. +php: | + array( + 'empty' => '', + 'one paragraph' => 'Line feeds are converted to spaces, so this value'. + " contains no line breaks except for the final one.\n", + 'multiple paragraphs' => "\nAn empty line, either at the start or in the value:\n". + "Is interpreted as a line break. Thus this value contains three line breaks.\n", + 'indented text' => "This is a folded paragraph followed by a list:\n". + " * first entry\n * second entry\nFollowed by another folded paragraph, ". + "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n", + 'above is equal to' => "This is a folded paragraph followed by a list:\n". + " * first entry\n * second entry\nFollowed by another folded paragraph, ". + "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n" + ) +--- +test: Single quotes +todo: true +yaml: | + empty: '' + second: '! : \ etc. can be used freely.' + third: 'a single quote '' must be escaped.' + span: 'this contains + six spaces + + and one + line break' + is same as: "this contains six spaces\nand one line break" +php: | + array( + 'empty' => '', + 'second' => '! : \\ etc. can be used freely.', + 'third' => "a single quote ' must be escaped.", + 'span' => "this contains six spaces\nand one line break", + 'is same as' => "this contains six spaces\nand one line break" + ) +--- +test: Double quotes +todo: true +yaml: | + empty: "" + second: "! : etc. can be used freely." + third: "a \" or a \\ must be escaped." + fourth: "this value ends with an LF.\n" + span: "this contains + four \ + spaces" + is equal to: "this contains four spaces" +php: | + array( + 'empty' => '', + 'second' => '! : etc. can be used freely.', + 'third' => 'a " or a \\ must be escaped.', + 'fourth' => "this value ends with an LF.\n", + 'span' => "this contains four spaces", + 'is equal to' => "this contains four spaces" + ) +--- +test: Unquoted strings +todo: true +yaml: | + first: There is no unquoted empty string. + + second: 12 ## This is an integer. + + third: !str 12 ## This is a string. + + span: this contains + six spaces + + and one + line break + + indicators: this has no comments. + #:foo and bar# are + both text. + + flow: [ can span + lines, # comment + like + this ] + + note: { one-line keys: but multi-line values } + +php: | + array( + 'first' => 'There is no unquoted empty string.', + 'second' => 12, + 'third' => '12', + 'span' => "this contains six spaces\nand one line break", + 'indicators' => "this has no comments. #:foo and bar# are both text.", + 'flow' => [ 'can span lines', 'like this' ], + 'note' => { 'one-line keys' => 'but multi-line values' } + ) +--- +test: Spanning sequences +todo: true +yaml: | + # The following are equal seqs + # with different identities. + flow: [ one, two ] + spanning: [ one, + two ] + block: + - one + - two +php: | + array( + 'flow' => [ 'one', 'two' ], + 'spanning' => [ 'one', 'two' ], + 'block' => [ 'one', 'two' ] + ) +--- +test: Flow mappings +yaml: | + # The following are equal maps + # with different identities. + flow: { one: 1, two: 2 } + block: + one: 1 + two: 2 +php: | + array( + 'flow' => array( 'one' => 1, 'two' => 2 ), + 'block' => array( 'one' => 1, 'two' => 2 ) + ) +--- +test: Representations of 12 +todo: true +yaml: | + - 12 # An integer + # The following scalars + # are loaded to the + # string value '1' '2'. + - !str 12 + - '12' + - "12" + - "\ + 1\ + 2\ + " + # Strings containing paths and regexps can be unquoted: + - /foo/bar + - d:/foo/bar + - foo/bar + - /a.*b/ +php: | + array( 12, '12', '12', '12', '12', '/foo/bar', 'd:/foo/bar', 'foo/bar', '/a.*b/' ) +--- +test: "Null" +todo: true +yaml: | + canonical: ~ + + english: null + + # This sequence has five + # entries, two with values. + sparse: + - ~ + - 2nd entry + - Null + - 4th entry + - + + four: This mapping has five keys, + only two with values. + +php: | + array ( + 'canonical' => null, + 'english' => null, + 'sparse' => array( null, '2nd entry', null, '4th entry', null ]), + 'four' => 'This mapping has five keys, only two with values.' + ) +--- +test: Omap +todo: true +yaml: | + # Explicitly typed dictionary. + Bestiary: !omap + - aardvark: African pig-like ant eater. Ugly. + - anteater: South-American ant eater. Two species. + - anaconda: South-American constrictor snake. Scary. + # Etc. +ruby: | + { + 'Bestiary' => YAML::Omap[ + 'aardvark', 'African pig-like ant eater. Ugly.', + 'anteater', 'South-American ant eater. Two species.', + 'anaconda', 'South-American constrictor snake. Scary.' + ] + } + +--- +test: Pairs +todo: true +yaml: | + # Explicitly typed pairs. + tasks: !pairs + - meeting: with team. + - meeting: with boss. + - break: lunch. + - meeting: with client. +ruby: | + { + 'tasks' => YAML::Pairs[ + 'meeting', 'with team.', + 'meeting', 'with boss.', + 'break', 'lunch.', + 'meeting', 'with client.' + ] + } + +--- +test: Set +todo: true +yaml: | + # Explicitly typed set. + baseball players: !set + Mark McGwire: + Sammy Sosa: + Ken Griffey: +ruby: | + { + 'baseball players' => YAML::Set[ + 'Mark McGwire', nil, + 'Sammy Sosa', nil, + 'Ken Griffey', nil + ] + } + +--- +test: Boolean +yaml: | + false: used as key + logical: true + answer: false +php: | + array( + false => 'used as key', + 'logical' => true, + 'answer' => false + ) +--- +test: Integer +yaml: | + canonical: 12345 + decimal: +12,345 + octal: 014 + hexadecimal: 0xC +php: | + array( + 'canonical' => 12345, + 'decimal' => 12345.0, + 'octal' => 12, + 'hexadecimal' => 12 + ) +--- +test: Float +yaml: | + canonical: 1.23015e+3 + exponential: 12.3015e+02 + fixed: 1,230.15 + negative infinity: -.inf + not a number: .NaN +php: | + array( + 'canonical' => 1230.15, + 'exponential' => 1230.15, + 'fixed' => 1230.15, + 'negative infinity' => log(0), + 'not a number' => -log(0) + ) +--- +test: Timestamp +todo: true +yaml: | + canonical: 2001-12-15T02:59:43.1Z + valid iso8601: 2001-12-14t21:59:43.10-05:00 + space separated: 2001-12-14 21:59:43.10 -05:00 + date (noon UTC): 2002-12-14 +ruby: | + array( + 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ), + 'valid iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'space separated' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'date (noon UTC)' => Date.new( 2002, 12, 14 ) + ) +--- +test: Binary +todo: true +yaml: | + canonical: !binary "\ + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" + base64: !binary | + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= + description: > + The binary value above is a tiny arrow + encoded as a gif image. +ruby-setup: | + arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;" +ruby: | + { + 'canonical' => arrow_gif, + 'base64' => arrow_gif, + 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n" + } + +--- +test: Merge key +todo: true +yaml: | + --- + - &CENTER { x: 1, y: 2 } + - &LEFT { x: 0, y: 2 } + - &BIG { r: 10 } + - &SMALL { r: 1 } + + # All the following maps are equal: + + - # Explicit keys + x: 1 + y: 2 + r: 10 + label: center/big + + - # Merge one map + << : *CENTER + r: 10 + label: center/big + + - # Merge multiple maps + << : [ *CENTER, *BIG ] + label: center/big + + - # Override + << : [ *BIG, *LEFT, *SMALL ] + x: 1 + label: center/big + +ruby-setup: | + center = { 'x' => 1, 'y' => 2 } + left = { 'x' => 0, 'y' => 2 } + big = { 'r' => 10 } + small = { 'r' => 1 } + node1 = { 'x' => 1, 'y' => 2, 'r' => 10, 'label' => 'center/big' } + node2 = center.dup + node2.update( { 'r' => 10, 'label' => 'center/big' } ) + node3 = big.dup + node3.update( center ) + node3.update( { 'label' => 'center/big' } ) + node4 = small.dup + node4.update( left ) + node4.update( big ) + node4.update( { 'x' => 1, 'label' => 'center/big' } ) + +ruby: | + [ + center, left, big, small, node1, node2, node3, node4 + ] + +--- +test: Default key +todo: true +yaml: | + --- # Old schema + link with: + - library1.dll + - library2.dll + --- # New schema + link with: + - = : library1.dll + version: 1.2 + - = : library2.dll + version: 2.3 +ruby: | + y = YAML::Stream.new + y.add( { 'link with' => [ 'library1.dll', 'library2.dll' ] } ) + obj_h = Hash[ 'version' => 1.2 ] + obj_h.default = 'library1.dll' + obj_h2 = Hash[ 'version' => 2.3 ] + obj_h2.default = 'library2.dll' + y.add( { 'link with' => [ obj_h, obj_h2 ] } ) +documents: 2 + +--- +test: Special keys +todo: true +yaml: | + "!": These three keys + "&": had to be quoted + "=": and are normal strings. + # NOTE: the following node should NOT be serialized this way. + encoded node : + !special '!' : '!type' + !special|canonical '&' : 12 + = : value + # The proper way to serialize the above node is as follows: + node : !!type &12 value +ruby: | + { '!' => 'These three keys', '&' => 'had to be quoted', + '=' => 'and are normal strings.', + 'encoded node' => YAML::PrivateType.new( 'type', 'value' ), + 'node' => YAML::PrivateType.new( 'type', 'value' ) } diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml new file mode 100644 index 000000000..46c8d4a2c --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml @@ -0,0 +1,244 @@ +--- %YAML:1.0 +test: Strings +brief: > + Any group of characters beginning with an + alphabetic or numeric character is a string, + unless it belongs to one of the groups below + (such as an Integer or Time). +yaml: | + String +php: | + 'String' +--- +test: String characters +brief: > + A string can contain any alphabetic or + numeric character, along with many + punctuation characters, including the + period, dash, space, quotes, exclamation, and + question mark. +yaml: | + - What's Yaml? + - It's for writing data structures in plain text. + - And? + - And what? That's not good enough for you? + - No, I mean, "And what about Yaml?" + - Oh, oh yeah. Uh.. Yaml for Ruby. +php: | + array( + "What's Yaml?", + "It's for writing data structures in plain text.", + "And?", + "And what? That's not good enough for you?", + "No, I mean, \"And what about Yaml?\"", + "Oh, oh yeah. Uh.. Yaml for Ruby." + ) +--- +test: Indicators in Strings +brief: > + Be careful using indicators in strings. In particular, + the comma, colon, and pound sign must be used carefully. +yaml: | + the colon followed by space is an indicator: but is a string:right here + same for the pound sign: here we have it#in a string + the comma can, honestly, be used in most cases: [ but not in, inline collections ] +php: | + array( + 'the colon followed by space is an indicator' => 'but is a string:right here', + 'same for the pound sign' => 'here we have it#in a string', + 'the comma can, honestly, be used in most cases' => array('but not in', 'inline collections') + ) +--- +test: Forcing Strings +brief: > + Any YAML type can be forced into a string using the + explicit !str method. +yaml: | + date string: !str 2001-08-01 + number string: !str 192 +php: | + array( + 'date string' => '2001-08-01', + 'number string' => '192' + ) +--- +test: Single-quoted Strings +brief: > + You can also enclose your strings within single quotes, + which allows use of slashes, colons, and other indicators + freely. Inside single quotes, you can represent a single + quote in your string by using two single quotes next to + each other. +yaml: | + all my favorite symbols: '#:!/%.)' + a few i hate: '&(*' + why do i hate them?: 'it''s very hard to explain' + entities: '£ me' +php: | + array( + 'all my favorite symbols' => '#:!/%.)', + 'a few i hate' => '&(*', + 'why do i hate them?' => 'it\'s very hard to explain', + 'entities' => '£ me' + ) +--- +test: Double-quoted Strings +brief: > + Enclosing strings in double quotes allows you + to use escapings to represent ASCII and + Unicode characters. +yaml: | + i know where i want my line breaks: "one here\nand another here\n" +php: | + array( + 'i know where i want my line breaks' => "one here\nand another here\n" + ) +--- +test: Multi-line Quoted Strings +todo: true +brief: > + Both single- and double-quoted strings may be + carried on to new lines in your YAML document. + They must be indented a step and indentation + is interpreted as a single space. +yaml: | + i want a long string: "so i'm going to + let it go on and on to other lines + until i end it with a quote." +php: | + array('i want a long string' => "so i'm going to ". + "let it go on and on to other lines ". + "until i end it with a quote." + ) + +--- +test: Plain scalars +todo: true +brief: > + Unquoted strings may also span multiple lines, if they + are free of YAML space indicators and indented. +yaml: | + - My little toe is broken in two places; + - I'm crazy to have skied this way; + - I'm not the craziest he's seen, since there was always the German guy + who skied for 3 hours on a broken shin bone (just below the kneecap); + - Nevertheless, second place is respectable, and he doesn't + recommend going for the record; + - He's going to put my foot in plaster for a month; + - This would impair my skiing ability somewhat for the + duration, as can be imagined. +php: | + array( + "My little toe is broken in two places;", + "I'm crazy to have skied this way;", + "I'm not the craziest he's seen, since there was always ". + "the German guy who skied for 3 hours on a broken shin ". + "bone (just below the kneecap);", + "Nevertheless, second place is respectable, and he doesn't ". + "recommend going for the record;", + "He's going to put my foot in plaster for a month;", + "This would impair my skiing ability somewhat for the duration, ". + "as can be imagined." + ) +--- +test: 'Null' +brief: > + You can use the tilde '~' character for a null value. +yaml: | + name: Mr. Show + hosted by: Bob and David + date of next season: ~ +php: | + array( + 'name' => 'Mr. Show', + 'hosted by' => 'Bob and David', + 'date of next season' => null + ) +--- +test: Boolean +brief: > + You can use 'true' and 'false' for Boolean values. +yaml: | + Is Gus a Liar?: true + Do I rely on Gus for Sustenance?: false +php: | + array( + 'Is Gus a Liar?' => true, + 'Do I rely on Gus for Sustenance?' => false + ) +--- +test: Integers +dump_skip: true +brief: > + An integer is a series of numbers, optionally + starting with a positive or negative sign. Integers + may also contain commas for readability. +yaml: | + zero: 0 + simple: 12 + one-thousand: 1,000 + negative one-thousand: -1,000 +php: | + array( + 'zero' => 0, + 'simple' => 12, + 'one-thousand' => 1000.0, + 'negative one-thousand' => -1000.0 + ) +--- +test: Integers as Map Keys +brief: > + An integer can be used a dictionary key. +yaml: | + 1: one + 2: two + 3: three +php: | + array( + 1 => 'one', + 2 => 'two', + 3 => 'three' + ) +--- +test: Floats +dump_skip: true +brief: > + Floats are represented by numbers with decimals, + allowing for scientific notation, as well as + positive and negative infinity and "not a number." +yaml: | + a simple float: 2.00 + larger float: 1,000.09 + scientific notation: 1.00009e+3 +php: | + array( + 'a simple float' => 2.0, + 'larger float' => 1000.09, + 'scientific notation' => 1000.09 + ) +--- +test: Time +todo: true +brief: > + You can represent timestamps by using + ISO8601 format, or a variation which + allows spaces between the date, time and + time zone. +yaml: | + iso8601: 2001-12-14t21:59:43.10-05:00 + space separated: 2001-12-14 21:59:43.10 -05:00 +php: | + array( + 'iso8601' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'space separated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ) + ) +--- +test: Date +todo: true +brief: > + A date can be represented by its year, + month and day in ISO8601 order. +yaml: | + 1976-07-31 +php: | + date( 1976, 7, 31 ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml b/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml new file mode 100644 index 000000000..ec456ed09 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml @@ -0,0 +1 @@ +value: diff --git a/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml b/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml new file mode 100644 index 000000000..6ca044c8d --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml @@ -0,0 +1,155 @@ +test: outside double quotes +yaml: | + \0 \ \a \b \n +php: | + "\\0 \\ \\a \\b \\n" +--- +test: null +yaml: | + "\0" +php: | + "\x00" +--- +test: bell +yaml: | + "\a" +php: | + "\x07" +--- +test: backspace +yaml: | + "\b" +php: | + "\x08" +--- +test: horizontal tab (1) +yaml: | + "\t" +php: | + "\x09" +--- +test: horizontal tab (2) +yaml: | + "\ " +php: | + "\x09" +--- +test: line feed +yaml: | + "\n" +php: | + "\x0a" +--- +test: vertical tab +yaml: | + "\v" +php: | + "\x0b" +--- +test: form feed +yaml: | + "\f" +php: | + "\x0c" +--- +test: carriage return +yaml: | + "\r" +php: | + "\x0d" +--- +test: escape +yaml: | + "\e" +php: | + "\x1b" +--- +test: space +yaml: | + "\ " +php: | + "\x20" +--- +test: slash +yaml: | + "\/" +php: | + "\x2f" +--- +test: backslash +yaml: | + "\\" +php: | + "\\" +--- +test: Unicode next line +yaml: | + "\N" +php: | + "\xc2\x85" +--- +test: Unicode non-breaking space +yaml: | + "\_" +php: | + "\xc2\xa0" +--- +test: Unicode line separator +yaml: | + "\L" +php: | + "\xe2\x80\xa8" +--- +test: Unicode paragraph separator +yaml: | + "\P" +php: | + "\xe2\x80\xa9" +--- +test: Escaped 8-bit Unicode +yaml: | + "\x42" +php: | + "B" +--- +test: Escaped 16-bit Unicode +yaml: | + "\u20ac" +php: | + "\xe2\x82\xac" +--- +test: Escaped 32-bit Unicode +yaml: | + "\U00000043" +php: | + "C" +--- +test: Example 5.13 Escaped Characters +note: | + Currently throws an error parsing first line. Maybe Symfony Yaml doesn't support + continuation of string across multiple lines? Keeping test here but disabled. +todo: true +yaml: | + "Fun with \\ + \" \a \b \e \f \ + \n \r \t \v \0 \ + \ \_ \N \L \P \ + \x41 \u0041 \U00000041" +php: | + "Fun with \x5C\n\x22 \x07 \x08 \x1B \x0C\n\x0A \x0D \x09 \x0B \x00\n\x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9\nA A A" +--- +test: Double quotes with a line feed +yaml: | + { double: "some value\n \"some quoted string\" and 'some single quotes one'" } +php: | + array( + 'double' => "some value\n \"some quoted string\" and 'some single quotes one'" + ) +--- +test: Backslashes +yaml: | + { single: 'foo\Var', no-quotes: foo\Var, double: "foo\\Var" } +php: | + array( + 'single' => 'foo\Var', 'no-quotes' => 'foo\Var', 'double' => 'foo\Var' + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/index.yml b/vendor/symfony/yaml/Tests/Fixtures/index.yml new file mode 100644 index 000000000..3216a89eb --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/index.yml @@ -0,0 +1,18 @@ +- escapedCharacters +- sfComments +- sfCompact +- sfTests +- sfObjects +- sfMergeKey +- sfQuotes +- YtsAnchorAlias +- YtsBasicTests +- YtsBlockMapping +- YtsDocumentSeparator +- YtsErrorTests +- YtsFlowCollections +- YtsFoldedScalars +- YtsNullsAndEmpties +- YtsSpecificationExamples +- YtsTypeTransfers +- unindentedCollections diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml b/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml new file mode 100644 index 000000000..b72a9b699 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml @@ -0,0 +1,76 @@ +--- %YAML:1.0 +test: Comments at the end of a line +brief: > + Comments at the end of a line +yaml: | + ex1: "foo # bar" + ex2: "foo # bar" # comment + ex3: 'foo # bar' # comment + ex4: foo # comment + ex5: foo # comment with tab before + ex6: foo#foo # comment here + ex7: foo # ignore me # and me +php: | + array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo', 'ex5' => 'foo', 'ex6' => 'foo#foo', 'ex7' => 'foo') +--- +test: Comments in the middle +brief: > + Comments in the middle +yaml: | + foo: + # some comment + # some comment + bar: foo + # some comment + # some comment +php: | + array('foo' => array('bar' => 'foo')) +--- +test: Comments on a hash line +brief: > + Comments on a hash line +yaml: | + foo: # a comment + foo: bar # a comment +php: | + array('foo' => array('foo' => 'bar')) +--- +test: 'Value starting with a #' +brief: > + 'Value starting with a #' +yaml: | + foo: '#bar' +php: | + array('foo' => '#bar') +--- +test: Document starting with a comment and a separator +brief: > + Commenting before document start is allowed +yaml: | + # document comment + --- + foo: bar # a comment +php: | + array('foo' => 'bar') +--- +test: Comment containing a colon on a hash line +brief: > + Comment containing a colon on a scalar line +yaml: 'foo # comment: this is also part of the comment' +php: | + 'foo' +--- +test: 'Hash key containing a #' +brief: > + 'Hash key containing a #' +yaml: 'foo#bar: baz' +php: | + array('foo#bar' => 'baz') +--- +test: 'Hash key ending with a space and a #' +brief: > + 'Hash key ending with a space and a #' +yaml: | + 'foo #': baz +php: | + array('foo #' => 'baz') diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml b/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml new file mode 100644 index 000000000..1339d23a6 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml @@ -0,0 +1,159 @@ +--- %YAML:1.0 +test: Compact notation +brief: | + Compact notation for sets of mappings with single element +yaml: | + --- + # products purchased + - item : Super Hoop + - item : Basketball + quantity: 1 + - item: + name: Big Shoes + nick: Biggies + quantity: 1 +php: | + array ( + array ( + 'item' => 'Super Hoop', + ), + array ( + 'item' => 'Basketball', + 'quantity' => 1, + ), + array ( + 'item' => array( + 'name' => 'Big Shoes', + 'nick' => 'Biggies' + ), + 'quantity' => 1 + ) + ) +--- +test: Compact notation combined with inline notation +brief: | + Combinations of compact and inline notation are allowed +yaml: | + --- + items: + - { item: Super Hoop, quantity: 1 } + - [ Basketball, Big Shoes ] +php: | + array ( + 'items' => array ( + array ( + 'item' => 'Super Hoop', + 'quantity' => 1, + ), + array ( + 'Basketball', + 'Big Shoes' + ) + ) + ) +--- %YAML:1.0 +test: Compact notation +brief: | + Compact notation for sets of mappings with single element +yaml: | + --- + # products purchased + - item : Super Hoop + - item : Basketball + quantity: 1 + - item: + name: Big Shoes + nick: Biggies + quantity: 1 +php: | + array ( + array ( + 'item' => 'Super Hoop', + ), + array ( + 'item' => 'Basketball', + 'quantity' => 1, + ), + array ( + 'item' => array( + 'name' => 'Big Shoes', + 'nick' => 'Biggies' + ), + 'quantity' => 1 + ) + ) +--- +test: Compact notation combined with inline notation +brief: | + Combinations of compact and inline notation are allowed +yaml: | + --- + items: + - { item: Super Hoop, quantity: 1 } + - [ Basketball, Big Shoes ] +php: | + array ( + 'items' => array ( + array ( + 'item' => 'Super Hoop', + 'quantity' => 1, + ), + array ( + 'Basketball', + 'Big Shoes' + ) + ) + ) +--- %YAML:1.0 +test: Compact notation +brief: | + Compact notation for sets of mappings with single element +yaml: | + --- + # products purchased + - item : Super Hoop + - item : Basketball + quantity: 1 + - item: + name: Big Shoes + nick: Biggies + quantity: 1 +php: | + array ( + array ( + 'item' => 'Super Hoop', + ), + array ( + 'item' => 'Basketball', + 'quantity' => 1, + ), + array ( + 'item' => array( + 'name' => 'Big Shoes', + 'nick' => 'Biggies' + ), + 'quantity' => 1 + ) + ) +--- +test: Compact notation combined with inline notation +brief: | + Combinations of compact and inline notation are allowed +yaml: | + --- + items: + - { item: Super Hoop, quantity: 1 } + - [ Basketball, Big Shoes ] +php: | + array ( + 'items' => array ( + array ( + 'item' => 'Super Hoop', + 'quantity' => 1, + ), + array ( + 'Basketball', + 'Big Shoes' + ) + ) + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml b/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml new file mode 100644 index 000000000..59f612514 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml @@ -0,0 +1,60 @@ +--- %YAML:1.0 +test: Simple In Place Substitution +brief: > + If you want to reuse an entire alias, only overwriting what is different + you can use a << in place substitution. This is not part of the official + YAML spec, but a widely implemented extension. See the following URL for + details: http://yaml.org/type/merge.html +yaml: | + foo: &foo + a: Steve + b: Clark + c: Brian + e: notnull + bar: + a: before + d: other + e: ~ + <<: *foo + b: new + x: Oren + c: + foo: bar + foo: ignore + bar: foo + duplicate: + foo: bar + foo: ignore + foo2: &foo2 + a: Ballmer + ding: &dong [ fi, fei, fo, fam] + check: + <<: + - *foo + - *dong + isit: tested + head: + <<: [ *foo , *dong , *foo2 ] + taz: &taz + a: Steve + w: + p: 1234 + nested: + <<: *taz + d: Doug + w: &nestedref + p: 12345 + z: + <<: *nestedref +php: | + array( + 'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull'), + 'bar' => array('a' => 'before', 'd' => 'other', 'e' => null, 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'), + 'duplicate' => array('foo' => 'bar'), + 'foo2' => array('a' => 'Ballmer'), + 'ding' => array('fi', 'fei', 'fo', 'fam'), + 'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'), + 'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'), + 'taz' => array('a' => 'Steve', 'w' => array('p' => 1234)), + 'nested' => array('a' => 'Steve', 'w' => array('p' => 12345), 'd' => 'Doug', 'z' => array('p' => 12345)) + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml b/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml new file mode 100644 index 000000000..ee124b244 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml @@ -0,0 +1,11 @@ +--- %YAML:1.0 +test: Objects +brief: > + Comments at the end of a line +yaml: | + ex1: "foo # bar" + ex2: "foo # bar" # comment + ex3: 'foo # bar' # comment + ex4: foo # comment +php: | + array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo') diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml b/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml new file mode 100644 index 000000000..7c60baec9 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml @@ -0,0 +1,33 @@ +--- %YAML:1.0 +test: Some characters at the beginning of a string must be escaped +brief: > + Some characters at the beginning of a string must be escaped +yaml: | + foo: '| bar' +php: | + array('foo' => '| bar') +--- +test: A key can be a quoted string +brief: > + A key can be a quoted string +yaml: | + "foo1": bar + 'foo2': bar + "foo \" bar": bar + 'foo '' bar': bar + 'foo3: ': bar + "foo4: ": bar + foo5: { "foo \" bar: ": bar, 'foo '' bar: ': bar } +php: | + array( + 'foo1' => 'bar', + 'foo2' => 'bar', + 'foo " bar' => 'bar', + 'foo \' bar' => 'bar', + 'foo3: ' => 'bar', + 'foo4: ' => 'bar', + 'foo5' => array( + 'foo " bar: ' => 'bar', + 'foo \' bar: ' => 'bar', + ), + ) diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml b/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml new file mode 100644 index 000000000..a427be1c8 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml @@ -0,0 +1,149 @@ +--- %YAML:1.0 +test: Multiple quoted string on one line +brief: > + Multiple quoted string on one line +yaml: | + stripped_title: { name: "foo bar", help: "bar foo" } +php: | + array('stripped_title' => array('name' => 'foo bar', 'help' => 'bar foo')) +--- +test: Empty sequence +yaml: | + foo: [ ] +php: | + array('foo' => array()) +--- +test: Empty value +yaml: | + foo: +php: | + array('foo' => null) +--- +test: Inline string parsing +brief: > + Inline string parsing +yaml: | + test: ['complex: string', 'another [string]'] +php: | + array('test' => array('complex: string', 'another [string]')) +--- +test: Boolean +brief: > + Boolean +yaml: | + - false + - true + - null + - ~ + - 'false' + - 'true' + - 'null' + - '~' +php: | + array( + false, + true, + null, + null, + 'false', + 'true', + 'null', + '~', + ) +--- +test: Empty lines in literal blocks +brief: > + Empty lines in literal blocks +yaml: | + foo: + bar: | + foo + + + + bar +php: | + array('foo' => array('bar' => "foo\n\n\n \nbar\n")) +--- +test: Empty lines in folded blocks +brief: > + Empty lines in folded blocks +yaml: | + foo: + bar: > + + foo + + + bar +php: | + array('foo' => array('bar' => "\nfoo\n\nbar\n")) +--- +test: IP addresses +brief: > + IP addresses +yaml: | + foo: 10.0.0.2 +php: | + array('foo' => '10.0.0.2') +--- +test: A sequence with an embedded mapping +brief: > + A sequence with an embedded mapping +yaml: | + - foo + - bar: { bar: foo } +php: | + array('foo', array('bar' => array('bar' => 'foo'))) +--- +test: A sequence with an unordered array +brief: > + A sequence with an unordered array +yaml: | + 1: foo + 0: bar +php: | + array(1 => 'foo', 0 => 'bar') +--- +test: Octal +brief: as in spec example 2.19, octal value is converted +yaml: | + foo: 0123 +php: | + array('foo' => 83) +--- +test: Octal strings +brief: Octal notation in a string must remain a string +yaml: | + foo: "0123" +php: | + array('foo' => '0123') +--- +test: Octal strings +brief: Octal notation in a string must remain a string +yaml: | + foo: '0123' +php: | + array('foo' => '0123') +--- +test: Octal strings +brief: Octal notation in a string must remain a string +yaml: | + foo: | + 0123 +php: | + array('foo' => "0123\n") +--- +test: Document as a simple hash +brief: Document as a simple hash +yaml: | + { foo: bar } +php: | + array('foo' => 'bar') +--- +test: Document as a simple array +brief: Document as a simple array +yaml: | + [ foo, bar ] +php: | + array('foo', 'bar') diff --git a/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml b/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml new file mode 100644 index 000000000..0c96108e9 --- /dev/null +++ b/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml @@ -0,0 +1,82 @@ +--- %YAML:1.0 +test: Unindented collection +brief: > + Unindented collection +yaml: | + collection: + - item1 + - item2 + - item3 +php: | + array('collection' => array('item1', 'item2', 'item3')) +--- +test: Nested unindented collection (two levels) +brief: > + Nested unindented collection +yaml: | + collection: + key: + - a + - b + - c +php: | + array('collection' => array('key' => array('a', 'b', 'c'))) +--- +test: Nested unindented collection (three levels) +brief: > + Nested unindented collection +yaml: | + collection: + key: + subkey: + - one + - two + - three +php: | + array('collection' => array('key' => array('subkey' => array('one', 'two', 'three')))) +--- +test: Key/value after unindented collection (1) +brief: > + Key/value after unindented collection (1) +yaml: | + collection: + key: + - a + - b + - c + foo: bar +php: | + array('collection' => array('key' => array('a', 'b', 'c')), 'foo' => 'bar') +--- +test: Key/value after unindented collection (at the same level) +brief: > + Key/value after unindented collection +yaml: | + collection: + key: + - a + - b + - c + foo: bar +php: | + array('collection' => array('key' => array('a', 'b', 'c'), 'foo' => 'bar')) +--- +test: Shortcut Key after unindented collection +brief: > + Key/value after unindented collection +yaml: | + collection: + - key: foo + foo: bar +php: | + array('collection' => array(array('key' => 'foo', 'foo' => 'bar'))) +--- +test: Shortcut Key after unindented collection with custom spaces +brief: > + Key/value after unindented collection +yaml: | + collection: + - key: foo + foo: bar +php: | + array('collection' => array(array('key' => 'foo', 'foo' => 'bar'))) diff --git a/vendor/symfony/yaml/Tests/InlineTest.php b/vendor/symfony/yaml/Tests/InlineTest.php new file mode 100644 index 000000000..7ca692dd1 --- /dev/null +++ b/vendor/symfony/yaml/Tests/InlineTest.php @@ -0,0 +1,497 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Inline; + +class InlineTest extends TestCase +{ + /** + * @dataProvider getTestsForParse + */ + public function testParse($yaml, $value) + { + $this->assertSame($value, Inline::parse($yaml), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml)); + } + + /** + * @dataProvider getTestsForParseWithMapObjects + */ + public function testParseWithMapObjects($yaml, $value) + { + $actual = Inline::parse($yaml, false, false, true); + + $this->assertSame(serialize($value), serialize($actual)); + } + + /** + * @dataProvider getTestsForDump + */ + public function testDump($yaml, $value) + { + $this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml)); + + $this->assertSame($value, Inline::parse(Inline::dump($value)), 'check consistency'); + } + + public function testDumpNumericValueWithLocale() + { + $locale = setlocale(LC_NUMERIC, 0); + if (false === $locale) { + $this->markTestSkipped('Your platform does not support locales.'); + } + + try { + $requiredLocales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252'); + if (false === setlocale(LC_NUMERIC, $requiredLocales)) { + $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $requiredLocales)); + } + + $this->assertEquals('1.2', Inline::dump(1.2)); + $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0))); + setlocale(LC_NUMERIC, $locale); + } catch (\Exception $e) { + setlocale(LC_NUMERIC, $locale); + throw $e; + } + } + + public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF() + { + $value = '686e444'; + + $this->assertSame($value, Inline::parse(Inline::dump($value))); + } + + /** + * @group legacy + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseScalarWithNonEscapedBlackslashShouldThrowException() + { + $this->assertSame('Foo\Var', Inline::parse('"Foo\Var"')); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseScalarWithNonEscapedBlackslashAtTheEndShouldThrowException() + { + Inline::parse('"Foo\\"'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException() + { + $value = "'don't do somthin' like that'"; + Inline::parse($value); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException() + { + $value = '"don"t do somthin" like that"'; + Inline::parse($value); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseInvalidMappingKeyShouldThrowException() + { + $value = '{ "foo " bar": "bar" }'; + Inline::parse($value); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseInvalidMappingShouldThrowException() + { + Inline::parse('[foo] bar'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseInvalidSequenceShouldThrowException() + { + Inline::parse('{ foo: bar } bar'); + } + + public function testParseScalarWithCorrectlyQuotedStringShouldReturnString() + { + $value = "'don''t do somthin'' like that'"; + $expect = "don't do somthin' like that"; + + $this->assertSame($expect, Inline::parseScalar($value)); + } + + /** + * @dataProvider getDataForParseReferences + */ + public function testParseReferences($yaml, $expected) + { + $this->assertSame($expected, Inline::parse($yaml, false, false, false, array('var' => 'var-value'))); + } + + public function getDataForParseReferences() + { + return array( + 'scalar' => array('*var', 'var-value'), + 'list' => array('[ *var ]', array('var-value')), + 'list-in-list' => array('[[ *var ]]', array(array('var-value'))), + 'map-in-list' => array('[ { key: *var } ]', array(array('key' => 'var-value'))), + 'embedded-mapping-in-list' => array('[ key: *var ]', array(array('key' => 'var-value'))), + 'map' => array('{ key: *var }', array('key' => 'var-value')), + 'list-in-map' => array('{ key: [*var] }', array('key' => array('var-value'))), + 'map-in-map' => array('{ foo: { bar: *var } }', array('foo' => array('bar' => 'var-value'))), + ); + } + + public function testParseMapReferenceInSequence() + { + $foo = array( + 'a' => 'Steve', + 'b' => 'Clark', + 'c' => 'Brian', + ); + $this->assertSame(array($foo), Inline::parse('[*foo]', false, false, false, array('foo' => $foo))); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage A reference must contain at least one character. + */ + public function testParseUnquotedAsterisk() + { + Inline::parse('{ foo: * }'); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage A reference must contain at least one character. + */ + public function testParseUnquotedAsteriskFollowedByAComment() + { + Inline::parse('{ foo: * #foo }'); + } + + /** + * @group legacy + * @expectedDeprecation Not quoting the scalar "@foo " starting with "@" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseUnquotedScalarStartingWithReservedAtIndicator() + { + Inline::parse('{ foo: @foo }'); + } + + /** + * @group legacy + * @expectedDeprecation Not quoting the scalar "`foo " starting with "`" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseUnquotedScalarStartingWithReservedBacktickIndicator() + { + Inline::parse('{ foo: `foo }'); + } + + /** + * @group legacy + * @expectedDeprecation Not quoting the scalar "|foo " starting with "|" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseUnquotedScalarStartingWithLiteralStyleIndicator() + { + Inline::parse('{ foo: |foo }'); + } + + /** + * @group legacy + * @expectedDeprecation Not quoting the scalar ">foo " starting with ">" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseUnquotedScalarStartingWithFoldedStyleIndicator() + { + Inline::parse('{ foo: >foo }'); + } + + public function getScalarIndicators() + { + return array(array('|'), array('>')); + } + + /** + * @dataProvider getDataForIsHash + */ + public function testIsHash($array, $expected) + { + $this->assertSame($expected, Inline::isHash($array)); + } + + public function getDataForIsHash() + { + return array( + array(array(), false), + array(array(1, 2, 3), false), + array(array(2 => 1, 1 => 2, 0 => 3), true), + array(array('foo' => 1, 'bar' => 2), true), + ); + } + + public function getTestsForParse() + { + return array( + array('', ''), + array('null', null), + array('false', false), + array('true', true), + array('12', 12), + array('-12', -12), + array('"quoted string"', 'quoted string'), + array("'quoted string'", 'quoted string'), + array('12.30e+02', 12.30e+02), + array('0x4D2', 0x4D2), + array('02333', 02333), + array('.Inf', -log(0)), + array('-.Inf', log(0)), + array("'686e444'", '686e444'), + array('686e444', 646e444), + array('123456789123456789123456789123456789', '123456789123456789123456789123456789'), + array('"foo\r\nbar"', "foo\r\nbar"), + array("'foo#bar'", 'foo#bar'), + array("'foo # bar'", 'foo # bar'), + array("'#cfcfcf'", '#cfcfcf'), + array('::form_base.html.twig', '::form_base.html.twig'), + + // Pre-YAML-1.2 booleans + array("'y'", 'y'), + array("'n'", 'n'), + array("'yes'", 'yes'), + array("'no'", 'no'), + array("'on'", 'on'), + array("'off'", 'off'), + + array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)), + array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)), + array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)), + array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)), + array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)), + + array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''), + array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''), + + // sequences + // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon + array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)), + array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)), + array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')), + + // mappings + array('{foo:bar,bar:foo,false:false,null:null,integer:12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{foo: \'bar\', bar: \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')), + array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')), + array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', array('foo\'' => 'bar', 'bar"' => 'foo: bar')), + array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', array('foo: ' => 'bar', 'bar: ' => 'foo: bar')), + + // nested sequences and mappings + array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))), + array('[foo, {bar: foo}]', array('foo', array('bar' => 'foo'))), + array('{ foo: {bar: foo} }', array('foo' => array('bar' => 'foo'))), + array('{ foo: [bar, foo] }', array('foo' => array('bar', 'foo'))), + + array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))), + + array('[{ foo: {bar: foo} }]', array(array('foo' => array('bar' => 'foo')))), + + array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))), + + array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))), + + array('[foo, bar: { foo: bar }]', array('foo', '1' => array('bar' => array('foo' => 'bar')))), + array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')), + ); + } + + public function getTestsForParseWithMapObjects() + { + return array( + array('', ''), + array('null', null), + array('false', false), + array('true', true), + array('12', 12), + array('-12', -12), + array('"quoted string"', 'quoted string'), + array("'quoted string'", 'quoted string'), + array('12.30e+02', 12.30e+02), + array('0x4D2', 0x4D2), + array('02333', 02333), + array('.Inf', -log(0)), + array('-.Inf', log(0)), + array("'686e444'", '686e444'), + array('686e444', 646e444), + array('123456789123456789123456789123456789', '123456789123456789123456789123456789'), + array('"foo\r\nbar"', "foo\r\nbar"), + array("'foo#bar'", 'foo#bar'), + array("'foo # bar'", 'foo # bar'), + array("'#cfcfcf'", '#cfcfcf'), + array('::form_base.html.twig', '::form_base.html.twig'), + + array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)), + array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)), + array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)), + array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)), + array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)), + + array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''), + array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''), + + // sequences + // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon + array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)), + array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)), + array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')), + + // mappings + array('{foo:bar,bar:foo,false:false,null:null,integer:12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{foo: \'bar\', bar: \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')), + array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')), + array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) array('foo\'' => 'bar', 'bar"' => 'foo: bar')), + array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', (object) array('foo: ' => 'bar', 'bar: ' => 'foo: bar')), + + // nested sequences and mappings + array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))), + array('[foo, {bar: foo}]', array('foo', (object) array('bar' => 'foo'))), + array('{ foo: {bar: foo} }', (object) array('foo' => (object) array('bar' => 'foo'))), + array('{ foo: [bar, foo] }', (object) array('foo' => array('bar', 'foo'))), + + array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))), + + array('[{ foo: {bar: foo} }]', array((object) array('foo' => (object) array('bar' => 'foo')))), + + array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))), + + array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', (object) array('bar' => 'foo', 'foo' => array('foo', (object) array('bar' => 'foo'))), array('foo', (object) array('bar' => 'foo')))), + + array('[foo, bar: { foo: bar }]', array('foo', '1' => (object) array('bar' => (object) array('foo' => 'bar')))), + array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', (object) array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')), + + array('{}', new \stdClass()), + array('{ foo : bar, bar : {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())), + array('{ foo : [], bar : {} }', (object) array('foo' => array(), 'bar' => new \stdClass())), + array('{foo: \'bar\', bar: {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())), + array('{\'foo\': \'bar\', "bar": {}}', (object) array('foo' => 'bar', 'bar' => new \stdClass())), + array('{\'foo\': \'bar\', "bar": \'{}\'}', (object) array('foo' => 'bar', 'bar' => '{}')), + + array('[foo, [{}, {}]]', array('foo', array(new \stdClass(), new \stdClass()))), + array('[foo, [[], {}]]', array('foo', array(array(), new \stdClass()))), + array('[foo, [[{}, {}], {}]]', array('foo', array(array(new \stdClass(), new \stdClass()), new \stdClass()))), + array('[foo, {bar: {}}]', array('foo', '1' => (object) array('bar' => new \stdClass()))), + ); + } + + public function getTestsForDump() + { + return array( + array('null', null), + array('false', false), + array('true', true), + array('12', 12), + array("'quoted string'", 'quoted string'), + array('!!float 1230', 12.30e+02), + array('1234', 0x4D2), + array('1243', 02333), + array('.Inf', -log(0)), + array('-.Inf', log(0)), + array("'686e444'", '686e444'), + array('"foo\r\nbar"', "foo\r\nbar"), + array("'foo#bar'", 'foo#bar'), + array("'foo # bar'", 'foo # bar'), + array("'#cfcfcf'", '#cfcfcf'), + + array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''), + + array("'-dash'", '-dash'), + array("'-'", '-'), + + // Pre-YAML-1.2 booleans + array("'y'", 'y'), + array("'n'", 'n'), + array("'yes'", 'yes'), + array("'no'", 'no'), + array("'on'", 'on'), + array("'off'", 'off'), + + // sequences + array('[foo, bar, false, null, 12]', array('foo', 'bar', false, null, 12)), + array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')), + + // mappings + array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)), + array('{ foo: bar, bar: \'foo: bar\' }', array('foo' => 'bar', 'bar' => 'foo: bar')), + + // nested sequences and mappings + array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))), + + array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))), + + array('{ foo: { bar: foo } }', array('foo' => array('bar' => 'foo'))), + + array('[foo, { bar: foo }]', array('foo', array('bar' => 'foo'))), + + array('[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))), + + array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')), + + array('{ foo: { bar: { 1: 2, baz: 3 } } }', array('foo' => array('bar' => array(1 => 2, 'baz' => 3)))), + ); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Malformed inline YAML string: {this, is not, supported}. + */ + public function testNotSupportedMissingValue() + { + Inline::parse('{this, is not, supported}'); + } + + public function testVeryLongQuotedStrings() + { + $longStringWithQuotes = str_repeat("x\r\n\\\"x\"x", 1000); + + $yamlString = Inline::dump(array('longStringWithQuotes' => $longStringWithQuotes)); + $arrayFromYaml = Inline::parse($yamlString); + + $this->assertEquals($longStringWithQuotes, $arrayFromYaml['longStringWithQuotes']); + } + + public function testBooleanMappingKeysAreConvertedToStrings() + { + $this->assertSame(array('false' => 'foo'), Inline::parse('{false: foo}')); + $this->assertSame(array('true' => 'foo'), Inline::parse('{true: foo}')); + } + + public function testTheEmptyStringIsAValidMappingKey() + { + $this->assertSame(array('' => 'foo'), Inline::parse('{ "": foo }')); + } +} diff --git a/vendor/symfony/yaml/Tests/ParseExceptionTest.php b/vendor/symfony/yaml/Tests/ParseExceptionTest.php new file mode 100644 index 000000000..b7797fb7f --- /dev/null +++ b/vendor/symfony/yaml/Tests/ParseExceptionTest.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Exception\ParseException; + +class ParseExceptionTest extends TestCase +{ + public function testGetMessage() + { + $exception = new ParseException('Error message', 42, 'foo: bar', '/var/www/app/config.yml'); + if (\PHP_VERSION_ID >= 50400) { + $message = 'Error message in "/var/www/app/config.yml" at line 42 (near "foo: bar")'; + } else { + $message = 'Error message in "\\/var\\/www\\/app\\/config.yml" at line 42 (near "foo: bar")'; + } + + $this->assertEquals($message, $exception->getMessage()); + } + + public function testGetMessageWithUnicodeInFilename() + { + $exception = new ParseException('Error message', 42, 'foo: bar', 'äöü.yml'); + if (\PHP_VERSION_ID >= 50400) { + $message = 'Error message in "äöü.yml" at line 42 (near "foo: bar")'; + } else { + $message = 'Error message in "\u00e4\u00f6\u00fc.yml" at line 42 (near "foo: bar")'; + } + + $this->assertEquals($message, $exception->getMessage()); + } +} diff --git a/vendor/symfony/yaml/Tests/ParserTest.php b/vendor/symfony/yaml/Tests/ParserTest.php new file mode 100644 index 000000000..2c3a6e0b8 --- /dev/null +++ b/vendor/symfony/yaml/Tests/ParserTest.php @@ -0,0 +1,1260 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Yaml; +use Symfony\Component\Yaml\Parser; + +class ParserTest extends TestCase +{ + /** @var Parser */ + protected $parser; + + protected function setUp() + { + $this->parser = new Parser(); + } + + protected function tearDown() + { + $this->parser = null; + } + + /** + * @dataProvider getDataFormSpecifications + */ + public function testSpecifications($file, $expected, $yaml, $comment) + { + $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment); + } + + public function getDataFormSpecifications() + { + $parser = new Parser(); + $path = __DIR__.'/Fixtures'; + + $tests = array(); + $files = $parser->parse(file_get_contents($path.'/index.yml')); + foreach ($files as $file) { + $yamls = file_get_contents($path.'/'.$file.'.yml'); + + // split YAMLs documents + foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) { + if (!$yaml) { + continue; + } + + $test = $parser->parse($yaml); + if (isset($test['todo']) && $test['todo']) { + // TODO + } else { + eval('$expected = '.trim($test['php']).';'); + + $tests[] = array($file, var_export($expected, true), $test['yaml'], $test['test']); + } + } + } + + return $tests; + } + + public function testTabsInYaml() + { + // test tabs in YAML + $yamls = array( + "foo:\n bar", + "foo:\n bar", + "foo:\n bar", + "foo:\n bar", + ); + + foreach ($yamls as $yaml) { + try { + $content = $this->parser->parse($yaml); + + $this->fail('YAML files must not contain tabs'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs'); + $this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs'); + } + } + } + + public function testEndOfTheDocumentMarker() + { + $yaml = <<<'EOF' +--- %YAML:1.0 +foo +... +EOF; + + $this->assertEquals('foo', $this->parser->parse($yaml)); + } + + public function getBlockChompingTests() + { + $tests = array(); + + $yaml = <<<'EOF' +foo: |- + one + two +bar: |- + one + two + +EOF; + $expected = array( + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping strip with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |- + one + two + +bar: |- + one + two + + +EOF; + $expected = array( + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping strip with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +{} + + +EOF; + $expected = array(); + $tests['Literal block chomping strip with multiple trailing newlines after a 1-liner'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |- + one + two +bar: |- + one + two +EOF; + $expected = array( + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: | + one + two +bar: | + one + two + +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ); + $tests['Literal block chomping clip with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: | + one + two + +bar: | + one + two + + +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ); + $tests['Literal block chomping clip with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: +- bar: | + one + + two +EOF; + $expected = array( + 'foo' => array( + array( + 'bar' => "one\n\ntwo", + ), + ), + ); + $tests['Literal block chomping clip with embedded blank line inside unindented collection'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: | + one + two +bar: | + one + two +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |+ + one + two +bar: |+ + one + two + +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ); + $tests['Literal block chomping keep with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |+ + one + two + +bar: |+ + one + two + + +EOF; + $expected = array( + 'foo' => "one\ntwo\n\n", + 'bar' => "one\ntwo\n\n", + ); + $tests['Literal block chomping keep with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: |+ + one + two +bar: |+ + one + two +EOF; + $expected = array( + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo", + ); + $tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >- + one + two +bar: >- + one + two + +EOF; + $expected = array( + 'foo' => 'one two', + 'bar' => 'one two', + ); + $tests['Folded block chomping strip with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >- + one + two + +bar: >- + one + two + + +EOF; + $expected = array( + 'foo' => 'one two', + 'bar' => 'one two', + ); + $tests['Folded block chomping strip with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >- + one + two +bar: >- + one + two +EOF; + $expected = array( + 'foo' => 'one two', + 'bar' => 'one two', + ); + $tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: > + one + two +bar: > + one + two + +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => "one two\n", + ); + $tests['Folded block chomping clip with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: > + one + two + +bar: > + one + two + + +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => "one two\n", + ); + $tests['Folded block chomping clip with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: > + one + two +bar: > + one + two +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => 'one two', + ); + $tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >+ + one + two +bar: >+ + one + two + +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => "one two\n", + ); + $tests['Folded block chomping keep with single trailing newline'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >+ + one + two + +bar: >+ + one + two + + +EOF; + $expected = array( + 'foo' => "one two\n\n", + 'bar' => "one two\n\n", + ); + $tests['Folded block chomping keep with multiple trailing newlines'] = array($expected, $yaml); + + $yaml = <<<'EOF' +foo: >+ + one + two +bar: >+ + one + two +EOF; + $expected = array( + 'foo' => "one two\n", + 'bar' => 'one two', + ); + $tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml); + + return $tests; + } + + /** + * @dataProvider getBlockChompingTests + */ + public function testBlockChomping($expected, $yaml) + { + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + /** + * Regression test for issue #7989. + * + * @see https://github.com/symfony/symfony/issues/7989 + */ + public function testBlockLiteralWithLeadingNewlines() + { + $yaml = <<<'EOF' +foo: |- + + + bar + +EOF; + $expected = array( + 'foo' => "\n\nbar", + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testObjectSupportEnabled() + { + $input = <<<'EOF' +foo: !!php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects'); + + $input = <<<'EOF' +foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, false, true), '->parse() is able to parse objects'); + } + + /** + * @dataProvider invalidDumpedObjectProvider + */ + public function testObjectSupportDisabledButNoExceptions($input) + { + $this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects'); + } + + /** + * @dataProvider getObjectForMapTests + */ + public function testObjectForMap($yaml, $expected) + { + $this->assertEquals($expected, $this->parser->parse($yaml, false, false, true)); + } + + public function getObjectForMapTests() + { + $tests = array(); + + $yaml = <<<'EOF' +foo: + fiz: [cat] +EOF; + $expected = new \stdClass(); + $expected->foo = new \stdClass(); + $expected->foo->fiz = array('cat'); + $tests['mapping'] = array($yaml, $expected); + + $yaml = '{ "foo": "bar", "fiz": "cat" }'; + $expected = new \stdClass(); + $expected->foo = 'bar'; + $expected->fiz = 'cat'; + $tests['inline-mapping'] = array($yaml, $expected); + + $yaml = "foo: bar\nbaz: foobar"; + $expected = new \stdClass(); + $expected->foo = 'bar'; + $expected->baz = 'foobar'; + $tests['object-for-map-is-applied-after-parsing'] = array($yaml, $expected); + + $yaml = <<<'EOT' +array: + - key: one + - key: two +EOT; + $expected = new \stdClass(); + $expected->array = array(); + $expected->array[0] = new \stdClass(); + $expected->array[0]->key = 'one'; + $expected->array[1] = new \stdClass(); + $expected->array[1]->key = 'two'; + $tests['nest-map-and-sequence'] = array($yaml, $expected); + + $yaml = <<<'YAML' +map: + 1: one + 2: two +YAML; + $expected = new \stdClass(); + $expected->map = new \stdClass(); + $expected->map->{1} = 'one'; + $expected->map->{2} = 'two'; + $tests['numeric-keys'] = array($yaml, $expected); + + $yaml = <<<'YAML' +map: + 0: one + 1: two +YAML; + $expected = new \stdClass(); + $expected->map = new \stdClass(); + $expected->map->{0} = 'one'; + $expected->map->{1} = 'two'; + $tests['zero-indexed-numeric-keys'] = array($yaml, $expected); + + return $tests; + } + + /** + * @dataProvider invalidDumpedObjectProvider + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testObjectsSupportDisabledWithExceptions($yaml) + { + $this->parser->parse($yaml, true, false); + } + + public function invalidDumpedObjectProvider() + { + $yamlTag = <<<'EOF' +foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + $localTag = <<<'EOF' +foo: !php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + + return array( + 'yaml-tag' => array($yamlTag), + 'local-tag' => array($localTag), + ); + } + + /** + * @requires extension iconv + */ + public function testNonUtf8Exception() + { + $yamls = array( + iconv('UTF-8', 'ISO-8859-1', "foo: 'äöüß'"), + iconv('UTF-8', 'ISO-8859-15', "euro: '€'"), + iconv('UTF-8', 'CP1252', "cp1252: '©ÉÇáñ'"), + ); + + foreach ($yamls as $yaml) { + try { + $this->parser->parse($yaml); + + $this->fail('charsets other than UTF-8 are rejected.'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.'); + } + } + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testUnindentedCollectionException() + { + $yaml = <<<'EOF' + +collection: +-item1 +-item2 +-item3 + +EOF; + + $this->parser->parse($yaml); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testShortcutKeyUnindentedCollectionException() + { + $yaml = <<<'EOF' + +collection: +- key: foo + foo: bar + +EOF; + + $this->parser->parse($yaml); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/ + */ + public function testMultipleDocumentsNotSupportedException() + { + Yaml::parse(<<<'EOL' +# Ranking of 1998 home runs +--- +- Mark McGwire +- Sammy Sosa +- Ken Griffey + +# Team ranking +--- +- Chicago Cubs +- St Louis Cardinals +EOL + ); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testSequenceInAMapping() + { + Yaml::parse(<<<'EOF' +yaml: + hash: me + - array stuff +EOF + ); + } + + public function testSequenceInMappingStartedBySingleDashLine() + { + $yaml = <<<'EOT' +a: +- + b: + - + bar: baz +- foo +d: e +EOT; + $expected = array( + 'a' => array( + array( + 'b' => array( + array( + 'bar' => 'baz', + ), + ), + ), + 'foo', + ), + 'd' => 'e', + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testSequenceFollowedByCommentEmbeddedInMapping() + { + $yaml = <<<'EOT' +a: + b: + - c +# comment + d: e +EOT; + $expected = array( + 'a' => array( + 'b' => array('c'), + 'd' => 'e', + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testMappingInASequence() + { + Yaml::parse(<<<'EOF' +yaml: + - array stuff + hash: me +EOF + ); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage missing colon + */ + public function testScalarInSequence() + { + Yaml::parse(<<<'EOF' +foo: + - bar +"missing colon" + foo: bar +EOF + ); + } + + /** + * > It is an error for two equal keys to appear in the same mapping node. + * > In such a case the YAML processor may continue, ignoring the second + * > `key: value` pair and issuing an appropriate warning. This strategy + * > preserves a consistent information model for one-pass and random access + * > applications. + * + * @see http://yaml.org/spec/1.2/spec.html#id2759572 + * @see http://yaml.org/spec/1.1/#id932806 + */ + public function testMappingDuplicateKeyBlock() + { + $input = <<<'EOD' +parent: + child: first + child: duplicate +parent: + child: duplicate + child: duplicate +EOD; + $expected = array( + 'parent' => array( + 'child' => 'first', + ), + ); + $this->assertSame($expected, Yaml::parse($input)); + } + + public function testMappingDuplicateKeyFlow() + { + $input = <<<'EOD' +parent: { child: first, child: duplicate } +parent: { child: duplicate, child: duplicate } +EOD; + $expected = array( + 'parent' => array( + 'child' => 'first', + ), + ); + $this->assertSame($expected, Yaml::parse($input)); + } + + public function testEmptyValue() + { + $input = <<<'EOF' +hash: +EOF; + + $this->assertEquals(array('hash' => null), Yaml::parse($input)); + } + + public function testCommentAtTheRootIndent() + { + $this->assertEquals(array( + 'services' => array( + 'app.foo_service' => array( + 'class' => 'Foo', + ), + 'app/bar_service' => array( + 'class' => 'Bar', + ), + ), + ), Yaml::parse(<<<'EOF' +# comment 1 +services: +# comment 2 + # comment 3 + app.foo_service: + class: Foo +# comment 4 + # comment 5 + app/bar_service: + class: Bar +EOF + )); + } + + public function testStringBlockWithComments() + { + $this->assertEquals(array('content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + ), Yaml::parse(<<<'EOF' +content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOF + )); + } + + public function testFoldedStringBlockWithComments() + { + $this->assertEquals(array(array('content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + )), Yaml::parse(<<<'EOF' +- + content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOF + )); + } + + public function testNestedFoldedStringBlockWithComments() + { + $this->assertEquals(array(array( + 'title' => 'some title', + 'content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + )), Yaml::parse(<<<'EOF' +- + title: some title + content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOF + )); + } + + public function testReferenceResolvingInInlineStrings() + { + $this->assertEquals(array( + 'var' => 'var-value', + 'scalar' => 'var-value', + 'list' => array('var-value'), + 'list_in_list' => array(array('var-value')), + 'map_in_list' => array(array('key' => 'var-value')), + 'embedded_mapping' => array(array('key' => 'var-value')), + 'map' => array('key' => 'var-value'), + 'list_in_map' => array('key' => array('var-value')), + 'map_in_map' => array('foo' => array('bar' => 'var-value')), + ), Yaml::parse(<<<'EOF' +var: &var var-value +scalar: *var +list: [ *var ] +list_in_list: [[ *var ]] +map_in_list: [ { key: *var } ] +embedded_mapping: [ key: *var ] +map: { key: *var } +list_in_map: { key: [*var] } +map_in_map: { foo: { bar: *var } } +EOF + )); + } + + public function testYamlDirective() + { + $yaml = <<<'EOF' +%YAML 1.2 +--- +foo: 1 +bar: 2 +EOF; + $this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml)); + } + + public function testFloatKeys() + { + $yaml = <<<'EOF' +foo: + 1.2: "bar" + 1.3: "baz" +EOF; + + $expected = array( + 'foo' => array( + '1.2' => 'bar', + '1.3' => 'baz', + ), + ); + + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + /** + * @group legacy + * @expectedDeprecation Using a colon in the unquoted mapping value "bar: baz" in line 1 is deprecated since Symfony 2.8 and will throw a ParseException in 3.0. + * throw ParseException in Symfony 3.0 + */ + public function testColonInMappingValueException() + { + $yaml = <<<'EOF' +foo: bar: baz +EOF; + + $this->parser->parse($yaml); + } + + public function testColonInMappingValueExceptionNotTriggeredByColonInComment() + { + $yaml = <<<'EOT' +foo: + bar: foobar # Note: a comment after a colon +EOT; + + $this->assertSame(array('foo' => array('bar' => 'foobar')), $this->parser->parse($yaml)); + } + + /** + * @dataProvider getCommentLikeStringInScalarBlockData + */ + public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult) + { + $this->assertSame($expectedParserResult, $this->parser->parse($yaml)); + } + + public function getCommentLikeStringInScalarBlockData() + { + $tests = array(); + + $yaml = <<<'EOT' +pages: + - + title: some title + content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOT; + $expected = array( + 'pages' => array( + array( + 'title' => 'some title', + 'content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + , + ), + ), + ); + $tests[] = array($yaml, $expected); + + $yaml = <<<'EOT' +test: | + foo + # bar + baz +collection: + - one: | + foo + # bar + baz + - two: | + foo + # bar + baz +EOT; + $expected = array( + 'test' => <<<'EOT' +foo +# bar +baz + +EOT + , + 'collection' => array( + array( + 'one' => <<<'EOT' +foo +# bar +baz + +EOT + , + ), + array( + 'two' => <<<'EOT' +foo +# bar +baz +EOT + , + ), + ), + ); + $tests[] = array($yaml, $expected); + + $yaml = <<<'EOT' +foo: + bar: + scalar-block: > + line1 + line2> + baz: +# comment + foobar: ~ +EOT; + $expected = array( + 'foo' => array( + 'bar' => array( + 'scalar-block' => "line1 line2>\n", + ), + 'baz' => array( + 'foobar' => null, + ), + ), + ); + $tests[] = array($yaml, $expected); + + $yaml = <<<'EOT' +a: + b: hello +# c: | +# first row +# second row + d: hello +EOT; + $expected = array( + 'a' => array( + 'b' => 'hello', + 'd' => 'hello', + ), + ); + $tests[] = array($yaml, $expected); + + return $tests; + } + + public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks() + { + $yaml = <<<'EOT' +test: > +

A heading

+ +
    +
  • a list
  • +
  • may be a good example
  • +
+EOT; + + $this->assertSame( + array( + 'test' => <<<'EOT' +

A heading

+
  • a list
  • may be a good example
+EOT + , + ), + $this->parser->parse($yaml) + ); + } + + public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks() + { + $yaml = <<<'EOT' +test: > +

A heading

+ +
    +
  • a list
  • +
  • may be a good example
  • +
+EOT; + + $this->assertSame( + array( + 'test' => <<<'EOT' +

A heading

+
    +
  • a list
  • +
  • may be a good example
  • +
+EOT + , + ), + $this->parser->parse($yaml) + ); + } + + /** + * @param $lineNumber + * @param $yaml + * @dataProvider parserThrowsExceptionWithCorrectLineNumberProvider + */ + public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml) + { + if (method_exists($this, 'expectException')) { + $this->expectException('\Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage(sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)); + } else { + $this->setExpectedException('\Symfony\Component\Yaml\Exception\ParseException', sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)); + } + + $this->parser->parse($yaml); + } + + public function parserThrowsExceptionWithCorrectLineNumberProvider() + { + return array( + array( + 4, + <<<'YAML' +foo: + - + # bar + bar: "123", +YAML + ), + array( + 5, + <<<'YAML' +foo: + - + # bar + # bar + bar: "123", +YAML + ), + array( + 8, + <<<'YAML' +foo: + - + # foobar + baz: 123 +bar: + - + # bar + bar: "123", +YAML + ), + array( + 10, + <<<'YAML' +foo: + - + # foobar + # foobar + baz: 123 +bar: + - + # bar + # bar + bar: "123", +YAML + ), + ); + } + + public function testCanParseVeryLongValue() + { + $longStringWithSpaces = str_repeat('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ', 20000); + $trickyVal = array('x' => $longStringWithSpaces); + + $yamlString = Yaml::dump($trickyVal); + $arrayFromYaml = $this->parser->parse($yamlString); + + $this->assertEquals($trickyVal, $arrayFromYaml); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + * @expectedExceptionMessage Reference "foo" does not exist at line 2 + */ + public function testParserCleansUpReferencesBetweenRuns() + { + $yaml = <<parser->parse($yaml); + + $yaml = <<parser->parse($yaml); + } +} + +class B +{ + public $b = 'foo'; +} diff --git a/vendor/symfony/yaml/Tests/YamlTest.php b/vendor/symfony/yaml/Tests/YamlTest.php new file mode 100644 index 000000000..9e776ca49 --- /dev/null +++ b/vendor/symfony/yaml/Tests/YamlTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Yaml; + +class YamlTest extends TestCase +{ + public function testParseAndDump() + { + $data = array('lorem' => 'ipsum', 'dolor' => 'sit'); + $yml = Yaml::dump($data); + $parsed = Yaml::parse($yml); + $this->assertEquals($data, $parsed); + } + + /** + * @group legacy + */ + public function testLegacyParseFromFile() + { + $filename = __DIR__.'/Fixtures/index.yml'; + $contents = file_get_contents($filename); + $parsedByFilename = Yaml::parse($filename); + $parsedByContents = Yaml::parse($contents); + $this->assertEquals($parsedByFilename, $parsedByContents); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The indentation must be greater than zero + */ + public function testZeroIndentationThrowsException() + { + Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, 0); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The indentation must be greater than zero + */ + public function testNegativeIndentationThrowsException() + { + Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, -4); + } +} diff --git a/vendor/symfony/yaml/phpunit.xml.dist b/vendor/symfony/yaml/phpunit.xml.dist index 6bdbea16e..7c732f8a7 100644 --- a/vendor/symfony/yaml/phpunit.xml.dist +++ b/vendor/symfony/yaml/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/twig/twig/.editorconfig b/vendor/twig/twig/.editorconfig new file mode 100644 index 000000000..270f1d1b7 --- /dev/null +++ b/vendor/twig/twig/.editorconfig @@ -0,0 +1,18 @@ +; top-most EditorConfig file +root = true + +; Unix-style newlines +[*] +end_of_line = LF + +[*.php] +indent_style = space +indent_size = 4 + +[*.test] +indent_style = space +indent_size = 4 + +[*.rst] +indent_style = space +indent_size = 4 diff --git a/vendor/twig/twig/.gitignore b/vendor/twig/twig/.gitignore new file mode 100644 index 000000000..31103621c --- /dev/null +++ b/vendor/twig/twig/.gitignore @@ -0,0 +1,5 @@ +/build +/composer.lock +/ext/twig/autom4te.cache/ +/phpunit.xml +/vendor diff --git a/vendor/twig/twig/.php_cs.dist b/vendor/twig/twig/.php_cs.dist new file mode 100644 index 000000000..cd75923a1 --- /dev/null +++ b/vendor/twig/twig/.php_cs.dist @@ -0,0 +1,15 @@ +setRules(array( + '@Symfony' => true, + '@Symfony:risky' => true, + 'array_syntax' => array('syntax' => 'long'), + 'php_unit_fqcn_annotation' => false, + 'no_unreachable_default_argument_value' => false, + 'braces' => array('allow_single_line_closure' => true), + 'heredoc_to_nowdoc' => false, + )) + ->setRiskyAllowed(true) + ->setFinder(PhpCsFixer\Finder::create()->in(__DIR__)) +; diff --git a/vendor/twig/twig/.travis.yml b/vendor/twig/twig/.travis.yml new file mode 100644 index 000000000..c479e324b --- /dev/null +++ b/vendor/twig/twig/.travis.yml @@ -0,0 +1,48 @@ +language: php + +sudo: false + +cache: + directories: + - vendor + - $HOME/.composer/cache/files + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - nightly + +env: + - TWIG_EXT=no + - TWIG_EXT=yes + +before_install: + - phpenv config-rm xdebug.ini + +install: + - travis_retry composer install + +before_script: + - if [ "$TWIG_EXT" == "yes" ]; then sh -c "cd ext/twig && phpize && ./configure --enable-twig && make && make install"; fi + - if [ "$TWIG_EXT" == "yes" ]; then echo "extension=twig.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi + +script: | + if [[ $TRAVIS_PHP_VERSION = 7.* || $TRAVIS_PHP_VERSION = nightly ]]; then + SYMFONY_PHPUNIT_VERSION=6.1 ./vendor/bin/simple-phpunit + else + ./vendor/bin/simple-phpunit + fi + +matrix: + fast_finish: true + exclude: + - php: 7.0 + env: TWIG_EXT=yes + - php: 7.1 + env: TWIG_EXT=yes + - php: nightly + env: TWIG_EXT=yes diff --git a/vendor/twig/twig/CHANGELOG b/vendor/twig/twig/CHANGELOG new file mode 100644 index 000000000..23bb3c70a --- /dev/null +++ b/vendor/twig/twig/CHANGELOG @@ -0,0 +1,972 @@ +* 1.34.3 (2017-06-07) + + * fixed namespaces introduction + +* 1.34.2 (2017-06-05) + + * fixed namespaces introduction + +* 1.34.1 (2017-06-05) + + * fixed namespaces introduction + +* 1.34.0 (2017-06-05) + + * added support for PHPUnit 6 when testing extensions + * fixed PHP 7.2 compatibility + * fixed template name generation in Twig_Environment::createTemplate() + * removed final tag on Twig_TokenParser_Include + * added namespaced aliases for all (non-deprecated) classes and interfaces + * dropped HHVM support + * dropped PHP 5.2 support + +* 1.33.2 (2017-04-20) + + * fixed edge case in the method cache for Twig attributes + +* 1.33.1 (2017-04-18) + + * fixed the empty() test + +* 1.33.0 (2017-03-22) + + * fixed a race condition handling when writing cache files + * "length" filter now returns string length when applied to an object that does + not implement \Countable but provides __toString() + * "empty" test will now consider the return value of the __toString() method for + objects implement __toString() but not \Countable + * fixed JS escaping for unicode characters with higher code points + +* 1.32.0 (2017-02-26) + + * fixed deprecation notice in Twig_Util_DeprecationCollector + * added a PSR-11 compatible runtime loader + * added `side` argument to `trim` to allow left or right trimming only. + +* 1.31.0 (2017-01-11) + + * added Twig_NodeCaptureInterface for nodes that capture all output + * fixed marking the environment as initialized too early + * fixed C89 compat for the C extension + * turned fatal error into exception when a previously generated cache is corrupted + * fixed offline cache warm-ups for embedded templates + +* 1.30.0 (2016-12-23) + + * added Twig_FactoryRuntimeLoader + * deprecated function/test/filter/tag overriding + * deprecated the "disable_c_ext" attribute on Twig_Node_Expression_GetAttr + +* 1.29.0 (2016-12-13) + + * fixed sandbox being left enabled if an exception is thrown while rendering + * marked some classes as being final (via @final) + * made Twig_Error report real source path when possible + * added support for {{ _self }} to provide an upgrade path from 1.x to 2.0 (replaces {{ _self.templateName }}) + * deprecated silent display of undefined blocks + * deprecated support for mbstring.func_overload != 0 + +* 1.28.2 (2016-11-23) + + * fixed precedence between getFoo() and isFoo() in Twig_Template::getAttribute() + * improved a deprecation message + +* 1.28.1 (2016-11-18) + + * fixed block() function when used with a template argument + +* 1.28.0 (2016-11-17) + + * added support for the PHP 7 null coalescing operator for the ?? Twig implementation + * exposed a way to access template data and methods in a portable way + * changed context access to use the PHP 7 null coalescing operator when available + * added the "with" tag + * added support for a custom template on the block() function + * added "is defined" support for block() and constant() + * optimized the way attributes are fetched + +* 1.27.0 (2016-10-25) + + * deprecated Twig_Parser::getEnvironment() + * deprecated Twig_Parser::addHandler() and Twig_Parser::addNodeVisitor() + * deprecated Twig_Compiler::addIndentation() + * fixed regression when registering two extensions having the same class name + * deprecated Twig_LoaderInterface::getSource() (implement Twig_SourceContextLoaderInterface instead) + * fixed the filesystem loader with relative paths + * deprecated Twig_Node::getLine() in favor of Twig_Node::getTemplateLine() + * deprecated Twig_Template::getSource() in favor of Twig_Template::getSourceContext() + * deprecated Twig_Node::getFilename() in favor of Twig_Node::getTemplateName() + * deprecated the "filename" escaping strategy (use "name" instead) + * added Twig_Source to hold information about the original template + * deprecated Twig_Error::getTemplateFile() and Twig_Error::setTemplateFile() in favor of Twig_Error::getTemplateName() and Twig_Error::setTemplateName() + * deprecated Parser::getFilename() + * fixed template paths when a template name contains a protocol like vfs:// + * improved debugging with Twig_Sandbox_SecurityError exceptions for disallowed methods and properties + +* 1.26.1 (2016-10-05) + + * removed template source code from generated template classes when debug is disabled + * fixed default implementation of Twig_Template::getDebugInfo() for better BC + * fixed regression on static calls for functions/filters/tests + +* 1.26.0 (2016-10-02) + + * added template cache invalidation based on more environment options + * added a missing deprecation notice + * fixed template paths when a template is stored in a PHAR file + * allowed filters/functions/tests implementation to use a different class than the extension they belong to + * deprecated Twig_ExtensionInterface::getName() + +* 1.25.0 (2016-09-21) + + * changed the way we store template source in template classes + * removed usage of realpath in cache keys + * fixed Twig cache sharing when used with different versions of PHP + * removed embed parent workaround for simple use cases + * deprecated the ability to store non Node instances in Node::$nodes + * deprecated Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler() + * deprecated Twig_Compiler::getFilename() + +* 1.24.2 (2016-09-01) + + * fixed static callables + * fixed a potential PHP warning when loading the cache + * fixed a case where the autoescaping does not work as expected + +* 1.24.1 (2016-05-30) + + * fixed reserved keywords (forbids true, false, null and none keywords for variables names) + * fixed support for PHP7 (Throwable support) + * marked the following methods as being internals on Twig_Environment: + getFunctions(), getFilters(), getTests(), getFunction(), getFilter(), getTest(), + getTokenParsers(), getTags(), getNodeVisitors(), getUnaryOperators(), getBinaryOperators(), + getFunctions(), getFilters(), getGlobals(), initGlobals(), initExtensions(), and initExtension() + +* 1.24.0 (2016-01-25) + + * adding support for the ?? operator + * fixed the defined test when used on a constant, a map, or a sequence + * undeprecated _self (should only be used to get the template name, not the template instance) + * fixed parsing on PHP7 + +* 1.23.3 (2016-01-11) + + * fixed typo + +* 1.23.2 (2015-01-11) + + * added versions in deprecated messages + * made file cache tolerant for trailing (back)slashes on directory configuration + * deprecated unused Twig_Node_Expression_ExtensionReference class + +* 1.23.1 (2015-11-05) + + * fixed some exception messages which triggered PHP warnings + * fixed BC on Twig_Test_NodeTestCase + +* 1.23.0 (2015-10-29) + + * deprecated the possibility to override an extension by registering another one with the same name + * deprecated Twig_ExtensionInterface::getGlobals() (added Twig_Extension_GlobalsInterface for BC) + * deprecated Twig_ExtensionInterface::initRuntime() (added Twig_Extension_InitRuntimeInterface for BC) + * deprecated Twig_Environment::computeAlternatives() + +* 1.22.3 (2015-10-13) + + * fixed regression when using null as a cache strategy + * improved performance when checking template freshness + * fixed warnings when loaded templates do not exist + * fixed template class name generation to prevent possible collisions + * fixed logic for custom escapers to call them even on integers and null values + * changed template cache names to take into account the Twig C extension + +* 1.22.2 (2015-09-22) + + * fixed a race condition in template loading + +* 1.22.1 (2015-09-15) + + * fixed regression in template_from_string + +* 1.22.0 (2015-09-13) + + * made Twig_Test_IntegrationTestCase more flexible + * added an option to force PHP bytecode invalidation when writing a compiled template into the cache + * fixed the profiler duration for the root node + * changed template cache names to take into account enabled extensions + * deprecated Twig_Environment::clearCacheFiles(), Twig_Environment::getCacheFilename(), + Twig_Environment::writeCacheFile(), and Twig_Environment::getTemplateClassPrefix() + * added a way to override the filesystem template cache system + * added a way to get the original template source from Twig_Template + +* 1.21.2 (2015-09-09) + + * fixed variable names for the deprecation triggering code + * fixed escaping strategy detection based on filename + * added Traversable support for replace, merge, and sort + * deprecated support for character by character replacement for the "replace" filter + +* 1.21.1 (2015-08-26) + + * fixed regression when using the deprecated Twig_Test_* classes + +* 1.21.0 (2015-08-24) + + * added deprecation notices for deprecated features + * added a deprecation "framework" for filters/functions/tests and test fixtures + +* 1.20.0 (2015-08-12) + + * forbid access to the Twig environment from templates and internal parts of Twig_Template + * fixed limited RCEs when in sandbox mode + * deprecated Twig_Template::getEnvironment() + * deprecated the _self variable for usage outside of the from and import tags + * added Twig_BaseNodeVisitor to ease the compatibility of node visitors + between 1.x and 2.x + +* 1.19.0 (2015-07-31) + + * fixed wrong error message when including an undefined template in a child template + * added support for variadic filters, functions, and tests + * added support for extra positional arguments in macros + * added ignore_missing flag to the source function + * fixed batch filter with zero items + * deprecated Twig_Environment::clearTemplateCache() + * fixed sandbox disabling when using the include function + +* 1.18.2 (2015-06-06) + + * fixed template/line guessing in exceptions for nested templates + * optimized the number of inodes and the size of realpath cache when using the cache + +* 1.18.1 (2015-04-19) + + * fixed memory leaks in the C extension + * deprecated Twig_Loader_String + * fixed the slice filter when used with a SimpleXMLElement object + * fixed filesystem loader when trying to load non-files (like directories) + +* 1.18.0 (2015-01-25) + + * fixed some error messages where the line was wrong (unknown variables or argument names) + * added a new way to customize the main Module node (via empty nodes) + * added Twig_Environment::createTemplate() to create a template from a string + * added a profiler + * fixed filesystem loader cache when different file paths are used for the same template + +* 1.17.0 (2015-01-14) + + * added a 'filename' autoescaping strategy, which dynamically chooses the + autoescaping strategy for a template based on template file extension. + +* 1.16.3 (2014-12-25) + + * fixed regression for dynamic parent templates + * fixed cache management with statcache + * fixed a regression in the slice filter + +* 1.16.2 (2014-10-17) + + * fixed timezone on dates as strings + * fixed 2-words test names when a custom node class is not used + * fixed macros when using an argument named like a PHP super global (like GET or POST) + * fixed date_modify when working with DateTimeImmutable + * optimized for loops + * fixed multi-byte characters handling in the split filter + * fixed a regression in the in operator + * fixed a regression in the slice filter + +* 1.16.1 (2014-10-10) + + * improved error reporting in a sandboxed template + * fixed missing error file/line information under certain circumstances + * fixed wrong error line number in some error messages + * fixed the in operator to use strict comparisons + * sped up the slice filter + * fixed for mb function overload mb_substr acting different + * fixed the attribute() function when passing a variable for the arguments + +* 1.16.0 (2014-07-05) + + * changed url_encode to always encode according to RFC 3986 + * fixed inheritance in a 'use'-hierarchy + * removed the __toString policy check when the sandbox is disabled + * fixed recursively calling blocks in templates with inheritance + +* 1.15.1 (2014-02-13) + + * fixed the conversion of the special '0000-00-00 00:00' date + * added an error message when trying to import an undefined block from a trait + * fixed a C extension crash when accessing defined but uninitialized property. + +* 1.15.0 (2013-12-06) + + * made ignoreStrictCheck in Template::getAttribute() works with __call() methods throwing BadMethodCallException + * added min and max functions + * added the round filter + * fixed a bug that prevented the optimizers to be enabled/disabled selectively + * fixed first and last filters for UTF-8 strings + * added a source function to include the content of a template without rendering it + * fixed the C extension sandbox behavior when get or set is prepend to method name + +* 1.14.2 (2013-10-30) + + * fixed error filename/line when an error occurs in an included file + * allowed operators that contain whitespaces to have more than one whitespace + * allowed tests to be made of 1 or 2 words (like "same as" or "divisible by") + +* 1.14.1 (2013-10-15) + + * made it possible to use named operators as variables + * fixed the possibility to have a variable named 'matches' + * added support for PHP 5.5 DateTimeInterface + +* 1.14.0 (2013-10-03) + + * fixed usage of the html_attr escaping strategy to avoid double-escaping with the html strategy + * added new operators: ends with, starts with, and matches + * fixed some compatibility issues with HHVM + * added a way to add custom escaping strategies + * fixed the C extension compilation on Windows + * fixed the batch filter when using a fill argument with an exact match of elements to batch + * fixed the filesystem loader cache when a template name exists in several namespaces + * fixed template_from_string when the template includes or extends other ones + * fixed a crash of the C extension on an edge case + +* 1.13.2 (2013-08-03) + + * fixed the error line number for an error occurs in and embedded template + * fixed crashes of the C extension on some edge cases + +* 1.13.1 (2013-06-06) + + * added the possibility to ignore the filesystem constructor argument in Twig_Loader_Filesystem + * fixed Twig_Loader_Chain::exists() for a loader which implements Twig_ExistsLoaderInterface + * adjusted backtrace call to reduce memory usage when an error occurs + * added support for object instances as the second argument of the constant test + * fixed the include function when used in an assignment + +* 1.13.0 (2013-05-10) + + * fixed getting a numeric-like item on a variable ('09' for instance) + * fixed getting a boolean or float key on an array, so it is consistent with PHP's array access: + `{{ array[false] }}` behaves the same as `echo $array[false];` (equals `$array[0]`) + * made the escape filter 20% faster for happy path (escaping string for html with UTF-8) + * changed ☃ to § in tests + * enforced usage of named arguments after positional ones + +* 1.12.3 (2013-04-08) + + * fixed a security issue in the filesystem loader where it was possible to include a template one + level above the configured path + * fixed fatal error that should be an exception when adding a filter/function/test too late + * added a batch filter + * added support for encoding an array as query string in the url_encode filter + +* 1.12.2 (2013-02-09) + + * fixed the timezone used by the date filter and function when the given date contains a timezone (like 2010-01-28T15:00:00+02:00) + * fixed globals when getGlobals is called early on + * added the first and last filter + +* 1.12.1 (2013-01-15) + + * added support for object instances as the second argument of the constant function + * relaxed globals management to avoid a BC break + * added support for {{ some_string[:2] }} + +* 1.12.0 (2013-01-08) + + * added verbatim as an alias for the raw tag to avoid confusion with the raw filter + * fixed registration of tests and functions as anonymous functions + * fixed globals management + +* 1.12.0-RC1 (2012-12-29) + + * added an include function (does the same as the include tag but in a more flexible way) + * added the ability to use any PHP callable to define filters, functions, and tests + * added a syntax error when using a loop variable that is not defined + * added the ability to set default values for macro arguments + * added support for named arguments for filters, tests, and functions + * moved filters/functions/tests syntax errors to the parser + * added support for extended ternary operator syntaxes + +* 1.11.1 (2012-11-11) + + * fixed debug info line numbering (was off by 2) + * fixed escaping when calling a macro inside another one (regression introduced in 1.9.1) + * optimized variable access on PHP 5.4 + * fixed a crash of the C extension when an exception was thrown from a macro called without being imported (using _self.XXX) + +* 1.11.0 (2012-11-07) + + * fixed macro compilation when a variable name is a PHP reserved keyword + * changed the date filter behavior to always apply the default timezone, except if false is passed as the timezone + * fixed bitwise operator precedences + * added the template_from_string function + * fixed default timezone usage for the date function + * optimized the way Twig exceptions are managed (to make them faster) + * added Twig_ExistsLoaderInterface (implementing this interface in your loader make the chain loader much faster) + +* 1.10.3 (2012-10-19) + + * fixed wrong template location in some error messages + * reverted a BC break introduced in 1.10.2 + * added a split filter + +* 1.10.2 (2012-10-15) + + * fixed macro calls on PHP 5.4 + +* 1.10.1 (2012-10-15) + + * made a speed optimization to macro calls when imported via the "import" tag + * fixed C extension compilation on Windows + * fixed a segfault in the C extension when using DateTime objects + +* 1.10.0 (2012-09-28) + + * extracted functional tests framework to make it reusable for third-party extensions + * added namespaced templates support in Twig_Loader_Filesystem + * added Twig_Loader_Filesystem::prependPath() + * fixed an error when a token parser pass a closure as a test to the subparse() method + +* 1.9.2 (2012-08-25) + + * fixed the in operator for objects that contain circular references + * fixed the C extension when accessing a public property of an object implementing the \ArrayAccess interface + +* 1.9.1 (2012-07-22) + + * optimized macro calls when auto-escaping is on + * fixed wrong parent class for Twig_Function_Node + * made Twig_Loader_Chain more explicit about problems + +* 1.9.0 (2012-07-13) + + * made the parsing independent of the template loaders + * fixed exception trace when an error occurs when rendering a child template + * added escaping strategies for CSS, URL, and HTML attributes + * fixed nested embed tag calls + * added the date_modify filter + +* 1.8.3 (2012-06-17) + + * fixed paths in the filesystem loader when passing a path that ends with a slash or a backslash + * fixed escaping when a project defines a function named html or js + * fixed chmod mode to apply the umask correctly + +* 1.8.2 (2012-05-30) + + * added the abs filter + * fixed a regression when using a number in template attributes + * fixed compiler when mbstring.func_overload is set to 2 + * fixed DateTimeZone support in date filter + +* 1.8.1 (2012-05-17) + + * fixed a regression when dealing with SimpleXMLElement instances in templates + * fixed "is_safe" value for the "dump" function when "html_errors" is not defined in php.ini + * switched to use mbstring whenever possible instead of iconv (you might need to update your encoding as mbstring and iconv encoding names sometimes differ) + +* 1.8.0 (2012-05-08) + + * enforced interface when adding tests, filters, functions, and node visitors from extensions + * fixed a side-effect of the date filter where the timezone might be changed + * simplified usage of the autoescape tag; the only (optional) argument is now the escaping strategy or false (with a BC layer) + * added a way to dynamically change the auto-escaping strategy according to the template "filename" + * changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html) + * added an embed tag + +* 1.7.0 (2012-04-24) + + * fixed a PHP warning when using CIFS + * fixed template line number in some exceptions + * added an iterable test + * added an error when defining two blocks with the same name in a template + * added the preserves_safety option for filters + * fixed a PHP notice when trying to access a key on a non-object/array variable + * enhanced error reporting when the template file is an instance of SplFileInfo + * added Twig_Environment::mergeGlobals() + * added compilation checks to avoid misuses of the sandbox tag + * fixed filesystem loader freshness logic for high traffic websites + * fixed random function when charset is null + +* 1.6.5 (2012-04-11) + + * fixed a regression when a template only extends another one without defining any blocks + +* 1.6.4 (2012-04-02) + + * fixed PHP notice in Twig_Error::guessTemplateLine() introduced in 1.6.3 + * fixed performance when compiling large files + * optimized parent template creation when the template does not use dynamic inheritance + +* 1.6.3 (2012-03-22) + + * fixed usage of Z_ADDREF_P for PHP 5.2 in the C extension + * fixed compilation of numeric values used in templates when using a locale where the decimal separator is not a dot + * made the strategy used to guess the real template file name and line number in exception messages much faster and more accurate + +* 1.6.2 (2012-03-18) + + * fixed sandbox mode when used with inheritance + * added preserveKeys support for the slice filter + * fixed the date filter when a DateTime instance is passed with a specific timezone + * added a trim filter + +* 1.6.1 (2012-02-29) + + * fixed Twig C extension + * removed the creation of Twig_Markup instances when not needed + * added a way to set the default global timezone for dates + * fixed the slice filter on strings when the length is not specified + * fixed the creation of the cache directory in case of a race condition + +* 1.6.0 (2012-02-04) + + * fixed raw blocks when used with the whitespace trim option + * made a speed optimization to macro calls when imported via the "from" tag + * fixed globals, parsers, visitors, filters, tests, and functions management in Twig_Environment when a new one or new extension is added + * fixed the attribute function when passing arguments + * added slice notation support for the [] operator (syntactic sugar for the slice operator) + * added a slice filter + * added string support for the reverse filter + * fixed the empty test and the length filter for Twig_Markup instances + * added a date function to ease date comparison + * fixed unary operators precedence + * added recursive parsing support in the parser + * added string and integer handling for the random function + +* 1.5.1 (2012-01-05) + + * fixed a regression when parsing strings + +* 1.5.0 (2012-01-04) + + * added Traversable objects support for the join filter + +* 1.5.0-RC2 (2011-12-30) + + * added a way to set the default global date interval format + * fixed the date filter for DateInterval instances (setTimezone() does not exist for them) + * refactored Twig_Template::display() to ease its extension + * added a number_format filter + +* 1.5.0-RC1 (2011-12-26) + + * removed the need to quote hash keys + * allowed hash keys to be any expression + * added a do tag + * added a flush tag + * added support for dynamically named filters and functions + * added a dump function to help debugging templates + * added a nl2br filter + * added a random function + * added a way to change the default format for the date filter + * fixed the lexer when an operator ending with a letter ends a line + * added string interpolation support + * enhanced exceptions for unknown filters, functions, tests, and tags + +* 1.4.0 (2011-12-07) + + * fixed lexer when using big numbers (> PHP_INT_MAX) + * added missing preserveKeys argument to the reverse filter + * fixed macros containing filter tag calls + +* 1.4.0-RC2 (2011-11-27) + + * removed usage of Reflection in Twig_Template::getAttribute() + * added a C extension that can optionally replace Twig_Template::getAttribute() + * added negative timestamp support to the date filter + +* 1.4.0-RC1 (2011-11-20) + + * optimized variable access when using PHP 5.4 + * changed the precedence of the .. operator to be more consistent with languages that implements such a feature like Ruby + * added an Exception to Twig_Loader_Array::isFresh() method when the template does not exist to be consistent with other loaders + * added Twig_Function_Node to allow more complex functions to have their own Node class + * added Twig_Filter_Node to allow more complex filters to have their own Node class + * added Twig_Test_Node to allow more complex tests to have their own Node class + * added a better error message when a template is empty but contain a BOM + * fixed "in" operator for empty strings + * fixed the "defined" test and the "default" filter (now works with more than one call (foo.bar.foo) and for both values of the strict_variables option) + * changed the way extensions are loaded (addFilter/addFunction/addGlobal/addTest/addNodeVisitor/addTokenParser/addExtension can now be called in any order) + * added Twig_Environment::display() + * made the escape filter smarter when the encoding is not supported by PHP + * added a convert_encoding filter + * moved all node manipulations outside the compile() Node method + * made several speed optimizations + +* 1.3.0 (2011-10-08) + +no changes + +* 1.3.0-RC1 (2011-10-04) + + * added an optimization for the parent() function + * added cache reloading when auto_reload is true and an extension has been modified + * added the possibility to force the escaping of a string already marked as safe (instance of Twig_Markup) + * allowed empty templates to be used as traits + * added traits support for the "parent" function + +* 1.2.0 (2011-09-13) + +no changes + +* 1.2.0-RC1 (2011-09-10) + + * enhanced the exception when a tag remains unclosed + * added support for empty Countable objects for the "empty" test + * fixed algorithm that determines if a template using inheritance is valid (no output between block definitions) + * added better support for encoding problems when escaping a string (available as of PHP 5.4) + * added a way to ignore a missing template when using the "include" tag ({% include "foo" ignore missing %}) + * added support for an array of templates to the "include" and "extends" tags ({% include ['foo', 'bar'] %}) + * added support for bitwise operators in expressions + * added the "attribute" function to allow getting dynamic attributes on variables + * added Twig_Loader_Chain + * added Twig_Loader_Array::setTemplate() + * added an optimization for the set tag when used to capture a large chunk of static text + * changed name regex to match PHP one "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" (works for blocks, tags, functions, filters, and macros) + * removed the possibility to use the "extends" tag from a block + * added "if" modifier support to "for" loops + +* 1.1.2 (2011-07-30) + + * fixed json_encode filter on PHP 5.2 + * fixed regression introduced in 1.1.1 ({{ block(foo|lower) }}) + * fixed inheritance when using conditional parents + * fixed compilation of templates when the body of a child template is not empty + * fixed output when a macro throws an exception + * fixed a parsing problem when a large chunk of text is enclosed in a comment tag + * added PHPDoc for all Token parsers and Core extension functions + +* 1.1.1 (2011-07-17) + + * added a performance optimization in the Optimizer (also helps to lower the number of nested level calls) + * made some performance improvement for some edge cases + +* 1.1.0 (2011-06-28) + + * fixed json_encode filter + +* 1.1.0-RC3 (2011-06-24) + + * fixed method case-sensitivity when using the sandbox mode + * added timezone support for the date filter + * fixed possible security problems with NUL bytes + +* 1.1.0-RC2 (2011-06-16) + + * added an exception when the template passed to "use" is not a string + * made 'a.b is defined' not throw an exception if a is not defined (in strict mode) + * added {% line \d+ %} directive + +* 1.1.0-RC1 (2011-05-28) + +Flush your cache after upgrading. + + * fixed date filter when using a timestamp + * fixed the defined test for some cases + * fixed a parsing problem when a large chunk of text is enclosed in a raw tag + * added support for horizontal reuse of template blocks (see docs for more information) + * added whitespace control modifier to all tags (see docs for more information) + * added null as an alias for none (the null test is also an alias for the none test now) + * made TRUE, FALSE, NONE equivalent to their lowercase counterparts + * wrapped all compilation and runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line + * moved display() method to Twig_Template (generated templates should now use doDisplay() instead) + +* 1.0.0 (2011-03-27) + + * fixed output when using mbstring + * fixed duplicate call of methods when using the sandbox + * made the charset configurable for the escape filter + +* 1.0.0-RC2 (2011-02-21) + + * changed the way {% set %} works when capturing (the content is now marked as safe) + * added support for macro name in the endmacro tag + * make Twig_Error compatible with PHP 5.3.0 > + * fixed an infinite loop on some Windows configurations + * fixed the "length" filter for numbers + * fixed Template::getAttribute() as properties in PHP are case sensitive + * removed coupling between Twig_Node and Twig_Template + * fixed the ternary operator precedence rule + +* 1.0.0-RC1 (2011-01-09) + +Backward incompatibilities: + + * the "items" filter, which has been deprecated for quite a long time now, has been removed + * the "range" filter has been converted to a function: 0|range(10) -> range(0, 10) + * the "constant" filter has been converted to a function: {{ some_date|date('DATE_W3C'|constant) }} -> {{ some_date|date(constant('DATE_W3C')) }} + * the "cycle" filter has been converted to a function: {{ ['odd', 'even']|cycle(i) }} -> {{ cycle(['odd', 'even'], i) }} + * the "for" tag does not support "joined by" anymore + * the "autoescape" first argument is now "true"/"false" (instead of "on"/"off") + * the "parent" tag has been replaced by a "parent" function ({{ parent() }} instead of {% parent %}) + * the "display" tag has been replaced by a "block" function ({{ block('title') }} instead of {% display title %}) + * removed the grammar and simple token parser (moved to the Twig Extensions repository) + +Changes: + + * added "needs_context" option for filters and functions (the context is then passed as a first argument) + * added global variables support + * made macros return their value instead of echoing directly (fixes calling a macro in sandbox mode) + * added the "from" tag to import macros as functions + * added support for functions (a function is just syntactic sugar for a getAttribute() call) + * made macros callable when sandbox mode is enabled + * added an exception when a macro uses a reserved name + * the "default" filter now uses the "empty" test instead of just checking for null + * added the "empty" test + +* 0.9.10 (2010-12-16) + +Backward incompatibilities: + + * The Escaper extension is enabled by default, which means that all displayed + variables are now automatically escaped. You can revert to the previous + behavior by removing the extension via $env->removeExtension('escaper') + or just set the 'autoescape' option to 'false'. + * removed the "without loop" attribute for the "for" tag (not needed anymore + as the Optimizer take care of that for most cases) + * arrays and hashes have now a different syntax + * arrays keep the same syntax with square brackets: [1, 2] + * hashes now use curly braces (["a": "b"] should now be written as {"a": "b"}) + * support for "arrays with keys" and "hashes without keys" is not supported anymore ([1, "foo": "bar"] or {"foo": "bar", 1}) + * the i18n extension is now part of the Twig Extensions repository + +Changes: + + * added the merge filter + * removed 'is_escaper' option for filters (a left over from the previous version) -- you must use 'is_safe' now instead + * fixed usage of operators as method names (like is, in, and not) + * changed the order of execution for node visitors + * fixed default() filter behavior when used with strict_variables set to on + * fixed filesystem loader compatibility with PHAR files + * enhanced error messages when an unexpected token is parsed in an expression + * fixed filename not being added to syntax error messages + * added the autoescape option to enable/disable autoescaping + * removed the newline after a comment (mimics PHP behavior) + * added a syntax error exception when parent block is used on a template that does not extend another one + * made the Escaper extension enabled by default + * fixed sandbox extension when used with auto output escaping + * fixed escaper when wrapping a Twig_Node_Print (the original class must be preserved) + * added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters) + * added priority to node visitors + +* 0.9.9 (2010-11-28) + +Backward incompatibilities: + * the self special variable has been renamed to _self + * the odd and even filters are now tests: + {{ foo|odd }} must now be written {{ foo is odd }} + * the "safe" filter has been renamed to "raw" + * in Node classes, + sub-nodes are now accessed via getNode() (instead of property access) + attributes via getAttribute() (instead of array access) + * the urlencode filter had been renamed to url_encode + * the include tag now merges the passed variables with the current context by default + (the old behavior is still possible by adding the "only" keyword) + * moved Exceptions to Twig_Error_* (Twig_SyntaxError/Twig_RuntimeError are now Twig_Error_Syntax/Twig_Error_Runtime) + * removed support for {{ 1 < i < 3 }} (use {{ i > 1 and i < 3 }} instead) + * the "in" filter has been removed ({{ a|in(b) }} should now be written {{ a in b }}) + +Changes: + * added file and line to Twig_Error_Runtime exceptions thrown from Twig_Template + * changed trans tag to accept any variable for the plural count + * fixed sandbox mode (__toString() method check was not enforced if called implicitly from complex statements) + * added the ** (power) operator + * changed the algorithm used for parsing expressions + * added the spaceless tag + * removed trim_blocks option + * added support for is*() methods for attributes (foo.bar now looks for foo->getBar() or foo->isBar()) + * changed all exceptions to extend Twig_Error + * fixed unary expressions ({{ not(1 or 0) }}) + * fixed child templates (with an extend tag) that uses one or more imports + * added support for {{ 1 not in [2, 3] }} (more readable than the current {{ not (1 in [2, 3]) }}) + * escaping has been rewritten + * the implementation of template inheritance has been rewritten + (blocks can now be called individually and still work with inheritance) + * fixed error handling for if tag when a syntax error occurs within a subparse process + * added a way to implement custom logic for resolving token parsers given a tag name + * fixed js escaper to be stricter (now uses a whilelist-based js escaper) + * added the following filers: "constant", "trans", "replace", "json_encode" + * added a "constant" test + * fixed objects with __toString() not being autoescaped + * fixed subscript expressions when calling __call() (methods now keep the case) + * added "test" feature (accessible via the "is" operator) + * removed the debug tag (should be done in an extension) + * fixed trans tag when no vars are used in plural form + * fixed race condition when writing template cache + * added the special _charset variable to reference the current charset + * added the special _context variable to reference the current context + * renamed self to _self (to avoid conflict) + * fixed Twig_Template::getAttribute() for protected properties + +* 0.9.8 (2010-06-28) + +Backward incompatibilities: + * the trans tag plural count is now attached to the plural tag: + old: `{% trans count %}...{% plural %}...{% endtrans %}` + new: `{% trans %}...{% plural count %}...{% endtrans %}` + + * added a way to translate strings coming from a variable ({% trans var %}) + * fixed trans tag when used with the Escaper extension + * fixed default cache umask + * removed Twig_Template instances from the debug tag output + * fixed objects with __isset() defined + * fixed set tag when used with a capture + * fixed type hinting for Twig_Environment::addFilter() method + +* 0.9.7 (2010-06-12) + +Backward incompatibilities: + * changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %}) + * removed the sandboxed attribute of the include tag (use the new sandbox tag instead) + * refactored the Node system (if you have custom nodes, you will have to update them to use the new API) + + * added self as a special variable that refers to the current template (useful for importing macros from the current template) + * added Twig_Template instance support to the include tag + * added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %}) + * added a grammar sub-framework to ease the creation of custom tags + * fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface) + * removed the Twig_Resource::resolveMissingFilter() method + * fixed the filter tag which did not apply filtering to included files + * added a bunch of unit tests + * added a bunch of phpdoc + * added a sandbox tag in the sandbox extension + * changed the date filter to support any date format supported by DateTime + * added strict_variable setting to throw an exception when an invalid variable is used in a template (disabled by default) + * added the lexer, parser, and compiler as arguments to the Twig_Environment constructor + * changed the cache option to only accepts an explicit path to a cache directory or false + * added a way to add token parsers, filters, and visitors without creating an extension + * added three interfaces: Twig_NodeInterface, Twig_TokenParserInterface, and Twig_FilterInterface + * changed the generated code to match the new coding standards + * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }}) + * added an exception when a child template has a non-empty body (as it is always ignored when rendering) + +* 0.9.6 (2010-05-12) + + * fixed variables defined outside a loop and for which the value changes in a for loop + * fixed the test suite for PHP 5.2 and older versions of PHPUnit + * added support for __call() in expression resolution + * fixed node visiting for macros (macros are now visited by visitors as any other node) + * fixed nested block definitions with a parent call (rarely useful but nonetheless supported now) + * added the cycle filter + * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII + * added a long-syntax for the set tag ({% set foo %}...{% endset %}) + * unit tests are now powered by PHPUnit + * added support for gettext via the `i18n` extension + * fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values + * added a more useful exception if an if tag is not closed properly + * added support for escaping strategy in the autoescape tag + * fixed lexer when a template has a big chunk of text between/in a block + +* 0.9.5 (2010-01-20) + +As for any new release, don't forget to remove all cached templates after +upgrading. + +If you have defined custom filters, you MUST upgrade them for this release. To +upgrade, replace "array" with "new Twig_Filter_Function", and replace the +environment constant by the "needs_environment" option: + + // before + 'even' => array('twig_is_even_filter', false), + 'escape' => array('twig_escape_filter', true), + + // after + 'even' => new Twig_Filter_Function('twig_is_even_filter'), + 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)), + +If you have created NodeTransformer classes, you will need to upgrade them to +the new interface (please note that the interface is not yet considered +stable). + + * fixed list nodes that did not extend the Twig_NodeListInterface + * added the "without loop" option to the for tag (it disables the generation of the loop variable) + * refactored node transformers to node visitors + * fixed automatic-escaping for blocks + * added a way to specify variables to pass to an included template + * changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules) + * improved the filter system to allow object methods to be used as filters + * changed the Array and String loaders to actually make use of the cache mechanism + * included the default filter function definitions in the extension class files directly (Core, Escaper) + * added the // operator (like the floor() PHP function) + * added the .. operator (as a syntactic sugar for the range filter when the step is 1) + * added the in operator (as a syntactic sugar for the in filter) + * added the following filters in the Core extension: in, range + * added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes) + * enhanced some error messages to provide better feedback in case of parsing errors + +* 0.9.4 (2009-12-02) + +If you have custom loaders, you MUST upgrade them for this release: The +Twig_Loader base class has been removed, and the Twig_LoaderInterface has also +been changed (see the source code for more information or the documentation). + + * added support for DateTime instances for the date filter + * fixed loop.last when the array only has one item + * made it possible to insert newlines in tag and variable blocks + * fixed a bug when a literal '\n' were present in a template text + * fixed bug when the filename of a template contains */ + * refactored loaders + +* 0.9.3 (2009-11-11) + +This release is NOT backward compatible with the previous releases. + + The loaders do not take the cache and autoReload arguments anymore. Instead, + the Twig_Environment class has two new options: cache and auto_reload. + Upgrading your code means changing this kind of code: + + $loader = new Twig_Loader_Filesystem('/path/to/templates', '/path/to/compilation_cache', true); + $twig = new Twig_Environment($loader); + + to something like this: + + $loader = new Twig_Loader_Filesystem('/path/to/templates'); + $twig = new Twig_Environment($loader, array( + 'cache' => '/path/to/compilation_cache', + 'auto_reload' => true, + )); + + * deprecated the "items" filter as it is not needed anymore + * made cache and auto_reload options of Twig_Environment instead of arguments of Twig_Loader + * optimized template loading speed + * removed output when an error occurs in a template and render() is used + * made major speed improvements for loops (up to 300% on even the smallest loops) + * added properties as part of the sandbox mode + * added public properties support (obj.item can now be the item property on the obj object) + * extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} ) + * fixed bug when \ was used in HTML + +* 0.9.2 (2009-10-29) + + * made some speed optimizations + * changed the cache extension to .php + * added a js escaping strategy + * added support for short block tag + * changed the filter tag to allow chained filters + * made lexer more flexible as you can now change the default delimiters + * added set tag + * changed default directory permission when cache dir does not exist (more secure) + * added macro support + * changed filters first optional argument to be a Twig_Environment instance instead of a Twig_Template instance + * made Twig_Autoloader::autoload() a static method + * avoid writing template file if an error occurs + * added $ escaping when outputting raw strings + * enhanced some error messages to ease debugging + * fixed empty cache files when the template contains an error + +* 0.9.1 (2009-10-14) + + * fixed a bug in PHP 5.2.6 + * fixed numbers with one than one decimal + * added support for method calls with arguments ({{ foo.bar('a', 43) }}) + * made small speed optimizations + * made minor tweaks to allow better extensibility and flexibility + +* 0.9.0 (2009-10-12) + + * Initial release diff --git a/vendor/twig/twig/README.rst b/vendor/twig/twig/README.rst new file mode 100644 index 000000000..81737b0b2 --- /dev/null +++ b/vendor/twig/twig/README.rst @@ -0,0 +1,15 @@ +Twig, the flexible, fast, and secure template language for PHP +============================================================== + +Twig is a template language for PHP, released under the new BSD license (code +and documentation). + +Twig uses a syntax similar to the Django and Jinja template languages which +inspired the Twig runtime environment. + +More Information +---------------- + +Read the `documentation`_ for more information. + +.. _documentation: http://twig.sensiolabs.org/documentation diff --git a/vendor/twig/twig/composer.json b/vendor/twig/twig/composer.json index b89f14ca8..71ceed8d2 100644 --- a/vendor/twig/twig/composer.json +++ b/vendor/twig/twig/composer.json @@ -27,7 +27,7 @@ "forum": "https://groups.google.com/forum/#!forum/twig-users" }, "require": { - "php": ">=5.2.7" + "php": ">=5.3.3" }, "require-dev": { "symfony/phpunit-bridge": "~3.3@dev", @@ -37,11 +37,14 @@ "autoload": { "psr-0" : { "Twig_" : "lib/" + }, + "psr-4" : { + "Twig\\" : "src/" } }, "extra": { "branch-alias": { - "dev-master": "1.33-dev" + "dev-master": "1.34-dev" } } } diff --git a/vendor/twig/twig/doc/advanced.rst b/vendor/twig/twig/doc/advanced.rst new file mode 100644 index 000000000..d86db501e --- /dev/null +++ b/vendor/twig/twig/doc/advanced.rst @@ -0,0 +1,962 @@ +Extending Twig +============== + +.. caution:: + + This section describes how to extend Twig as of **Twig 1.12**. If you are + using an older version, read the :doc:`legacy` chapter + instead. + +Twig can be extended in many ways; you can add extra tags, filters, tests, +operators, global variables, and functions. You can even extend the parser +itself with node visitors. + +.. note:: + + The first section of this chapter describes how to extend Twig easily. If + you want to reuse your changes in different projects or if you want to + share them with others, you should then create an extension as described + in the following section. + +.. caution:: + + When extending Twig without creating an extension, Twig won't be able to + recompile your templates when the PHP code is updated. To see your changes + in real-time, either disable template caching or package your code into an + extension (see the next section of this chapter). + +Before extending Twig, you must understand the differences between all the +different possible extension points and when to use them. + +First, remember that Twig has two main language constructs: + +* ``{{ }}``: used to print the result of an expression evaluation; + +* ``{% %}``: used to execute statements. + +To understand why Twig exposes so many extension points, let's see how to +implement a *Lorem ipsum* generator (it needs to know the number of words to +generate). + +You can use a ``lipsum`` *tag*: + +.. code-block:: jinja + + {% lipsum 40 %} + +That works, but using a tag for ``lipsum`` is not a good idea for at least +three main reasons: + +* ``lipsum`` is not a language construct; +* The tag outputs something; +* The tag is not flexible as you cannot use it in an expression: + + .. code-block:: jinja + + {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }} + +In fact, you rarely need to create tags; and that's good news because tags are +the most complex extension point of Twig. + +Now, let's use a ``lipsum`` *filter*: + +.. code-block:: jinja + + {{ 40|lipsum }} + +Again, it works, but it looks weird. A filter transforms the passed value to +something else but here we use the value to indicate the number of words to +generate (so, ``40`` is an argument of the filter, not the value we want to +transform). + +Next, let's use a ``lipsum`` *function*: + +.. code-block:: jinja + + {{ lipsum(40) }} + +Here we go. For this specific example, the creation of a function is the +extension point to use. And you can use it anywhere an expression is accepted: + +.. code-block:: jinja + + {{ 'some text' ~ lipsum(40) ~ 'some more text' }} + + {% set lipsum = lipsum(40) %} + +Last but not the least, you can also use a *global* object with a method able +to generate lorem ipsum text: + +.. code-block:: jinja + + {{ text.lipsum(40) }} + +As a rule of thumb, use functions for frequently used features and global +objects for everything else. + +Keep in mind the following when you want to extend Twig: + +========== ========================== ========== ========================= +What? Implementation difficulty? How often? When? +========== ========================== ========== ========================= +*macro* trivial frequent Content generation +*global* trivial frequent Helper object +*function* trivial frequent Content generation +*filter* trivial frequent Value transformation +*tag* complex rare DSL language construct +*test* trivial rare Boolean decision +*operator* trivial rare Values transformation +========== ========================== ========== ========================= + +Globals +------- + +A global variable is like any other template variable, except that it's +available in all templates and macros:: + + $twig = new Twig_Environment($loader); + $twig->addGlobal('text', new Text()); + +You can then use the ``text`` variable anywhere in a template: + +.. code-block:: jinja + + {{ text.lipsum(40) }} + +Filters +------- + +Creating a filter is as simple as associating a name with a PHP callable:: + + // an anonymous function + $filter = new Twig_SimpleFilter('rot13', function ($string) { + return str_rot13($string); + }); + + // or a simple PHP function + $filter = new Twig_SimpleFilter('rot13', 'str_rot13'); + + // or a class static method + $filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter')); + $filter = new Twig_SimpleFilter('rot13', 'SomeClass::rot13Filter'); + + // or a class method + $filter = new Twig_SimpleFilter('rot13', array($this, 'rot13Filter')); + // the one below needs a runtime implementation (see below for more information) + $filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter')); + +The first argument passed to the ``Twig_SimpleFilter`` constructor is the name +of the filter you will use in templates and the second one is the PHP callable +to associate with it. + +Then, add the filter to your Twig environment:: + + $twig = new Twig_Environment($loader); + $twig->addFilter($filter); + +And here is how to use it in a template: + +.. code-block:: jinja + + {{ 'Twig'|rot13 }} + + {# will output Gjvt #} + +When called by Twig, the PHP callable receives the left side of the filter +(before the pipe ``|``) as the first argument and the extra arguments passed +to the filter (within parentheses ``()``) as extra arguments. + +For instance, the following code: + +.. code-block:: jinja + + {{ 'TWIG'|lower }} + {{ now|date('d/m/Y') }} + +is compiled to something like the following:: + + + + +The ``Twig_SimpleFilter`` class takes an array of options as its last +argument:: + + $filter = new Twig_SimpleFilter('rot13', 'str_rot13', $options); + +Environment-aware Filters +~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want to access the current environment instance in your filter, set the +``needs_environment`` option to ``true``; Twig will pass the current +environment as the first argument to the filter call:: + + $filter = new Twig_SimpleFilter('rot13', function (Twig_Environment $env, $string) { + // get the current charset for instance + $charset = $env->getCharset(); + + return str_rot13($string); + }, array('needs_environment' => true)); + +Context-aware Filters +~~~~~~~~~~~~~~~~~~~~~ + +If you want to access the current context in your filter, set the +``needs_context`` option to ``true``; Twig will pass the current context as +the first argument to the filter call (or the second one if +``needs_environment`` is also set to ``true``):: + + $filter = new Twig_SimpleFilter('rot13', function ($context, $string) { + // ... + }, array('needs_context' => true)); + + $filter = new Twig_SimpleFilter('rot13', function (Twig_Environment $env, $context, $string) { + // ... + }, array('needs_context' => true, 'needs_environment' => true)); + +Automatic Escaping +~~~~~~~~~~~~~~~~~~ + +If automatic escaping is enabled, the output of the filter may be escaped +before printing. If your filter acts as an escaper (or explicitly outputs HTML +or JavaScript code), you will want the raw output to be printed. In such a +case, set the ``is_safe`` option:: + + $filter = new Twig_SimpleFilter('nl2br', 'nl2br', array('is_safe' => array('html'))); + +Some filters may need to work on input that is already escaped or safe, for +example when adding (safe) HTML tags to originally unsafe output. In such a +case, set the ``pre_escape`` option to escape the input data before it is run +through your filter:: + + $filter = new Twig_SimpleFilter('somefilter', 'somefilter', array('pre_escape' => 'html', 'is_safe' => array('html'))); + +Variadic Filters +~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.19 + Support for variadic filters was added in Twig 1.19. + +When a filter should accept an arbitrary number of arguments, set the +``is_variadic`` option to ``true``; Twig will pass the extra arguments as the +last argument to the filter call as an array:: + + $filter = new Twig_SimpleFilter('thumbnail', function ($file, array $options = array()) { + // ... + }, array('is_variadic' => true)); + +Be warned that named arguments passed to a variadic filter cannot be checked +for validity as they will automatically end up in the option array. + +Dynamic Filters +~~~~~~~~~~~~~~~ + +A filter name containing the special ``*`` character is a dynamic filter as +the ``*`` can be any string:: + + $filter = new Twig_SimpleFilter('*_path', function ($name, $arguments) { + // ... + }); + +The following filters will be matched by the above defined dynamic filter: + +* ``product_path`` +* ``category_path`` + +A dynamic filter can define more than one dynamic parts:: + + $filter = new Twig_SimpleFilter('*_path_*', function ($name, $suffix, $arguments) { + // ... + }); + +The filter will receive all dynamic part values before the normal filter +arguments, but after the environment and the context. For instance, a call to +``'foo'|a_path_b()`` will result in the following arguments to be passed to +the filter: ``('a', 'b', 'foo')``. + +Deprecated Filters +~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.21 + Support for deprecated filters was added in Twig 1.21. + +You can mark a filter as being deprecated by setting the ``deprecated`` option +to ``true``. You can also give an alternative filter that replaces the +deprecated one when that makes sense:: + + $filter = new Twig_SimpleFilter('obsolete', function () { + // ... + }, array('deprecated' => true, 'alternative' => 'new_one')); + +When a filter is deprecated, Twig emits a deprecation notice when compiling a +template using it. See :ref:`deprecation-notices` for more information. + +Functions +--------- + +Functions are defined in the exact same way as filters, but you need to create +an instance of ``Twig_SimpleFunction``:: + + $twig = new Twig_Environment($loader); + $function = new Twig_SimpleFunction('function_name', function () { + // ... + }); + $twig->addFunction($function); + +Functions support the same features as filters, except for the ``pre_escape`` +and ``preserves_safety`` options. + +Tests +----- + +Tests are defined in the exact same way as filters and functions, but you need +to create an instance of ``Twig_SimpleTest``:: + + $twig = new Twig_Environment($loader); + $test = new Twig_SimpleTest('test_name', function () { + // ... + }); + $twig->addTest($test); + +Tests allow you to create custom application specific logic for evaluating +boolean conditions. As a simple example, let's create a Twig test that checks if +objects are 'red':: + + $twig = new Twig_Environment($loader); + $test = new Twig_SimpleTest('red', function ($value) { + if (isset($value->color) && $value->color == 'red') { + return true; + } + if (isset($value->paint) && $value->paint == 'red') { + return true; + } + return false; + }); + $twig->addTest($test); + +Test functions should always return true/false. + +When creating tests you can use the ``node_class`` option to provide custom test +compilation. This is useful if your test can be compiled into PHP primitives. +This is used by many of the tests built into Twig:: + + $twig = new Twig_Environment($loader); + $test = new Twig_SimpleTest( + 'odd', + null, + array('node_class' => 'Twig_Node_Expression_Test_Odd')); + $twig->addTest($test); + + class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test + { + public function compile(Twig_Compiler $compiler) + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' % 2 == 1') + ->raw(')') + ; + } + } + +The above example shows how you can create tests that use a node class. The +node class has access to one sub-node called 'node'. This sub-node contains the +value that is being tested. When the ``odd`` filter is used in code such as: + +.. code-block:: jinja + + {% if my_value is odd %} + +The ``node`` sub-node will contain an expression of ``my_value``. Node-based +tests also have access to the ``arguments`` node. This node will contain the +various other arguments that have been provided to your test. + +If you want to pass a variable number of positional or named arguments to the +test, set the ``is_variadic`` option to ``true``. Tests also support dynamic +name feature as filters and functions. + +Tags +---- + +One of the most exciting features of a template engine like Twig is the +possibility to define new language constructs. This is also the most complex +feature as you need to understand how Twig's internals work. + +Let's create a simple ``set`` tag that allows the definition of simple +variables from within a template. The tag can be used like follows: + +.. code-block:: jinja + + {% set name = "value" %} + + {{ name }} + + {# should output value #} + +.. note:: + + The ``set`` tag is part of the Core extension and as such is always + available. The built-in version is slightly more powerful and supports + multiple assignments by default (cf. the template designers chapter for + more information). + +Three steps are needed to define a new tag: + +* Defining a Token Parser class (responsible for parsing the template code); + +* Defining a Node class (responsible for converting the parsed code to PHP); + +* Registering the tag. + +Registering a new tag +~~~~~~~~~~~~~~~~~~~~~ + +Adding a tag is as simple as calling the ``addTokenParser`` method on the +``Twig_Environment`` instance:: + + $twig = new Twig_Environment($loader); + $twig->addTokenParser(new Project_Set_TokenParser()); + +Defining a Token Parser +~~~~~~~~~~~~~~~~~~~~~~~ + +Now, let's see the actual code of this class:: + + class Project_Set_TokenParser extends Twig_TokenParser + { + public function parse(Twig_Token $token) + { + $parser = $this->parser; + $stream = $parser->getStream(); + + $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); + $stream->expect(Twig_Token::OPERATOR_TYPE, '='); + $value = $parser->getExpressionParser()->parseExpression(); + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + return new Project_Set_Node($name, $value, $token->getLine(), $this->getTag()); + } + + public function getTag() + { + return 'set'; + } + } + +The ``getTag()`` method must return the tag we want to parse, here ``set``. + +The ``parse()`` method is invoked whenever the parser encounters a ``set`` +tag. It should return a ``Twig_Node`` instance that represents the node (the +``Project_Set_Node`` calls creating is explained in the next section). + +The parsing process is simplified thanks to a bunch of methods you can call +from the token stream (``$this->parser->getStream()``): + +* ``getCurrent()``: Gets the current token in the stream. + +* ``next()``: Moves to the next token in the stream, *but returns the old one*. + +* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether + the current token is of a particular type or value (or both). The value may be an + array of several possible values. + +* ``expect($type[, $value[, $message]])``: If the current token isn't of the given + type/value a syntax error is thrown. Otherwise, if the type and value are correct, + the token is returned and the stream moves to the next token. + +* ``look()``: Looks at the next token without consuming it. + +Parsing expressions is done by calling the ``parseExpression()`` like we did for +the ``set`` tag. + +.. tip:: + + Reading the existing ``TokenParser`` classes is the best way to learn all + the nitty-gritty details of the parsing process. + +Defining a Node +~~~~~~~~~~~~~~~ + +The ``Project_Set_Node`` class itself is rather simple:: + + class Project_Set_Node extends Twig_Node + { + public function __construct($name, Twig_Node_Expression $value, $line, $tag = null) + { + parent::__construct(array('value' => $value), array('name' => $name), $line, $tag); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('$context[\''.$this->getAttribute('name').'\'] = ') + ->subcompile($this->getNode('value')) + ->raw(";\n") + ; + } + } + +The compiler implements a fluid interface and provides methods that helps the +developer generate beautiful and readable PHP code: + +* ``subcompile()``: Compiles a node. + +* ``raw()``: Writes the given string as is. + +* ``write()``: Writes the given string by adding indentation at the beginning + of each line. + +* ``string()``: Writes a quoted string. + +* ``repr()``: Writes a PHP representation of a given value (see + ``Twig_Node_For`` for a usage example). + +* ``addDebugInfo()``: Adds the line of the original template file related to + the current node as a comment. + +* ``indent()``: Indents the generated code (see ``Twig_Node_Block`` for a + usage example). + +* ``outdent()``: Outdents the generated code (see ``Twig_Node_Block`` for a + usage example). + +.. _creating_extensions: + +Creating an Extension +--------------------- + +The main motivation for writing an extension is to move often used code into a +reusable class like adding support for internationalization. An extension can +define tags, filters, tests, operators, global variables, functions, and node +visitors. + +Most of the time, it is useful to create a single extension for your project, +to host all the specific tags and filters you want to add to Twig. + +.. tip:: + + When packaging your code into an extension, Twig is smart enough to + recompile your templates whenever you make a change to it (when + ``auto_reload`` is enabled). + +.. note:: + + Before writing your own extensions, have a look at the Twig official + extension repository: http://github.com/twigphp/Twig-extensions. + +An extension is a class that implements the following interface:: + + interface Twig_ExtensionInterface + { + /** + * Initializes the runtime environment. + * + * This is where you can load some file that contains filter functions for instance. + * + * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead + */ + function initRuntime(Twig_Environment $environment); + + /** + * Returns the token parser instances to add to the existing list. + * + * @return (Twig_TokenParserInterface|Twig_TokenParserBrokerInterface)[] + */ + function getTokenParsers(); + + /** + * Returns the node visitor instances to add to the existing list. + * + * @return Twig_NodeVisitorInterface[] + */ + function getNodeVisitors(); + + /** + * Returns a list of filters to add to the existing list. + * + * @return Twig_SimpleFilter[] + */ + function getFilters(); + + /** + * Returns a list of tests to add to the existing list. + * + * @return Twig_SimpleTest[] + */ + function getTests(); + + /** + * Returns a list of functions to add to the existing list. + * + * @return Twig_SimpleFunction[] + */ + function getFunctions(); + + /** + * Returns a list of operators to add to the existing list. + * + * @return array First array of unary operators, second array of binary operators + */ + function getOperators(); + + /** + * Returns a list of global variables to add to the existing list. + * + * @return array An array of global variables + * + * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead + */ + function getGlobals(); + + /** + * Returns the name of the extension. + * + * @return string The extension name + * + * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally + */ + function getName(); + } + +To keep your extension class clean and lean, inherit from the built-in +``Twig_Extension`` class instead of implementing the interface as it provides +empty implementations for all methods: + + class Project_Twig_Extension extends Twig_Extension + { + } + +Of course, this extension does nothing for now. We will customize it in the +next sections. + +.. note:: + + Prior to Twig 1.26, you must implement the ``getName()`` method which must + return a unique identifier for the extension. + +Twig does not care where you save your extension on the filesystem, as all +extensions must be registered explicitly to be available in your templates. + +You can register an extension by using the ``addExtension()`` method on your +main ``Environment`` object:: + + $twig = new Twig_Environment($loader); + $twig->addExtension(new Project_Twig_Extension()); + +.. tip:: + + The Twig core extensions are great examples of how extensions work. + +Globals +~~~~~~~ + +Global variables can be registered in an extension via the ``getGlobals()`` +method:: + + class Project_Twig_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface + { + public function getGlobals() + { + return array( + 'text' => new Text(), + ); + } + + // ... + } + +Functions +~~~~~~~~~ + +Functions can be registered in an extension via the ``getFunctions()`` +method:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getFunctions() + { + return array( + new Twig_SimpleFunction('lipsum', 'generate_lipsum'), + ); + } + + // ... + } + +Filters +~~~~~~~ + +To add a filter to an extension, you need to override the ``getFilters()`` +method. This method must return an array of filters to add to the Twig +environment:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getFilters() + { + return array( + new Twig_SimpleFilter('rot13', 'str_rot13'), + ); + } + + // ... + } + +Tags +~~~~ + +Adding a tag in an extension can be done by overriding the +``getTokenParsers()`` method. This method must return an array of tags to add +to the Twig environment:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getTokenParsers() + { + return array(new Project_Set_TokenParser()); + } + + // ... + } + +In the above code, we have added a single new tag, defined by the +``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is +responsible for parsing the tag and compiling it to PHP. + +Operators +~~~~~~~~~ + +The ``getOperators()`` methods lets you add new operators. Here is how to add +``!``, ``||``, and ``&&`` operators:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getOperators() + { + return array( + array( + '!' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'), + ), + array( + '||' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '&&' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + ), + ); + } + + // ... + } + +Tests +~~~~~ + +The ``getTests()`` method lets you add new test functions:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getTests() + { + return array( + new Twig_SimpleTest('even', 'twig_test_even'), + ); + } + + // ... + } + +Definition vs Runtime +~~~~~~~~~~~~~~~~~~~~~ + +Twig filters, functions, and tests runtime implementations can be defined as +any valid PHP callable: + +* **functions/static methods**: Simple to implement and fast (used by all Twig + core extensions); but it is hard for the runtime to depend on external + objects; + +* **closures**: Simple to implement; + +* **object methods**: More flexible and required if your runtime code depends + on external objects. + +The simplest way to use methods is to define them on the extension itself:: + + class Project_Twig_Extension extends Twig_Extension + { + private $rot13Provider; + + public function __construct($rot13Provider) + { + $this->rot13Provider = $rot13Provider; + } + + public function getFunctions() + { + return array( + new Twig_SimpleFunction('rot13', array($this, 'rot13')), + ); + } + + public function rot13($value) + { + return $rot13Provider->rot13($value); + } + } + +This is very convenient but not recommended as it makes template compilation +depend on runtime dependencies even if they are not needed (think for instance +as a dependency that connects to a database engine). + +As of Twig 1.26, you can easily decouple the extension definitions from their +runtime implementations by registering a ``Twig_RuntimeLoaderInterface`` +instance on the environment that knows how to instantiate such runtime classes +(runtime classes must be autoload-able):: + + class RuntimeLoader implements Twig_RuntimeLoaderInterface + { + public function load($class) + { + // implement the logic to create an instance of $class + // and inject its dependencies + // most of the time, it means using your dependency injection container + if ('Project_Twig_RuntimeExtension' === $class) { + return new $class(new Rot13Provider()); + } else { + // ... + } + } + } + + $twig->addRuntimeLoader(new RuntimeLoader()); + +.. note:: + + As of Twig 1.32, Twig comes with a PSR-11 compatible runtime loader + (``Twig_ContainerRuntimeLoader``) that works on PHP 5.3+. + +It is now possible to move the runtime logic to a new +``Project_Twig_RuntimeExtension`` class and use it directly in the extension:: + + class Project_Twig_RuntimeExtension + { + private $rot13Provider; + + public function __construct($rot13Provider) + { + $this->rot13Provider = $rot13Provider; + } + + public function rot13($value) + { + return $rot13Provider->rot13($value); + } + } + + class Project_Twig_Extension extends Twig_Extension + { + public function getFunctions() + { + return array( + new Twig_SimpleFunction('rot13', array('Project_Twig_RuntimeExtension', 'rot13')), + // or + new Twig_SimpleFunction('rot13', 'Project_Twig_RuntimeExtension::rot13'), + ); + } + } + +Overloading +----------- + +To overload an already defined filter, test, operator, global variable, or +function, re-define it in an extension and register it **as late as +possible** (order matters):: + + class MyCoreExtension extends Twig_Extension + { + public function getFilters() + { + return array( + new Twig_SimpleFilter('date', array($this, 'dateFilter')), + ); + } + + public function dateFilter($timestamp, $format = 'F j, Y H:i') + { + // do something different from the built-in date filter + } + } + + $twig = new Twig_Environment($loader); + $twig->addExtension(new MyCoreExtension()); + +Here, we have overloaded the built-in ``date`` filter with a custom one. + +If you do the same on the ``Twig_Environment`` itself, beware that it takes +precedence over any other registered extensions:: + + $twig = new Twig_Environment($loader); + $twig->addFilter(new Twig_SimpleFilter('date', function ($timestamp, $format = 'F j, Y H:i') { + // do something different from the built-in date filter + })); + // the date filter will come from the above registration, not + // from the registered extension below + $twig->addExtension(new MyCoreExtension()); + +.. caution:: + + Note that overloading the built-in Twig elements is not recommended as it + might be confusing. + +Testing an Extension +-------------------- + +Functional Tests +~~~~~~~~~~~~~~~~ + +You can create functional tests for extensions simply by creating the +following file structure in your test directory:: + + Fixtures/ + filters/ + foo.test + bar.test + functions/ + foo.test + bar.test + tags/ + foo.test + bar.test + IntegrationTest.php + +The ``IntegrationTest.php`` file should look like this:: + + class Project_Tests_IntegrationTest extends Twig_Test_IntegrationTestCase + { + public function getExtensions() + { + return array( + new Project_Twig_Extension1(), + new Project_Twig_Extension2(), + ); + } + + public function getFixturesDir() + { + return dirname(__FILE__).'/Fixtures/'; + } + } + +Fixtures examples can be found within the Twig repository +`tests/Twig/Fixtures`_ directory. + +Node Tests +~~~~~~~~~~ + +Testing the node visitors can be complex, so extend your test cases from +``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository +`tests/Twig/Node`_ directory. + +.. _`rot13`: http://www.php.net/manual/en/function.str-rot13.php +.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Fixtures +.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Node diff --git a/vendor/twig/twig/doc/advanced_legacy.rst b/vendor/twig/twig/doc/advanced_legacy.rst new file mode 100644 index 000000000..33e9f45a4 --- /dev/null +++ b/vendor/twig/twig/doc/advanced_legacy.rst @@ -0,0 +1,885 @@ +Extending Twig +============== + +.. caution:: + + This section describes how to extends Twig for versions **older than + 1.12**. If you are using a newer version, read the :doc:`newer` + chapter instead. + +Twig can be extended in many ways; you can add extra tags, filters, tests, +operators, global variables, and functions. You can even extend the parser +itself with node visitors. + +.. note:: + + The first section of this chapter describes how to extend Twig easily. If + you want to reuse your changes in different projects or if you want to + share them with others, you should then create an extension as described + in the following section. + +.. caution:: + + When extending Twig by calling methods on the Twig environment instance, + Twig won't be able to recompile your templates when the PHP code is + updated. To see your changes in real-time, either disable template caching + or package your code into an extension (see the next section of this + chapter). + +Before extending Twig, you must understand the differences between all the +different possible extension points and when to use them. + +First, remember that Twig has two main language constructs: + +* ``{{ }}``: used to print the result of an expression evaluation; + +* ``{% %}``: used to execute statements. + +To understand why Twig exposes so many extension points, let's see how to +implement a *Lorem ipsum* generator (it needs to know the number of words to +generate). + +You can use a ``lipsum`` *tag*: + +.. code-block:: jinja + + {% lipsum 40 %} + +That works, but using a tag for ``lipsum`` is not a good idea for at least +three main reasons: + +* ``lipsum`` is not a language construct; +* The tag outputs something; +* The tag is not flexible as you cannot use it in an expression: + + .. code-block:: jinja + + {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }} + +In fact, you rarely need to create tags; and that's good news because tags are +the most complex extension point of Twig. + +Now, let's use a ``lipsum`` *filter*: + +.. code-block:: jinja + + {{ 40|lipsum }} + +Again, it works, but it looks weird. A filter transforms the passed value to +something else but here we use the value to indicate the number of words to +generate (so, ``40`` is an argument of the filter, not the value we want to +transform). + +Next, let's use a ``lipsum`` *function*: + +.. code-block:: jinja + + {{ lipsum(40) }} + +Here we go. For this specific example, the creation of a function is the +extension point to use. And you can use it anywhere an expression is accepted: + +.. code-block:: jinja + + {{ 'some text' ~ ipsum(40) ~ 'some more text' }} + + {% set ipsum = ipsum(40) %} + +Last but not the least, you can also use a *global* object with a method able +to generate lorem ipsum text: + +.. code-block:: jinja + + {{ text.lipsum(40) }} + +As a rule of thumb, use functions for frequently used features and global +objects for everything else. + +Keep in mind the following when you want to extend Twig: + +========== ========================== ========== ========================= +What? Implementation difficulty? How often? When? +========== ========================== ========== ========================= +*macro* trivial frequent Content generation +*global* trivial frequent Helper object +*function* trivial frequent Content generation +*filter* trivial frequent Value transformation +*tag* complex rare DSL language construct +*test* trivial rare Boolean decision +*operator* trivial rare Values transformation +========== ========================== ========== ========================= + +Globals +------- + +A global variable is like any other template variable, except that it's +available in all templates and macros:: + + $twig = new Twig_Environment($loader); + $twig->addGlobal('text', new Text()); + +You can then use the ``text`` variable anywhere in a template: + +.. code-block:: jinja + + {{ text.lipsum(40) }} + +Filters +------- + +A filter is a regular PHP function or an object method that takes the left +side of the filter (before the pipe ``|``) as first argument and the extra +arguments passed to the filter (within parentheses ``()``) as extra arguments. + +Defining a filter is as easy as associating the filter name with a PHP +callable. For instance, let's say you have the following code in a template: + +.. code-block:: jinja + + {{ 'TWIG'|lower }} + +When compiling this template to PHP, Twig looks for the PHP callable +associated with the ``lower`` filter. The ``lower`` filter is a built-in Twig +filter, and it is simply mapped to the PHP ``strtolower()`` function. After +compilation, the generated PHP code is roughly equivalent to: + +.. code-block:: html+php + + + +As you can see, the ``'TWIG'`` string is passed as a first argument to the PHP +function. + +A filter can also take extra arguments like in the following example: + +.. code-block:: jinja + + {{ now|date('d/m/Y') }} + +In this case, the extra arguments are passed to the function after the main +argument, and the compiled code is equivalent to: + +.. code-block:: html+php + + + +Let's see how to create a new filter. + +In this section, we will create a ``rot13`` filter, which should return the +`rot13`_ transformation of a string. Here is an example of its usage and the +expected output: + +.. code-block:: jinja + + {{ "Twig"|rot13 }} + + {# should displays Gjvt #} + +Adding a filter is as simple as calling the ``addFilter()`` method on the +``Twig_Environment`` instance:: + + $twig = new Twig_Environment($loader); + $twig->addFilter('rot13', new Twig_Filter_Function('str_rot13')); + +The second argument of ``addFilter()`` is an instance of ``Twig_Filter``. +Here, we use ``Twig_Filter_Function`` as the filter is a PHP function. The +first argument passed to the ``Twig_Filter_Function`` constructor is the name +of the PHP function to call, here ``str_rot13``, a native PHP function. + +Let's say I now want to be able to add a prefix before the converted string: + +.. code-block:: jinja + + {{ "Twig"|rot13('prefix_') }} + + {# should displays prefix_Gjvt #} + +As the PHP ``str_rot13()`` function does not support this requirement, let's +create a new PHP function:: + + function project_compute_rot13($string, $prefix = '') + { + return $prefix.str_rot13($string); + } + +As you can see, the ``prefix`` argument of the filter is passed as an extra +argument to the ``project_compute_rot13()`` function. + +Adding this filter is as easy as before:: + + $twig->addFilter('rot13', new Twig_Filter_Function('project_compute_rot13')); + +For better encapsulation, a filter can also be defined as a static method of a +class. The ``Twig_Filter_Function`` class can also be used to register such +static methods as filters:: + + $twig->addFilter('rot13', new Twig_Filter_Function('SomeClass::rot13Filter')); + +.. tip:: + + In an extension, you can also define a filter as a static method of the + extension class. + +Environment aware Filters +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``Twig_Filter`` classes take options as their last argument. For instance, +if you want access to the current environment instance in your filter, set the +``needs_environment`` option to ``true``:: + + $filter = new Twig_Filter_Function('str_rot13', array('needs_environment' => true)); + +Twig will then pass the current environment as the first argument to the +filter call:: + + function twig_compute_rot13(Twig_Environment $env, $string) + { + // get the current charset for instance + $charset = $env->getCharset(); + + return str_rot13($string); + } + +Automatic Escaping +~~~~~~~~~~~~~~~~~~ + +If automatic escaping is enabled, the output of the filter may be escaped +before printing. If your filter acts as an escaper (or explicitly outputs HTML +or JavaScript code), you will want the raw output to be printed. In such a +case, set the ``is_safe`` option:: + + $filter = new Twig_Filter_Function('nl2br', array('is_safe' => array('html'))); + +Some filters may need to work on input that is already escaped or safe, for +example when adding (safe) HTML tags to originally unsafe output. In such a +case, set the ``pre_escape`` option to escape the input data before it is run +through your filter:: + + $filter = new Twig_Filter_Function('somefilter', array('pre_escape' => 'html', 'is_safe' => array('html'))); + +Dynamic Filters +~~~~~~~~~~~~~~~ + +.. versionadded:: 1.5 + Dynamic filters support was added in Twig 1.5. + +A filter name containing the special ``*`` character is a dynamic filter as +the ``*`` can be any string:: + + $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path')); + + function twig_path($name, $arguments) + { + // ... + } + +The following filters will be matched by the above defined dynamic filter: + +* ``product_path`` +* ``category_path`` + +A dynamic filter can define more than one dynamic parts:: + + $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path')); + + function twig_path($name, $suffix, $arguments) + { + // ... + } + +The filter will receive all dynamic part values before the normal filters +arguments. For instance, a call to ``'foo'|a_path_b()`` will result in the +following PHP call: ``twig_path('a', 'b', 'foo')``. + +Functions +--------- + +A function is a regular PHP function or an object method that can be called from +templates. + +.. code-block:: jinja + + {{ constant("DATE_W3C") }} + +When compiling this template to PHP, Twig looks for the PHP callable +associated with the ``constant`` function. The ``constant`` function is a built-in Twig +function, and it is simply mapped to the PHP ``constant()`` function. After +compilation, the generated PHP code is roughly equivalent to: + +.. code-block:: html+php + + + +Adding a function is similar to adding a filter. This can be done by calling the +``addFunction()`` method on the ``Twig_Environment`` instance:: + + $twig = new Twig_Environment($loader); + $twig->addFunction('functionName', new Twig_Function_Function('someFunction')); + +You can also expose extension methods as functions in your templates:: + + // $this is an object that implements Twig_ExtensionInterface. + $twig = new Twig_Environment($loader); + $twig->addFunction('otherFunction', new Twig_Function_Method($this, 'someMethod')); + +Functions also support ``needs_environment`` and ``is_safe`` parameters. + +Dynamic Functions +~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.5 + Dynamic functions support was added in Twig 1.5. + +A function name containing the special ``*`` character is a dynamic function +as the ``*`` can be any string:: + + $twig->addFunction('*_path', new Twig_Function_Function('twig_path')); + + function twig_path($name, $arguments) + { + // ... + } + +The following functions will be matched by the above defined dynamic function: + +* ``product_path`` +* ``category_path`` + +A dynamic function can define more than one dynamic parts:: + + $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path')); + + function twig_path($name, $suffix, $arguments) + { + // ... + } + +The function will receive all dynamic part values before the normal functions +arguments. For instance, a call to ``a_path_b('foo')`` will result in the +following PHP call: ``twig_path('a', 'b', 'foo')``. + +Tags +---- + +One of the most exciting feature of a template engine like Twig is the +possibility to define new language constructs. This is also the most complex +feature as you need to understand how Twig's internals work. + +Let's create a simple ``set`` tag that allows the definition of simple +variables from within a template. The tag can be used like follows: + +.. code-block:: jinja + + {% set name = "value" %} + + {{ name }} + + {# should output value #} + +.. note:: + + The ``set`` tag is part of the Core extension and as such is always + available. The built-in version is slightly more powerful and supports + multiple assignments by default (cf. the template designers chapter for + more information). + +Three steps are needed to define a new tag: + +* Defining a Token Parser class (responsible for parsing the template code); + +* Defining a Node class (responsible for converting the parsed code to PHP); + +* Registering the tag. + +Registering a new tag +~~~~~~~~~~~~~~~~~~~~~ + +Adding a tag is as simple as calling the ``addTokenParser`` method on the +``Twig_Environment`` instance:: + + $twig = new Twig_Environment($loader); + $twig->addTokenParser(new Project_Set_TokenParser()); + +Defining a Token Parser +~~~~~~~~~~~~~~~~~~~~~~~ + +Now, let's see the actual code of this class:: + + class Project_Set_TokenParser extends Twig_TokenParser + { + public function parse(Twig_Token $token) + { + $lineno = $token->getLine(); + $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(); + $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, '='); + $value = $this->parser->getExpressionParser()->parseExpression(); + + $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + + return new Project_Set_Node($name, $value, $lineno, $this->getTag()); + } + + public function getTag() + { + return 'set'; + } + } + +The ``getTag()`` method must return the tag we want to parse, here ``set``. + +The ``parse()`` method is invoked whenever the parser encounters a ``set`` +tag. It should return a ``Twig_Node`` instance that represents the node (the +``Project_Set_Node`` calls creating is explained in the next section). + +The parsing process is simplified thanks to a bunch of methods you can call +from the token stream (``$this->parser->getStream()``): + +* ``getCurrent()``: Gets the current token in the stream. + +* ``next()``: Moves to the next token in the stream, *but returns the old one*. + +* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether + the current token is of a particular type or value (or both). The value may be an + array of several possible values. + +* ``expect($type[, $value[, $message]])``: If the current token isn't of the given + type/value a syntax error is thrown. Otherwise, if the type and value are correct, + the token is returned and the stream moves to the next token. + +* ``look()``: Looks a the next token without consuming it. + +Parsing expressions is done by calling the ``parseExpression()`` like we did for +the ``set`` tag. + +.. tip:: + + Reading the existing ``TokenParser`` classes is the best way to learn all + the nitty-gritty details of the parsing process. + +Defining a Node +~~~~~~~~~~~~~~~ + +The ``Project_Set_Node`` class itself is rather simple:: + + class Project_Set_Node extends Twig_Node + { + public function __construct($name, Twig_Node_Expression $value, $lineno, $tag = null) + { + parent::__construct(array('value' => $value), array('name' => $name), $lineno, $tag); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('$context[\''.$this->getAttribute('name').'\'] = ') + ->subcompile($this->getNode('value')) + ->raw(";\n") + ; + } + } + +The compiler implements a fluid interface and provides methods that helps the +developer generate beautiful and readable PHP code: + +* ``subcompile()``: Compiles a node. + +* ``raw()``: Writes the given string as is. + +* ``write()``: Writes the given string by adding indentation at the beginning + of each line. + +* ``string()``: Writes a quoted string. + +* ``repr()``: Writes a PHP representation of a given value (see + ``Twig_Node_For`` for a usage example). + +* ``addDebugInfo()``: Adds the line of the original template file related to + the current node as a comment. + +* ``indent()``: Indents the generated code (see ``Twig_Node_Block`` for a + usage example). + +* ``outdent()``: Outdents the generated code (see ``Twig_Node_Block`` for a + usage example). + +.. _creating_extensions: + +Creating an Extension +--------------------- + +The main motivation for writing an extension is to move often used code into a +reusable class like adding support for internationalization. An extension can +define tags, filters, tests, operators, global variables, functions, and node +visitors. + +Creating an extension also makes for a better separation of code that is +executed at compilation time and code needed at runtime. As such, it makes +your code faster. + +Most of the time, it is useful to create a single extension for your project, +to host all the specific tags and filters you want to add to Twig. + +.. tip:: + + When packaging your code into an extension, Twig is smart enough to + recompile your templates whenever you make a change to it (when the + ``auto_reload`` is enabled). + +.. note:: + + Before writing your own extensions, have a look at the Twig official + extension repository: http://github.com/twigphp/Twig-extensions. + +An extension is a class that implements the following interface:: + + interface Twig_ExtensionInterface + { + /** + * Initializes the runtime environment. + * + * This is where you can load some file that contains filter functions for instance. + */ + function initRuntime(Twig_Environment $environment); + + /** + * Returns the token parser instances to add to the existing list. + * + * @return (Twig_TokenParserInterface|Twig_TokenParserBrokerInterface)[] + */ + function getTokenParsers(); + + /** + * Returns the node visitor instances to add to the existing list. + * + * @return Twig_NodeVisitorInterface[] + */ + function getNodeVisitors(); + + /** + * Returns a list of filters to add to the existing list. + * + * @return Twig_SimpleFilter[] + */ + function getFilters(); + + /** + * Returns a list of tests to add to the existing list. + * + * @return Twig_SimpleTest[] + */ + function getTests(); + + /** + * Returns a list of functions to add to the existing list. + * + * @return Twig_SimpleFunction[] + */ + function getFunctions(); + + /** + * Returns a list of operators to add to the existing list. + * + * @return array First array of unary operators, second array of binary operators + */ + function getOperators(); + + /** + * Returns a list of global variables to add to the existing list. + * + * @return array An array of global variables + */ + function getGlobals(); + + /** + * Returns the name of the extension. + * + * @return string The extension name + */ + function getName(); + } + +To keep your extension class clean and lean, it can inherit from the built-in +``Twig_Extension`` class instead of implementing the whole interface. That +way, you just need to implement the ``getName()`` method as the +``Twig_Extension`` provides empty implementations for all other methods. + +The ``getName()`` method must return a unique identifier for your extension. + +Now, with this information in mind, let's create the most basic extension +possible:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getName() + { + return 'project'; + } + } + +.. note:: + + Of course, this extension does nothing for now. We will customize it in + the next sections. + +Twig does not care where you save your extension on the filesystem, as all +extensions must be registered explicitly to be available in your templates. + +You can register an extension by using the ``addExtension()`` method on your +main ``Environment`` object:: + + $twig = new Twig_Environment($loader); + $twig->addExtension(new Project_Twig_Extension()); + +Of course, you need to first load the extension file by either using +``require_once()`` or by using an autoloader (see `spl_autoload_register()`_). + +.. tip:: + + The bundled extensions are great examples of how extensions work. + +Globals +~~~~~~~ + +Global variables can be registered in an extension via the ``getGlobals()`` +method:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getGlobals() + { + return array( + 'text' => new Text(), + ); + } + + // ... + } + +Functions +~~~~~~~~~ + +Functions can be registered in an extension via the ``getFunctions()`` +method:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getFunctions() + { + return array( + 'lipsum' => new Twig_Function_Function('generate_lipsum'), + ); + } + + // ... + } + +Filters +~~~~~~~ + +To add a filter to an extension, you need to override the ``getFilters()`` +method. This method must return an array of filters to add to the Twig +environment:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getFilters() + { + return array( + 'rot13' => new Twig_Filter_Function('str_rot13'), + ); + } + + // ... + } + +As you can see in the above code, the ``getFilters()`` method returns an array +where keys are the name of the filters (``rot13``) and the values the +definition of the filter (``new Twig_Filter_Function('str_rot13')``). + +As seen in the previous chapter, you can also define filters as static methods +on the extension class:: + +$twig->addFilter('rot13', new Twig_Filter_Function('Project_Twig_Extension::rot13Filter')); + +You can also use ``Twig_Filter_Method`` instead of ``Twig_Filter_Function`` +when defining a filter to use a method:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getFilters() + { + return array( + 'rot13' => new Twig_Filter_Method($this, 'rot13Filter'), + ); + } + + public function rot13Filter($string) + { + return str_rot13($string); + } + + // ... + } + +The first argument of the ``Twig_Filter_Method`` constructor is always +``$this``, the current extension object. The second one is the name of the +method to call. + +Using methods for filters is a great way to package your filter without +polluting the global namespace. This also gives the developer more flexibility +at the cost of a small overhead. + +Overriding default Filters +.......................... + +If some default core filters do not suit your needs, you can easily override +them by creating your own extension. Just use the same names as the one you +want to override:: + + class MyCoreExtension extends Twig_Extension + { + public function getFilters() + { + return array( + 'date' => new Twig_Filter_Method($this, 'dateFilter'), + // ... + ); + } + + public function dateFilter($timestamp, $format = 'F j, Y H:i') + { + return '...'.twig_date_format_filter($timestamp, $format); + } + + public function getName() + { + return 'project'; + } + } + +Here, we override the ``date`` filter with a custom one. Using this extension +is as simple as registering the ``MyCoreExtension`` extension by calling the +``addExtension()`` method on the environment instance:: + + $twig = new Twig_Environment($loader); + $twig->addExtension(new MyCoreExtension()); + +Tags +~~~~ + +Adding a tag in an extension can be done by overriding the +``getTokenParsers()`` method. This method must return an array of tags to add +to the Twig environment:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getTokenParsers() + { + return array(new Project_Set_TokenParser()); + } + + // ... + } + +In the above code, we have added a single new tag, defined by the +``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is +responsible for parsing the tag and compiling it to PHP. + +Operators +~~~~~~~~~ + +The ``getOperators()`` methods allows to add new operators. Here is how to add +``!``, ``||``, and ``&&`` operators:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getOperators() + { + return array( + array( + '!' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'), + ), + array( + '||' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '&&' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + ), + ); + } + + // ... + } + +Tests +~~~~~ + +The ``getTests()`` methods allows to add new test functions:: + + class Project_Twig_Extension extends Twig_Extension + { + public function getTests() + { + return array( + 'even' => new Twig_Test_Function('twig_test_even'), + ); + } + + // ... + } + +Testing an Extension +-------------------- + +.. versionadded:: 1.10 + Support for functional tests was added in Twig 1.10. + +Functional Tests +~~~~~~~~~~~~~~~~ + +You can create functional tests for extensions simply by creating the +following file structure in your test directory:: + + Fixtures/ + filters/ + foo.test + bar.test + functions/ + foo.test + bar.test + tags/ + foo.test + bar.test + IntegrationTest.php + +The ``IntegrationTest.php`` file should look like this:: + + class Project_Tests_IntegrationTest extends Twig_Test_IntegrationTestCase + { + public function getExtensions() + { + return array( + new Project_Twig_Extension1(), + new Project_Twig_Extension2(), + ); + } + + public function getFixturesDir() + { + return dirname(__FILE__).'/Fixtures/'; + } + } + +Fixtures examples can be found within the Twig repository +`tests/Twig/Fixtures`_ directory. + +Node Tests +~~~~~~~~~~ + +Testing the node visitors can be complex, so extend your test cases from +``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository +`tests/Twig/Node`_ directory. + +.. _`spl_autoload_register()`: http://www.php.net/spl_autoload_register +.. _`rot13`: http://www.php.net/manual/en/function.str-rot13.php +.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Fixtures +.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Node diff --git a/vendor/twig/twig/doc/api.rst b/vendor/twig/twig/doc/api.rst new file mode 100644 index 000000000..8be2b8af8 --- /dev/null +++ b/vendor/twig/twig/doc/api.rst @@ -0,0 +1,590 @@ +Twig for Developers +=================== + +This chapter describes the API to Twig and not the template language. It will +be most useful as reference to those implementing the template interface to +the application and not those who are creating Twig templates. + +Basics +------ + +Twig uses a central object called the **environment** (of class +``Twig_Environment``). Instances of this class are used to store the +configuration and extensions, and are used to load templates from the file +system or other locations. + +Most applications will create one ``Twig_Environment`` object on application +initialization and use that to load templates. In some cases it's however +useful to have multiple environments side by side, if different configurations +are in use. + +The simplest way to configure Twig to load templates for your application +looks roughly like this:: + + require_once '/path/to/lib/Twig/Autoloader.php'; + Twig_Autoloader::register(); + + $loader = new Twig_Loader_Filesystem('/path/to/templates'); + $twig = new Twig_Environment($loader, array( + 'cache' => '/path/to/compilation_cache', + )); + +This will create a template environment with the default settings and a loader +that looks up the templates in the ``/path/to/templates/`` folder. Different +loaders are available and you can also write your own if you want to load +templates from a database or other resources. + +.. note:: + + Notice that the second argument of the environment is an array of options. + The ``cache`` option is a compilation cache directory, where Twig caches + the compiled templates to avoid the parsing phase for sub-sequent + requests. It is very different from the cache you might want to add for + the evaluated templates. For such a need, you can use any available PHP + cache library. + +Rendering Templates +------------------- + +To load a template from a Twig environment, call the ``load()`` method which +returns a ``Twig_TemplateWrapper`` instance:: + + $template = $twig->load('index.html'); + +.. note:: + + Before Twig 1.28, you should use ``loadTemplate()`` instead which returns a + ``Twig_Template`` instance. + +To render the template with some variables, call the ``render()`` method:: + + echo $template->render(array('the' => 'variables', 'go' => 'here')); + +.. note:: + + The ``display()`` method is a shortcut to output the template directly. + +You can also load and render the template in one fell swoop:: + + echo $twig->render('index.html', array('the' => 'variables', 'go' => 'here')); + +.. versionadded:: 1.28 + The possibility to render blocks from the API was added in Twig 1.28. + +If a template defines blocks, they can be rendered individually via the +``renderBlock()`` call:: + + echo $template->renderBlock('block_name', array('the' => 'variables', 'go' => 'here')); + +.. _environment_options: + +Environment Options +------------------- + +When creating a new ``Twig_Environment`` instance, you can pass an array of +options as the constructor second argument:: + + $twig = new Twig_Environment($loader, array('debug' => true)); + +The following options are available: + +* ``debug`` *boolean* + + When set to ``true``, the generated templates have a + ``__toString()`` method that you can use to display the generated nodes + (default to ``false``). + +* ``charset`` *string* (defaults to ``utf-8``) + + The charset used by the templates. + +* ``base_template_class`` *string* (defaults to ``Twig_Template``) + + The base template class to use for generated + templates. + +* ``cache`` *string* or ``false`` + + An absolute path where to store the compiled templates, or + ``false`` to disable caching (which is the default). + +* ``auto_reload`` *boolean* + + When developing with Twig, it's useful to recompile the + template whenever the source code changes. If you don't provide a value for + the ``auto_reload`` option, it will be determined automatically based on the + ``debug`` value. + +* ``strict_variables`` *boolean* + + If set to ``false``, Twig will silently ignore invalid + variables (variables and or attributes/methods that do not exist) and + replace them with a ``null`` value. When set to ``true``, Twig throws an + exception instead (default to ``false``). + +* ``autoescape`` *string* or *boolean* + + If set to ``true``, HTML auto-escaping will be enabled by + default for all templates (default to ``true``). + + As of Twig 1.8, you can set the escaping strategy to use (``html``, ``js``, + ``false`` to disable). + + As of Twig 1.9, you can set the escaping strategy to use (``css``, ``url``, + ``html_attr``, or a PHP callback that takes the template name and must + return the escaping strategy to use -- the callback cannot be a function name + to avoid collision with built-in escaping strategies). + + As of Twig 1.17, the ``filename`` escaping strategy (renamed to ``name`` as + of Twig 1.27) determines the escaping strategy to use for a template based on + the template filename extension (this strategy does not incur any overhead at + runtime as auto-escaping is done at compilation time.) + +* ``optimizations`` *integer* + + A flag that indicates which optimizations to apply + (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to + disable). + +Loaders +------- + +Loaders are responsible for loading templates from a resource such as the file +system. + +Compilation Cache +~~~~~~~~~~~~~~~~~ + +All template loaders can cache the compiled templates on the filesystem for +future reuse. It speeds up Twig a lot as templates are only compiled once; and +the performance boost is even larger if you use a PHP accelerator such as APC. +See the ``cache`` and ``auto_reload`` options of ``Twig_Environment`` above +for more information. + +Built-in Loaders +~~~~~~~~~~~~~~~~ + +Here is a list of the built-in loaders Twig provides: + +``Twig_Loader_Filesystem`` +.......................... + +.. versionadded:: 1.10 + The ``prependPath()`` and support for namespaces were added in Twig 1.10. + +.. versionadded:: 1.27 + Relative paths support was added in Twig 1.27. + +``Twig_Loader_Filesystem`` loads templates from the file system. This loader +can find templates in folders on the file system and is the preferred way to +load them:: + + $loader = new Twig_Loader_Filesystem($templateDir); + +It can also look for templates in an array of directories:: + + $loader = new Twig_Loader_Filesystem(array($templateDir1, $templateDir2)); + +With such a configuration, Twig will first look for templates in +``$templateDir1`` and if they do not exist, it will fallback to look for them +in the ``$templateDir2``. + +You can add or prepend paths via the ``addPath()`` and ``prependPath()`` +methods:: + + $loader->addPath($templateDir3); + $loader->prependPath($templateDir4); + +The filesystem loader also supports namespaced templates. This allows to group +your templates under different namespaces which have their own template paths. + +When using the ``setPaths()``, ``addPath()``, and ``prependPath()`` methods, +specify the namespace as the second argument (when not specified, these +methods act on the "main" namespace):: + + $loader->addPath($templateDir, 'admin'); + +Namespaced templates can be accessed via the special +``@namespace_name/template_path`` notation:: + + $twig->render('@admin/index.html', array()); + +``Twig_Loader_Filesystem`` support absolute and relative paths. Using relative +paths is preferred as it makes the cache keys independent of the project root +directory (for instance, it allows warming the cache from a build server where +the directory might be different from the one used on production servers):: + + $loader = new Twig_Loader_Filesystem('templates', getcwd().'/..'); + +.. note:: + + When not passing the root path as a second argument, Twig uses ``getcwd()`` + for relative paths. + +``Twig_Loader_Array`` +..................... + +``Twig_Loader_Array`` loads a template from a PHP array. It's passed an array +of strings bound to template names:: + + $loader = new Twig_Loader_Array(array( + 'index.html' => 'Hello {{ name }}!', + )); + $twig = new Twig_Environment($loader); + + echo $twig->render('index.html', array('name' => 'Fabien')); + +This loader is very useful for unit testing. It can also be used for small +projects where storing all templates in a single PHP file might make sense. + +.. tip:: + + When using the ``Array`` or ``String`` loaders with a cache mechanism, you + should know that a new cache key is generated each time a template content + "changes" (the cache key being the source code of the template). If you + don't want to see your cache grows out of control, you need to take care + of clearing the old cache file by yourself. + +``Twig_Loader_Chain`` +..................... + +``Twig_Loader_Chain`` delegates the loading of templates to other loaders:: + + $loader1 = new Twig_Loader_Array(array( + 'base.html' => '{% block content %}{% endblock %}', + )); + $loader2 = new Twig_Loader_Array(array( + 'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}', + 'base.html' => 'Will never be loaded', + )); + + $loader = new Twig_Loader_Chain(array($loader1, $loader2)); + + $twig = new Twig_Environment($loader); + +When looking for a template, Twig will try each loader in turn and it will +return as soon as the template is found. When rendering the ``index.html`` +template from the above example, Twig will load it with ``$loader2`` but the +``base.html`` template will be loaded from ``$loader1``. + +``Twig_Loader_Chain`` accepts any loader that implements +``Twig_LoaderInterface``. + +.. note:: + + You can also add loaders via the ``addLoader()`` method. + +Create your own Loader +~~~~~~~~~~~~~~~~~~~~~~ + +All loaders implement the ``Twig_LoaderInterface``:: + + interface Twig_LoaderInterface + { + /** + * Gets the source code of a template, given its name. + * + * @param string $name string The name of the template to load + * + * @return string The template source code + * + * @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface + */ + function getSource($name); + + /** + * Gets the cache key to use for the cache for a given template name. + * + * @param string $name string The name of the template to load + * + * @return string The cache key + */ + function getCacheKey($name); + + /** + * Returns true if the template is still fresh. + * + * @param string $name The template name + * @param timestamp $time The last modification time of the cached template + */ + function isFresh($name, $time); + } + +The ``isFresh()`` method must return ``true`` if the current cached template +is still fresh, given the last modification time, or ``false`` otherwise. + +.. note:: + + As of Twig 1.27, you should also implement + ``Twig_SourceContextLoaderInterface`` to avoid deprecation notices. + +.. tip:: + + As of Twig 1.11.0, you can also implement ``Twig_ExistsLoaderInterface`` + to make your loader faster when used with the chain loader. + +Using Extensions +---------------- + +Twig extensions are packages that add new features to Twig. Using an +extension is as simple as using the ``addExtension()`` method:: + + $twig->addExtension(new Twig_Extension_Sandbox()); + +Twig comes bundled with the following extensions: + +* *Twig_Extension_Core*: Defines all the core features of Twig. + +* *Twig_Extension_Escaper*: Adds automatic output-escaping and the possibility + to escape/unescape blocks of code. + +* *Twig_Extension_Sandbox*: Adds a sandbox mode to the default Twig + environment, making it safe to evaluate untrusted code. + +* *Twig_Extension_Profiler*: Enabled the built-in Twig profiler (as of Twig + 1.18). + +* *Twig_Extension_Optimizer*: Optimizes the node tree before compilation. + +The core, escaper, and optimizer extensions do not need to be added to the +Twig environment, as they are registered by default. + +Built-in Extensions +------------------- + +This section describes the features added by the built-in extensions. + +.. tip:: + + Read the chapter about extending Twig to learn how to create your own + extensions. + +Core Extension +~~~~~~~~~~~~~~ + +The ``core`` extension defines all the core features of Twig: + +* :doc:`Tags `; +* :doc:`Filters `; +* :doc:`Functions `; +* :doc:`Tests `. + +Escaper Extension +~~~~~~~~~~~~~~~~~ + +The ``escaper`` extension adds automatic output escaping to Twig. It defines a +tag, ``autoescape``, and a filter, ``raw``. + +When creating the escaper extension, you can switch on or off the global +output escaping strategy:: + + $escaper = new Twig_Extension_Escaper('html'); + $twig->addExtension($escaper); + +If set to ``html``, all variables in templates are escaped (using the ``html`` +escaping strategy), except those using the ``raw`` filter: + +.. code-block:: jinja + + {{ article.to_html|raw }} + +You can also change the escaping mode locally by using the ``autoescape`` tag +(see the :doc:`autoescape` doc for the syntax used before +Twig 1.8): + +.. code-block:: jinja + + {% autoescape 'html' %} + {{ var }} + {{ var|raw }} {# var won't be escaped #} + {{ var|escape }} {# var won't be double-escaped #} + {% endautoescape %} + +.. warning:: + + The ``autoescape`` tag has no effect on included files. + +The escaping rules are implemented as follows: + +* Literals (integers, booleans, arrays, ...) used in the template directly as + variables or filter arguments are never automatically escaped: + + .. code-block:: jinja + + {{ "Twig
" }} {# won't be escaped #} + + {% set text = "Twig
" %} + {{ text }} {# will be escaped #} + +* Expressions which the result is always a literal or a variable marked safe + are never automatically escaped: + + .. code-block:: jinja + + {{ foo ? "Twig
" : "
Twig" }} {# won't be escaped #} + + {% set text = "Twig
" %} + {{ foo ? text : "
Twig" }} {# will be escaped #} + + {% set text = "Twig
" %} + {{ foo ? text|raw : "
Twig" }} {# won't be escaped #} + + {% set text = "Twig
" %} + {{ foo ? text|escape : "
Twig" }} {# the result of the expression won't be escaped #} + +* Escaping is applied before printing, after any other filter is applied: + + .. code-block:: jinja + + {{ var|upper }} {# is equivalent to {{ var|upper|escape }} #} + +* The `raw` filter should only be used at the end of the filter chain: + + .. code-block:: jinja + + {{ var|raw|upper }} {# will be escaped #} + + {{ var|upper|raw }} {# won't be escaped #} + +* Automatic escaping is not applied if the last filter in the chain is marked + safe for the current context (e.g. ``html`` or ``js``). ``escape`` and + ``escape('html')`` are marked safe for HTML, ``escape('js')`` is marked + safe for JavaScript, ``raw`` is marked safe for everything. + + .. code-block:: jinja + + {% autoescape 'js' %} + {{ var|escape('html') }} {# will be escaped for HTML and JavaScript #} + {{ var }} {# will be escaped for JavaScript #} + {{ var|escape('js') }} {# won't be double-escaped #} + {% endautoescape %} + +.. note:: + + Note that autoescaping has some limitations as escaping is applied on + expressions after evaluation. For instance, when working with + concatenation, ``{{ foo|raw ~ bar }}`` won't give the expected result as + escaping is applied on the result of the concatenation, not on the + individual variables (so, the ``raw`` filter won't have any effect here). + +Sandbox Extension +~~~~~~~~~~~~~~~~~ + +The ``sandbox`` extension can be used to evaluate untrusted code. Access to +unsafe attributes and methods is prohibited. The sandbox security is managed +by a policy instance. By default, Twig comes with one policy class: +``Twig_Sandbox_SecurityPolicy``. This class allows you to white-list some +tags, filters, properties, and methods:: + + $tags = array('if'); + $filters = array('upper'); + $methods = array( + 'Article' => array('getTitle', 'getBody'), + ); + $properties = array( + 'Article' => array('title', 'body'), + ); + $functions = array('range'); + $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions); + +With the previous configuration, the security policy will only allow usage of +the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be +able to call the ``getTitle()`` and ``getBody()`` methods on ``Article`` +objects, and the ``title`` and ``body`` public properties. Everything else +won't be allowed and will generate a ``Twig_Sandbox_SecurityError`` exception. + +The policy object is the first argument of the sandbox constructor:: + + $sandbox = new Twig_Extension_Sandbox($policy); + $twig->addExtension($sandbox); + +By default, the sandbox mode is disabled and should be enabled when including +untrusted template code by using the ``sandbox`` tag: + +.. code-block:: jinja + + {% sandbox %} + {% include 'user.html' %} + {% endsandbox %} + +You can sandbox all templates by passing ``true`` as the second argument of +the extension constructor:: + + $sandbox = new Twig_Extension_Sandbox($policy, true); + +Profiler Extension +~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.18 + The Profile extension was added in Twig 1.18. + +The ``profiler`` extension enables a profiler for Twig templates; it should +only be used on your development machines as it adds some overhead:: + + $profile = new Twig_Profiler_Profile(); + $twig->addExtension(new Twig_Extension_Profiler($profile)); + + $dumper = new Twig_Profiler_Dumper_Text(); + echo $dumper->dump($profile); + +A profile contains information about time and memory consumption for template, +block, and macro executions. + +You can also dump the data in a `Blackfire.io `_ +compatible format:: + + $dumper = new Twig_Profiler_Dumper_Blackfire(); + file_put_contents('/path/to/profile.prof', $dumper->dump($profile)); + +Upload the profile to visualize it (create a `free account +`_ first): + +.. code-block:: sh + + blackfire --slot=7 upload /path/to/profile.prof + +Optimizer Extension +~~~~~~~~~~~~~~~~~~~ + +The ``optimizer`` extension optimizes the node tree before compilation:: + + $twig->addExtension(new Twig_Extension_Optimizer()); + +By default, all optimizations are turned on. You can select the ones you want +to enable by passing them to the constructor:: + + $optimizer = new Twig_Extension_Optimizer(Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR); + + $twig->addExtension($optimizer); + +Twig supports the following optimizations: + +* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_ALL``, enables all optimizations + (this is the default value). +* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_NONE``, disables all optimizations. + This reduces the compilation time, but it can increase the execution time + and the consumed memory. +* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR``, optimizes the ``for`` tag by + removing the ``loop`` variable creation whenever possible. +* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_RAW_FILTER``, removes the ``raw`` + filter whenever possible. +* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_VAR_ACCESS``, simplifies the creation + and access of variables in the compiled templates whenever possible. + +Exceptions +---------- + +Twig can throw exceptions: + +* ``Twig_Error``: The base exception for all errors. + +* ``Twig_Error_Syntax``: Thrown to tell the user that there is a problem with + the template syntax. + +* ``Twig_Error_Runtime``: Thrown when an error occurs at runtime (when a filter + does not exist for instance). + +* ``Twig_Error_Loader``: Thrown when an error occurs during template loading. + +* ``Twig_Sandbox_SecurityError``: Thrown when an unallowed tag, filter, or + method is called in a sandboxed template. diff --git a/vendor/twig/twig/doc/coding_standards.rst b/vendor/twig/twig/doc/coding_standards.rst new file mode 100644 index 000000000..bf8ea91a4 --- /dev/null +++ b/vendor/twig/twig/doc/coding_standards.rst @@ -0,0 +1,101 @@ +Coding Standards +================ + +When writing Twig templates, we recommend you to follow these official coding +standards: + +* Put one (and only one) space after the start of a delimiter (``{{``, ``{%``, + and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``): + + .. code-block:: jinja + + {{ foo }} + {# comment #} + {% if foo %}{% endif %} + + When using the whitespace control character, do not put any spaces between + it and the delimiter: + + .. code-block:: jinja + + {{- foo -}} + {#- comment -#} + {%- if foo -%}{%- endif -%} + +* Put one (and only one) space before and after the following operators: + comparison operators (``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``), math + operators (``+``, ``-``, ``/``, ``*``, ``%``, ``//``, ``**``), logic + operators (``not``, ``and``, ``or``), ``~``, ``is``, ``in``, and the ternary + operator (``?:``): + + .. code-block:: jinja + + {{ 1 + 2 }} + {{ foo ~ bar }} + {{ true ? true : false }} + +* Put one (and only one) space after the ``:`` sign in hashes and ``,`` in + arrays and hashes: + + .. code-block:: jinja + + {{ [1, 2, 3] }} + {{ {'foo': 'bar'} }} + +* Do not put any spaces after an opening parenthesis and before a closing + parenthesis in expressions: + + .. code-block:: jinja + + {{ 1 + (2 * 3) }} + +* Do not put any spaces before and after string delimiters: + + .. code-block:: jinja + + {{ 'foo' }} + {{ "foo" }} + +* Do not put any spaces before and after the following operators: ``|``, + ``.``, ``..``, ``[]``: + + .. code-block:: jinja + + {{ foo|upper|lower }} + {{ user.name }} + {{ user[name] }} + {% for i in 1..12 %}{% endfor %} + +* Do not put any spaces before and after the parenthesis used for filter and + function calls: + + .. code-block:: jinja + + {{ foo|default('foo') }} + {{ range(1..10) }} + +* Do not put any spaces before and after the opening and the closing of arrays + and hashes: + + .. code-block:: jinja + + {{ [1, 2, 3] }} + {{ {'foo': 'bar'} }} + +* Use lower cased and underscored variable names: + + .. code-block:: jinja + + {% set foo = 'foo' %} + {% set foo_bar = 'foo' %} + +* Indent your code inside tags (use the same indentation as the one used for + the target language of the rendered template): + + .. code-block:: jinja + + {% block foo %} + {% if true %} + true + {% endif %} + {% endblock %} diff --git a/vendor/twig/twig/doc/deprecated.rst b/vendor/twig/twig/doc/deprecated.rst new file mode 100644 index 000000000..8b25cc410 --- /dev/null +++ b/vendor/twig/twig/doc/deprecated.rst @@ -0,0 +1,224 @@ +Deprecated Features +=================== + +This document lists all deprecated features in Twig. Deprecated features are +kept for backward compatibility and removed in the next major release (a +feature that was deprecated in Twig 1.x is removed in Twig 2.0). + +Deprecation Notices +------------------- + +As of Twig 1.21, Twig generates deprecation notices when a template uses +deprecated features. See :ref:`deprecation-notices` for more information. + +Macros +------ + +As of Twig 2.0, macros imported in a file are not available in child templates +anymore (via an ``include`` call for instance). You need to import macros +explicitly in each file where you are using them. + +Token Parsers +------------- + +* As of Twig 1.x, the token parser broker sub-system is deprecated. The + following class and interface will be removed in 2.0: + + * ``Twig_TokenParserBrokerInterface`` + * ``Twig_TokenParserBroker`` + +* As of Twig 1.27, ``Twig_Parser::getFilename()`` is deprecated. From a token + parser, use ``$this->parser->getStream()->getSourceContext()->getPath()`` instead. + +* As of Twig 1.27, ``Twig_Parser::getEnvironment()`` is deprecated. + +Extensions +---------- + +* As of Twig 1.x, the ability to remove an extension is deprecated and the + ``Twig_Environment::removeExtension()`` method will be removed in 2.0. + +* As of Twig 1.23, the ``Twig_ExtensionInterface::initRuntime()`` method is + deprecated. You have two options to avoid the deprecation notice: if you + implement this method to store the environment for your custom filters, + functions, or tests, use the ``needs_environment`` option instead; if you + have more complex needs, explicitly implement + ``Twig_Extension_InitRuntimeInterface`` (not recommended). + +* As of Twig 1.23, the ``Twig_ExtensionInterface::getGlobals()`` method is + deprecated. Implement ``Twig_Extension_GlobalsInterface`` to avoid + deprecation notices. + +* As of Twig 1.26, the ``Twig_ExtensionInterface::getName()`` method is + deprecated and it is not used internally anymore. + +PEAR +---- + +PEAR support has been discontinued in Twig 1.15.1, and no PEAR packages are +provided anymore. Use Composer instead. + +Filters +------- + +* As of Twig 1.x, use ``Twig_SimpleFilter`` to add a filter. The following + classes and interfaces will be removed in 2.0: + + * ``Twig_FilterInterface`` + * ``Twig_FilterCallableInterface`` + * ``Twig_Filter`` + * ``Twig_Filter_Function`` + * ``Twig_Filter_Method`` + * ``Twig_Filter_Node`` + +* As of Twig 2.x, the ``Twig_SimpleFilter`` class is deprecated and will be + removed in Twig 3.x (use ``Twig_Filter`` instead). In Twig 2.x, + ``Twig_SimpleFilter`` is just an alias for ``Twig_Filter``. + +Functions +--------- + +* As of Twig 1.x, use ``Twig_SimpleFunction`` to add a function. The following + classes and interfaces will be removed in 2.0: + + * ``Twig_FunctionInterface`` + * ``Twig_FunctionCallableInterface`` + * ``Twig_Function`` + * ``Twig_Function_Function`` + * ``Twig_Function_Method`` + * ``Twig_Function_Node`` + +* As of Twig 2.x, the ``Twig_SimpleFunction`` class is deprecated and will be + removed in Twig 3.x (use ``Twig_Function`` instead). In Twig 2.x, + ``Twig_SimpleFunction`` is just an alias for ``Twig_Function``. + +Tests +----- + +* As of Twig 1.x, use ``Twig_SimpleTest`` to add a test. The following classes + and interfaces will be removed in 2.0: + + * ``Twig_TestInterface`` + * ``Twig_TestCallableInterface`` + * ``Twig_Test`` + * ``Twig_Test_Function`` + * ``Twig_Test_Method`` + * ``Twig_Test_Node`` + +* As of Twig 2.x, the ``Twig_SimpleTest`` class is deprecated and will be + removed in Twig 3.x (use ``Twig_Test`` instead). In Twig 2.x, + ``Twig_SimpleTest`` is just an alias for ``Twig_Test``. + +* The ``sameas`` and ``divisibleby`` tests are deprecated in favor of ``same + as`` and ``divisible by`` respectively. + +Tags +---- + +* As of Twig 1.x, the ``raw`` tag is deprecated. You should use ``verbatim`` + instead. + +Nodes +----- + +* As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig + 2.0. + +* As of Twig 1.26, ``Node::$nodes`` should only contains ``Twig_Node`` + instances, storing a ``null`` value is deprecated and won't be possible in + Twig 2.x. + +* As of Twig 1.27, the ``filename`` attribute on ``Twig_Node_Module`` is + deprecated. Use ``getName()`` instead. + +* As of Twig 1.27, the ``Twig_Node::getFilename()/Twig_Node::getLine()`` + methods are deprecated, use + ``Twig_Node::getTemplateName()/Twig_Node::getTemplateLine()`` instead. + +Interfaces +---------- + +* As of Twig 2.x, the following interfaces are deprecated and empty (they will + be removed in Twig 3.0): + +* ``Twig_CompilerInterface`` (use ``Twig_Compiler`` instead) +* ``Twig_LexerInterface`` (use ``Twig_Lexer`` instead) +* ``Twig_NodeInterface`` (use ``Twig_Node`` instead) +* ``Twig_ParserInterface`` (use ``Twig_Parser`` instead) +* ``Twig_ExistsLoaderInterface`` (merged with ``Twig_LoaderInterface``) +* ``Twig_SourceContextLoaderInterface`` (merged with ``Twig_LoaderInterface``) +* ``Twig_TemplateInterface`` (use ``Twig_Template`` instead, and use + those constants Twig_Template::ANY_CALL, Twig_Template::ARRAY_CALL, + Twig_Template::METHOD_CALL) + +Compiler +-------- + +* As of Twig 1.26, the ``Twig_Compiler::getFilename()`` has been deprecated. + You should not use it anyway as its values is not reliable. + +* As of Twig 1.27, the ``Twig_Compiler::addIndentation()`` has been deprecated. + Use ``Twig_Compiler::write('')`` instead. + +Loaders +------- + +* As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in + 2.0. You can render a string via ``Twig_Environment::createTemplate()``. + +* As of Twig 1.27, ``Twig_LoaderInterface::getSource()`` is deprecated. + Implement ``Twig_SourceContextLoaderInterface`` instead and use + ``getSourceContext()``. + +Node Visitors +------------- + +* Because of the removal of ``Twig_NodeInterface`` in 2.0, you need to extend + ``Twig_BaseNodeVisitor`` instead of implementing ``Twig_NodeVisitorInterface`` + directly to make your node visitors compatible with both Twig 1.x and 2.x. + +Globals +------- + +* As of Twig 2.x, the ability to register a global variable after the runtime + or the extensions have been initialized is not possible anymore (but + changing the value of an already registered global is possible). + +* As of Twig 1.x, using the ``_self`` global variable to get access to the + current ``Twig_Template`` instance is deprecated; most usages only need the + current template name, which will continue to work in Twig 2.0. In Twig 2.0, + ``_self`` returns the current template name instead of the current + ``Twig_Template`` instance. If you are using ``{{ _self.templateName }}``, + just replace it with ``{{ _self }}``. + +Miscellaneous +------------- + +* As of Twig 1.x, ``Twig_Environment::clearTemplateCache()``, + ``Twig_Environment::writeCacheFile()``, + ``Twig_Environment::clearCacheFiles()``, + ``Twig_Environment::getCacheFilename()``, + ``Twig_Environment::getTemplateClassPrefix()``, + ``Twig_Environment::getLexer()``, ``Twig_Environment::getParser()``, and + ``Twig_Environment::getCompiler()`` are deprecated and will be removed in 2.0. + +* As of Twig 1.x, ``Twig_Template::getEnvironment()`` and + ``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be + removed in 2.0. + +* As of Twig 1.21, setting the environment option ``autoescape`` to ``true`` is + deprecated and will be removed in 2.0. Use ``"html"`` instead. + +* As of Twig 1.27, ``Twig_Error::getTemplateFile()`` and + ``Twig_Error::setTemplateFile()`` are deprecated. Use + ``Twig_Error::getTemplateName()`` and ``Twig_Error::setTemplateName()`` + instead. + +* As of Twig 1.27, ``Twig_Template::getSource()`` is deprecated. Use + ``Twig_Template::getSourceContext()`` instead. + +* As of Twig 1.27, ``Twig_Parser::addHandler()`` and + ``Twig_Parser::addNodeVisitor()`` are deprecated and will be removed in 2.0. + +* As of Twig 1.29, some classes are marked as being final via the `@final` + annotation. Those classes will be marked as final in 2.0. diff --git a/vendor/twig/twig/doc/filters/abs.rst b/vendor/twig/twig/doc/filters/abs.rst new file mode 100644 index 000000000..22fa59d03 --- /dev/null +++ b/vendor/twig/twig/doc/filters/abs.rst @@ -0,0 +1,18 @@ +``abs`` +======= + +The ``abs`` filter returns the absolute value. + +.. code-block:: jinja + + {# number = -5 #} + + {{ number|abs }} + + {# outputs 5 #} + +.. note:: + + Internally, Twig uses the PHP `abs`_ function. + +.. _`abs`: http://php.net/abs diff --git a/vendor/twig/twig/doc/filters/batch.rst b/vendor/twig/twig/doc/filters/batch.rst new file mode 100644 index 000000000..f8b6fa9d4 --- /dev/null +++ b/vendor/twig/twig/doc/filters/batch.rst @@ -0,0 +1,51 @@ +``batch`` +========= + +.. versionadded:: 1.12.3 + The ``batch`` filter was added in Twig 1.12.3. + +The ``batch`` filter "batches" items by returning a list of lists with the +given number of items. A second parameter can be provided and used to fill in +missing items: + +.. code-block:: jinja + + {% set items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] %} + +

+ {% for row in items|batch(3, 'No item') %} + + {% for column in row %} + + {% endfor %} + + {% endfor %} +
{{ column }}
+ +The above example will be rendered as: + +.. code-block:: jinja + + + + + + + + + + + + + + + + + +
abc
def
gNo itemNo item
+ +Arguments +--------- + +* ``size``: The size of the batch; fractional numbers will be rounded up +* ``fill``: Used to fill in missing items diff --git a/vendor/twig/twig/doc/filters/capitalize.rst b/vendor/twig/twig/doc/filters/capitalize.rst new file mode 100644 index 000000000..10546a1f3 --- /dev/null +++ b/vendor/twig/twig/doc/filters/capitalize.rst @@ -0,0 +1,11 @@ +``capitalize`` +============== + +The ``capitalize`` filter capitalizes a value. The first character will be +uppercase, all others lowercase: + +.. code-block:: jinja + + {{ 'my first car'|capitalize }} + + {# outputs 'My first car' #} diff --git a/vendor/twig/twig/doc/filters/convert_encoding.rst b/vendor/twig/twig/doc/filters/convert_encoding.rst new file mode 100644 index 000000000..f4ebe5807 --- /dev/null +++ b/vendor/twig/twig/doc/filters/convert_encoding.rst @@ -0,0 +1,28 @@ +``convert_encoding`` +==================== + +.. versionadded:: 1.4 + The ``convert_encoding`` filter was added in Twig 1.4. + +The ``convert_encoding`` filter converts a string from one encoding to +another. The first argument is the expected output charset and the second one +is the input charset: + +.. code-block:: jinja + + {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }} + +.. note:: + + This filter relies on the `iconv`_ or `mbstring`_ extension, so one of + them must be installed. In case both are installed, `mbstring`_ is used by + default (Twig before 1.8.1 uses `iconv`_ by default). + +Arguments +--------- + +* ``to``: The output charset +* ``from``: The input charset + +.. _`iconv`: http://php.net/iconv +.. _`mbstring`: http://php.net/mbstring diff --git a/vendor/twig/twig/doc/filters/date.rst b/vendor/twig/twig/doc/filters/date.rst new file mode 100644 index 000000000..99a17ab75 --- /dev/null +++ b/vendor/twig/twig/doc/filters/date.rst @@ -0,0 +1,100 @@ +``date`` +======== + +.. versionadded:: 1.1 + The timezone support has been added in Twig 1.1. + +.. versionadded:: 1.5 + The default date format support has been added in Twig 1.5. + +.. versionadded:: 1.6.1 + The default timezone support has been added in Twig 1.6.1. + +.. versionadded:: 1.11.0 + The introduction of the false value for the timezone was introduced in Twig 1.11.0 + +The ``date`` filter formats a date to a given format: + +.. code-block:: jinja + + {{ post.published_at|date("m/d/Y") }} + +The format specifier is the same as supported by `date`_, +except when the filtered data is of type `DateInterval`_, when the format must conform to +`DateInterval::format`_ instead. + +The ``date`` filter accepts strings (it must be in a format supported by the +`strtotime`_ function), `DateTime`_ instances, or `DateInterval`_ instances. For +instance, to display the current date, filter the word "now": + +.. code-block:: jinja + + {{ "now"|date("m/d/Y") }} + +To escape words and characters in the date format use ``\\`` in front of each +character: + +.. code-block:: jinja + + {{ post.published_at|date("F jS \\a\\t g:ia") }} + +If the value passed to the ``date`` filter is ``null``, it will return the +current date by default. If an empty string is desired instead of the current +date, use a ternary operator: + +.. code-block:: jinja + + {{ post.published_at is empty ? "" : post.published_at|date("m/d/Y") }} + +If no format is provided, Twig will use the default one: ``F j, Y H:i``. This +default can be easily changed by calling the ``setDateFormat()`` method on the +``core`` extension instance. The first argument is the default format for +dates and the second one is the default format for date intervals: + +.. code-block:: php + + $twig = new Twig_Environment($loader); + $twig->getExtension('Twig_Extension_Core')->setDateFormat('d/m/Y', '%d days'); + + // before Twig 1.26 + $twig->getExtension('core')->setDateFormat('d/m/Y', '%d days'); + +Timezone +-------- + +By default, the date is displayed by applying the default timezone (the one +specified in php.ini or declared in Twig -- see below), but you can override +it by explicitly specifying a timezone: + +.. code-block:: jinja + + {{ post.published_at|date("m/d/Y", "Europe/Paris") }} + +If the date is already a DateTime object, and if you want to keep its current +timezone, pass ``false`` as the timezone value: + +.. code-block:: jinja + + {{ post.published_at|date("m/d/Y", false) }} + +The default timezone can also be set globally by calling ``setTimezone()``: + +.. code-block:: php + + $twig = new Twig_Environment($loader); + $twig->getExtension('Twig_Extension_Core')->setTimezone('Europe/Paris'); + + // before Twig 1.26 + $twig->getExtension('core')->setTimezone('Europe/Paris'); + +Arguments +--------- + +* ``format``: The date format +* ``timezone``: The date timezone + +.. _`strtotime`: http://www.php.net/strtotime +.. _`DateTime`: http://www.php.net/DateTime +.. _`DateInterval`: http://www.php.net/DateInterval +.. _`date`: http://www.php.net/date +.. _`DateInterval::format`: http://www.php.net/DateInterval.format diff --git a/vendor/twig/twig/doc/filters/date_modify.rst b/vendor/twig/twig/doc/filters/date_modify.rst new file mode 100644 index 000000000..add40b56b --- /dev/null +++ b/vendor/twig/twig/doc/filters/date_modify.rst @@ -0,0 +1,23 @@ +``date_modify`` +=============== + +.. versionadded:: 1.9.0 + The date_modify filter has been added in Twig 1.9.0. + +The ``date_modify`` filter modifies a date with a given modifier string: + +.. code-block:: jinja + + {{ post.published_at|date_modify("+1 day")|date("m/d/Y") }} + +The ``date_modify`` filter accepts strings (it must be in a format supported +by the `strtotime`_ function) or `DateTime`_ instances. You can easily combine +it with the :doc:`date` filter for formatting. + +Arguments +--------- + +* ``modifier``: The modifier + +.. _`strtotime`: http://www.php.net/strtotime +.. _`DateTime`: http://www.php.net/DateTime diff --git a/vendor/twig/twig/doc/filters/default.rst b/vendor/twig/twig/doc/filters/default.rst new file mode 100644 index 000000000..641ac6e75 --- /dev/null +++ b/vendor/twig/twig/doc/filters/default.rst @@ -0,0 +1,33 @@ +``default`` +=========== + +The ``default`` filter returns the passed default value if the value is +undefined or empty, otherwise the value of the variable: + +.. code-block:: jinja + + {{ var|default('var is not defined') }} + + {{ var.foo|default('foo item on var is not defined') }} + + {{ var['foo']|default('foo item on var is not defined') }} + + {{ ''|default('passed var is empty') }} + +When using the ``default`` filter on an expression that uses variables in some +method calls, be sure to use the ``default`` filter whenever a variable can be +undefined: + +.. code-block:: jinja + + {{ var.method(foo|default('foo'))|default('foo') }} + +.. note:: + + Read the documentation for the :doc:`defined<../tests/defined>` and + :doc:`empty<../tests/empty>` tests to learn more about their semantics. + +Arguments +--------- + +* ``default``: The default value diff --git a/vendor/twig/twig/doc/filters/escape.rst b/vendor/twig/twig/doc/filters/escape.rst new file mode 100644 index 000000000..21491343b --- /dev/null +++ b/vendor/twig/twig/doc/filters/escape.rst @@ -0,0 +1,119 @@ +``escape`` +========== + +.. versionadded:: 1.9.0 + The ``css``, ``url``, and ``html_attr`` strategies were added in Twig + 1.9.0. + +.. versionadded:: 1.14.0 + The ability to define custom escapers was added in Twig 1.14.0. + +The ``escape`` filter escapes a string for safe insertion into the final +output. It supports different escaping strategies depending on the template +context. + +By default, it uses the HTML escaping strategy: + +.. code-block:: jinja + + {{ user.username|escape }} + +For convenience, the ``e`` filter is defined as an alias: + +.. code-block:: jinja + + {{ user.username|e }} + +The ``escape`` filter can also be used in other contexts than HTML thanks to +an optional argument which defines the escaping strategy to use: + +.. code-block:: jinja + + {{ user.username|e }} + {# is equivalent to #} + {{ user.username|e('html') }} + +And here is how to escape variables included in JavaScript code: + +.. code-block:: jinja + + {{ user.username|escape('js') }} + {{ user.username|e('js') }} + +The ``escape`` filter supports the following escaping strategies: + +* ``html``: escapes a string for the **HTML body** context. + +* ``js``: escapes a string for the **JavaScript context**. + +* ``css``: escapes a string for the **CSS context**. CSS escaping can be + applied to any string being inserted into CSS and escapes everything except + alphanumerics. + +* ``url``: escapes a string for the **URI or parameter contexts**. This should + not be used to escape an entire URI; only a subcomponent being inserted. + +* ``html_attr``: escapes a string for the **HTML attribute** context. + +.. note:: + + Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function + for the HTML escaping strategy. + +.. caution:: + + When using automatic escaping, Twig tries to not double-escape a variable + when the automatic escaping strategy is the same as the one applied by the + escape filter; but that does not work when using a variable as the + escaping strategy: + + .. code-block:: jinja + + {% set strategy = 'html' %} + + {% autoescape 'html' %} + {{ var|escape('html') }} {# won't be double-escaped #} + {{ var|escape(strategy) }} {# will be double-escaped #} + {% endautoescape %} + + When using a variable as the escaping strategy, you should disable + automatic escaping: + + .. code-block:: jinja + + {% set strategy = 'html' %} + + {% autoescape 'html' %} + {{ var|escape(strategy)|raw }} {# won't be double-escaped #} + {% endautoescape %} + +Custom Escapers +--------------- + +You can define custom escapers by calling the ``setEscaper()`` method on the +``core`` extension instance. The first argument is the escaper name (to be +used in the ``escape`` call) and the second one must be a valid PHP callable: + +.. code-block:: php + + $twig = new Twig_Environment($loader); + $twig->getExtension('Twig_Extension_Core')->setEscaper('csv', 'csv_escaper'); + + // before Twig 1.26 + $twig->getExtension('core')->setEscaper('csv', 'csv_escaper'); + +When called by Twig, the callable receives the Twig environment instance, the +string to escape, and the charset. + +.. note:: + + Built-in escapers cannot be overridden mainly they should be considered as + the final implementation and also for better performance. + +Arguments +--------- + +* ``strategy``: The escaping strategy +* ``charset``: The string charset + +.. _`htmlspecialchars`: http://php.net/htmlspecialchars diff --git a/vendor/twig/twig/doc/filters/first.rst b/vendor/twig/twig/doc/filters/first.rst new file mode 100644 index 000000000..674c1f9ed --- /dev/null +++ b/vendor/twig/twig/doc/filters/first.rst @@ -0,0 +1,25 @@ +``first`` +========= + +.. versionadded:: 1.12.2 + The ``first`` filter was added in Twig 1.12.2. + +The ``first`` filter returns the first "element" of a sequence, a mapping, or +a string: + +.. code-block:: jinja + + {{ [1, 2, 3, 4]|first }} + {# outputs 1 #} + + {{ { a: 1, b: 2, c: 3, d: 4 }|first }} + {# outputs 1 #} + + {{ '1234'|first }} + {# outputs 1 #} + +.. note:: + + It also works with objects implementing the `Traversable`_ interface. + +.. _`Traversable`: http://php.net/manual/en/class.traversable.php diff --git a/vendor/twig/twig/doc/filters/format.rst b/vendor/twig/twig/doc/filters/format.rst new file mode 100644 index 000000000..f8effd9a9 --- /dev/null +++ b/vendor/twig/twig/doc/filters/format.rst @@ -0,0 +1,16 @@ +``format`` +========== + +The ``format`` filter formats a given string by replacing the placeholders +(placeholders follows the `sprintf`_ notation): + +.. code-block:: jinja + + {{ "I like %s and %s."|format(foo, "bar") }} + + {# outputs I like foo and bar + if the foo parameter equals to the foo string. #} + +.. _`sprintf`: http://www.php.net/sprintf + +.. seealso:: :doc:`replace` diff --git a/vendor/twig/twig/doc/filters/index.rst b/vendor/twig/twig/doc/filters/index.rst new file mode 100644 index 000000000..8daa96118 --- /dev/null +++ b/vendor/twig/twig/doc/filters/index.rst @@ -0,0 +1,37 @@ +Filters +======= + +.. toctree:: + :maxdepth: 1 + + abs + batch + capitalize + convert_encoding + date + date_modify + default + escape + first + format + join + json_encode + keys + last + length + lower + merge + nl2br + number_format + raw + replace + reverse + round + slice + sort + split + striptags + title + trim + upper + url_encode diff --git a/vendor/twig/twig/doc/filters/join.rst b/vendor/twig/twig/doc/filters/join.rst new file mode 100644 index 000000000..2fab94528 --- /dev/null +++ b/vendor/twig/twig/doc/filters/join.rst @@ -0,0 +1,23 @@ +``join`` +======== + +The ``join`` filter returns a string which is the concatenation of the items +of a sequence: + +.. code-block:: jinja + + {{ [1, 2, 3]|join }} + {# returns 123 #} + +The separator between elements is an empty string per default, but you can +define it with the optional first parameter: + +.. code-block:: jinja + + {{ [1, 2, 3]|join('|') }} + {# outputs 1|2|3 #} + +Arguments +--------- + +* ``glue``: The separator diff --git a/vendor/twig/twig/doc/filters/json_encode.rst b/vendor/twig/twig/doc/filters/json_encode.rst new file mode 100644 index 000000000..a39bb476e --- /dev/null +++ b/vendor/twig/twig/doc/filters/json_encode.rst @@ -0,0 +1,21 @@ +``json_encode`` +=============== + +The ``json_encode`` filter returns the JSON representation of a value: + +.. code-block:: jinja + + {{ data|json_encode() }} + +.. note:: + + Internally, Twig uses the PHP `json_encode`_ function. + +Arguments +--------- + +* ``options``: A bitmask of `json_encode options`_ (``{{ + data|json_encode(constant('JSON_PRETTY_PRINT')) }}``) + +.. _`json_encode`: http://php.net/json_encode +.. _`json_encode options`: http://www.php.net/manual/en/json.constants.php diff --git a/vendor/twig/twig/doc/filters/keys.rst b/vendor/twig/twig/doc/filters/keys.rst new file mode 100644 index 000000000..e4f090c6b --- /dev/null +++ b/vendor/twig/twig/doc/filters/keys.rst @@ -0,0 +1,11 @@ +``keys`` +======== + +The ``keys`` filter returns the keys of an array. It is useful when you want to +iterate over the keys of an array: + +.. code-block:: jinja + + {% for key in array|keys %} + ... + {% endfor %} diff --git a/vendor/twig/twig/doc/filters/last.rst b/vendor/twig/twig/doc/filters/last.rst new file mode 100644 index 000000000..345b6573d --- /dev/null +++ b/vendor/twig/twig/doc/filters/last.rst @@ -0,0 +1,25 @@ +``last`` +======== + +.. versionadded:: 1.12.2 + The ``last`` filter was added in Twig 1.12.2. + +The ``last`` filter returns the last "element" of a sequence, a mapping, or +a string: + +.. code-block:: jinja + + {{ [1, 2, 3, 4]|last }} + {# outputs 4 #} + + {{ { a: 1, b: 2, c: 3, d: 4 }|last }} + {# outputs 4 #} + + {{ '1234'|last }} + {# outputs 4 #} + +.. note:: + + It also works with objects implementing the `Traversable`_ interface. + +.. _`Traversable`: http://php.net/manual/en/class.traversable.php diff --git a/vendor/twig/twig/doc/filters/length.rst b/vendor/twig/twig/doc/filters/length.rst new file mode 100644 index 000000000..5620f3b3c --- /dev/null +++ b/vendor/twig/twig/doc/filters/length.rst @@ -0,0 +1,21 @@ +``length`` +========== + +.. versionadded:: 1.33 + + Support for the ``__toString()`` magic method has been added in Twig 1.33. + +The ``length`` filter returns the number of items of a sequence or mapping, or +the length of a string. + +For objects that implement the ``Countable`` interface, ``length`` will use the +return value of the ``count()`` method. + +For objects that implement the ``__toString()`` magic method (and not ``Countable``), +it will return the length of the string provided by that method. + +.. code-block:: jinja + + {% if users|length > 10 %} + ... + {% endif %} diff --git a/vendor/twig/twig/doc/filters/lower.rst b/vendor/twig/twig/doc/filters/lower.rst new file mode 100644 index 000000000..ef9faa90a --- /dev/null +++ b/vendor/twig/twig/doc/filters/lower.rst @@ -0,0 +1,10 @@ +``lower`` +========= + +The ``lower`` filter converts a value to lowercase: + +.. code-block:: jinja + + {{ 'WELCOME'|lower }} + + {# outputs 'welcome' #} diff --git a/vendor/twig/twig/doc/filters/merge.rst b/vendor/twig/twig/doc/filters/merge.rst new file mode 100644 index 000000000..88780dd6f --- /dev/null +++ b/vendor/twig/twig/doc/filters/merge.rst @@ -0,0 +1,48 @@ +``merge`` +========= + +The ``merge`` filter merges an array with another array: + +.. code-block:: jinja + + {% set values = [1, 2] %} + + {% set values = values|merge(['apple', 'orange']) %} + + {# values now contains [1, 2, 'apple', 'orange'] #} + +New values are added at the end of the existing ones. + +The ``merge`` filter also works on hashes: + +.. code-block:: jinja + + {% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %} + + {% set items = items|merge({ 'peugeot': 'car', 'renault': 'car' }) %} + + {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car', 'renault': 'car' } #} + +For hashes, the merging process occurs on the keys: if the key does not +already exist, it is added but if the key already exists, its value is +overridden. + +.. tip:: + + If you want to ensure that some values are defined in an array (by given + default values), reverse the two elements in the call: + + .. code-block:: jinja + + {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %} + + {% set items = { 'apple': 'unknown' }|merge(items) %} + + {# items now contains { 'apple': 'fruit', 'orange': 'fruit' } #} + +.. note:: + + Internally, Twig uses the PHP `array_merge`_ function. It supports + Traversable objects by transforming those to arrays. + +.. _`array_merge`: http://php.net/array_merge diff --git a/vendor/twig/twig/doc/filters/nl2br.rst b/vendor/twig/twig/doc/filters/nl2br.rst new file mode 100644 index 000000000..5c923e143 --- /dev/null +++ b/vendor/twig/twig/doc/filters/nl2br.rst @@ -0,0 +1,22 @@ +``nl2br`` +========= + +.. versionadded:: 1.5 + The ``nl2br`` filter was added in Twig 1.5. + +The ``nl2br`` filter inserts HTML line breaks before all newlines in a string: + +.. code-block:: jinja + + {{ "I like Twig.\nYou will like it too."|nl2br }} + {# outputs + + I like Twig.
+ You will like it too. + + #} + +.. note:: + + The ``nl2br`` filter pre-escapes the input before applying the + transformation. diff --git a/vendor/twig/twig/doc/filters/number_format.rst b/vendor/twig/twig/doc/filters/number_format.rst new file mode 100644 index 000000000..c5425ea72 --- /dev/null +++ b/vendor/twig/twig/doc/filters/number_format.rst @@ -0,0 +1,56 @@ +``number_format`` +================= + +.. versionadded:: 1.5 + The ``number_format`` filter was added in Twig 1.5 + +The ``number_format`` filter formats numbers. It is a wrapper around PHP's +`number_format`_ function: + +.. code-block:: jinja + + {{ 200.35|number_format }} + +You can control the number of decimal places, decimal point, and thousands +separator using the additional arguments: + +.. code-block:: jinja + + {{ 9800.333|number_format(2, '.', ',') }} + +To format negative numbers, wrap the number with parentheses (needed because of +Twig's :ref:`precedence of operators `: + +.. code-block:: jinja + + {{ -9800.333|number_format(2, '.', ',') }} {# outputs : -9 #} + {{ (-9800.333)|number_format(2, '.', ',') }} {# outputs : -9.800,33 #} + +If no formatting options are provided then Twig will use the default formatting +options of: + +* 0 decimal places. +* ``.`` as the decimal point. +* ``,`` as the thousands separator. + +These defaults can be easily changed through the core extension: + +.. code-block:: php + + $twig = new Twig_Environment($loader); + $twig->getExtension('Twig_Extension_Core')->setNumberFormat(3, '.', ','); + + // before Twig 1.26 + $twig->getExtension('core')->setNumberFormat(3, '.', ','); + +The defaults set for ``number_format`` can be over-ridden upon each call using the +additional parameters. + +Arguments +--------- + +* ``decimal``: The number of decimal points to display +* ``decimal_point``: The character(s) to use for the decimal point +* ``thousand_sep``: The character(s) to use for the thousands separator + +.. _`number_format`: http://php.net/number_format diff --git a/vendor/twig/twig/doc/filters/raw.rst b/vendor/twig/twig/doc/filters/raw.rst new file mode 100644 index 000000000..e5e5b12ec --- /dev/null +++ b/vendor/twig/twig/doc/filters/raw.rst @@ -0,0 +1,36 @@ +``raw`` +======= + +The ``raw`` filter marks the value as being "safe", which means that in an +environment with automatic escaping enabled this variable will not be escaped +if ``raw`` is the last filter applied to it: + +.. code-block:: jinja + + {% autoescape %} + {{ var|raw }} {# var won't be escaped #} + {% endautoescape %} + +.. note:: + + Be careful when using the ``raw`` filter inside expressions: + + .. code-block:: jinja + + {% autoescape %} + {% set hello = 'Hello' %} + {% set hola = 'Hola' %} + + {{ false ? 'Hola' : hello|raw }} + does not render the same as + {{ false ? hola : hello|raw }} + but renders the same as + {{ (false ? hola : hello)|raw }} + {% endautoescape %} + + The first ternary statement is not escaped: ``hello`` is marked as being + safe and Twig does not escape static values (see + :doc:`escape<../tags/autoescape>`). In the second ternary statement, even + if ``hello`` is marked as safe, ``hola`` remains unsafe and so is the whole + expression. The third ternary statement is marked as safe and the result is + not escaped. diff --git a/vendor/twig/twig/doc/filters/replace.rst b/vendor/twig/twig/doc/filters/replace.rst new file mode 100644 index 000000000..8dbb74593 --- /dev/null +++ b/vendor/twig/twig/doc/filters/replace.rst @@ -0,0 +1,19 @@ +``replace`` +=========== + +The ``replace`` filter formats a given string by replacing the placeholders +(placeholders are free-form): + +.. code-block:: jinja + + {{ "I like %this% and %that%."|replace({'%this%': foo, '%that%': "bar"}) }} + + {# outputs I like foo and bar + if the foo parameter equals to the foo string. #} + +Arguments +--------- + +* ``from``: The placeholder values + +.. seealso:: :doc:`format` diff --git a/vendor/twig/twig/doc/filters/reverse.rst b/vendor/twig/twig/doc/filters/reverse.rst new file mode 100644 index 000000000..76fd2c1ab --- /dev/null +++ b/vendor/twig/twig/doc/filters/reverse.rst @@ -0,0 +1,47 @@ +``reverse`` +=========== + +.. versionadded:: 1.6 + Support for strings has been added in Twig 1.6. + +The ``reverse`` filter reverses a sequence, a mapping, or a string: + +.. code-block:: jinja + + {% for user in users|reverse %} + ... + {% endfor %} + + {{ '1234'|reverse }} + + {# outputs 4321 #} + +.. tip:: + + For sequences and mappings, numeric keys are not preserved. To reverse + them as well, pass ``true`` as an argument to the ``reverse`` filter: + + .. code-block:: jinja + + {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse %} + {{ key }}: {{ value }} + {%- endfor %} + + {# output: 0: c 1: b 2: a #} + + {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse(true) %} + {{ key }}: {{ value }} + {%- endfor %} + + {# output: 3: c 2: b 1: a #} + +.. note:: + + It also works with objects implementing the `Traversable`_ interface. + +Arguments +--------- + +* ``preserve_keys``: Preserve keys when reversing a mapping or a sequence. + +.. _`Traversable`: http://php.net/Traversable diff --git a/vendor/twig/twig/doc/filters/round.rst b/vendor/twig/twig/doc/filters/round.rst new file mode 100644 index 000000000..2521cf16a --- /dev/null +++ b/vendor/twig/twig/doc/filters/round.rst @@ -0,0 +1,37 @@ +``round`` +========= + +.. versionadded:: 1.15.0 + The ``round`` filter was added in Twig 1.15.0. + +The ``round`` filter rounds a number to a given precision: + +.. code-block:: jinja + + {{ 42.55|round }} + {# outputs 43 #} + + {{ 42.55|round(1, 'floor') }} + {# outputs 42.5 #} + +The ``round`` filter takes two optional arguments; the first one specifies the +precision (default is ``0``) and the second the rounding method (default is +``common``): + +* ``common`` rounds either up or down (rounds the value up to precision decimal + places away from zero, when it is half way there -- making 1.5 into 2 and + -1.5 into -2); + +* ``ceil`` always rounds up; + +* ``floor`` always rounds down. + +.. note:: + + The ``//`` operator is equivalent to ``|round(0, 'floor')``. + +Arguments +--------- + +* ``precision``: The rounding precision +* ``method``: The rounding method diff --git a/vendor/twig/twig/doc/filters/slice.rst b/vendor/twig/twig/doc/filters/slice.rst new file mode 100644 index 000000000..70bf139e6 --- /dev/null +++ b/vendor/twig/twig/doc/filters/slice.rst @@ -0,0 +1,71 @@ +``slice`` +=========== + +.. versionadded:: 1.6 + The ``slice`` filter was added in Twig 1.6. + +The ``slice`` filter extracts a slice of a sequence, a mapping, or a string: + +.. code-block:: jinja + + {% for i in [1, 2, 3, 4, 5]|slice(1, 2) %} + {# will iterate over 2 and 3 #} + {% endfor %} + + {{ '12345'|slice(1, 2) }} + + {# outputs 23 #} + +You can use any valid expression for both the start and the length: + +.. code-block:: jinja + + {% for i in [1, 2, 3, 4, 5]|slice(start, length) %} + {# ... #} + {% endfor %} + +As syntactic sugar, you can also use the ``[]`` notation: + +.. code-block:: jinja + + {% for i in [1, 2, 3, 4, 5][start:length] %} + {# ... #} + {% endfor %} + + {{ '12345'[1:2] }} {# will display "23" #} + + {# you can omit the first argument -- which is the same as 0 #} + {{ '12345'[:2] }} {# will display "12" #} + + {# you can omit the last argument -- which will select everything till the end #} + {{ '12345'[2:] }} {# will display "345" #} + +The ``slice`` filter works as the `array_slice`_ PHP function for arrays and +`mb_substr`_ for strings with a fallback to `substr`_. + +If the start is non-negative, the sequence will start at that start in the +variable. If start is negative, the sequence will start that far from the end +of the variable. + +If length is given and is positive, then the sequence will have up to that +many elements in it. If the variable is shorter than the length, then only the +available variable elements will be present. If length is given and is +negative then the sequence will stop that many elements from the end of the +variable. If it is omitted, then the sequence will have everything from offset +up until the end of the variable. + +.. note:: + + It also works with objects implementing the `Traversable`_ interface. + +Arguments +--------- + +* ``start``: The start of the slice +* ``length``: The size of the slice +* ``preserve_keys``: Whether to preserve key or not (when the input is an array) + +.. _`Traversable`: http://php.net/manual/en/class.traversable.php +.. _`array_slice`: http://php.net/array_slice +.. _`mb_substr` : http://php.net/mb-substr +.. _`substr`: http://php.net/substr diff --git a/vendor/twig/twig/doc/filters/sort.rst b/vendor/twig/twig/doc/filters/sort.rst new file mode 100644 index 000000000..350207f8e --- /dev/null +++ b/vendor/twig/twig/doc/filters/sort.rst @@ -0,0 +1,18 @@ +``sort`` +======== + +The ``sort`` filter sorts an array: + +.. code-block:: jinja + + {% for user in users|sort %} + ... + {% endfor %} + +.. note:: + + Internally, Twig uses the PHP `asort`_ function to maintain index + association. It supports Traversable objects by transforming + those to arrays. + +.. _`asort`: http://php.net/asort diff --git a/vendor/twig/twig/doc/filters/split.rst b/vendor/twig/twig/doc/filters/split.rst new file mode 100644 index 000000000..bbc6d798f --- /dev/null +++ b/vendor/twig/twig/doc/filters/split.rst @@ -0,0 +1,53 @@ +``split`` +========= + +.. versionadded:: 1.10.3 + The ``split`` filter was added in Twig 1.10.3. + +The ``split`` filter splits a string by the given delimiter and returns a list +of strings: + +.. code-block:: jinja + + {% set foo = "one,two,three"|split(',') %} + {# foo contains ['one', 'two', 'three'] #} + +You can also pass a ``limit`` argument: + + * If ``limit`` is positive, the returned array will contain a maximum of + limit elements with the last element containing the rest of string; + + * If ``limit`` is negative, all components except the last -limit are + returned; + + * If ``limit`` is zero, then this is treated as 1. + +.. code-block:: jinja + + {% set foo = "one,two,three,four,five"|split(',', 3) %} + {# foo contains ['one', 'two', 'three,four,five'] #} + +If the ``delimiter`` is an empty string, then value will be split by equal +chunks. Length is set by the ``limit`` argument (one character by default). + +.. code-block:: jinja + + {% set foo = "123"|split('') %} + {# foo contains ['1', '2', '3'] #} + + {% set bar = "aabbcc"|split('', 2) %} + {# bar contains ['aa', 'bb', 'cc'] #} + +.. note:: + + Internally, Twig uses the PHP `explode`_ or `str_split`_ (if delimiter is + empty) functions for string splitting. + +Arguments +--------- + +* ``delimiter``: The delimiter +* ``limit``: The limit argument + +.. _`explode`: http://php.net/explode +.. _`str_split`: http://php.net/str_split diff --git a/vendor/twig/twig/doc/filters/striptags.rst b/vendor/twig/twig/doc/filters/striptags.rst new file mode 100644 index 000000000..82953b7b6 --- /dev/null +++ b/vendor/twig/twig/doc/filters/striptags.rst @@ -0,0 +1,29 @@ +``striptags`` +============= + +The ``striptags`` filter strips SGML/XML tags and replace adjacent whitespace +by one space: + +.. code-block:: jinja + + {{ some_html|striptags }} + +You can also provide tags which should not be stripped: + +.. code-block:: jinja + + {{ some_html|striptags('

') }} + +In this example, the ``
``, ``
``, ``

``, and ``

`` tags won't be +removed from the string. + +.. note:: + + Internally, Twig uses the PHP `strip_tags`_ function. + +Arguments +--------- + +* ``allowable_tags``: Tags which should not be stripped + +.. _`strip_tags`: http://php.net/strip_tags diff --git a/vendor/twig/twig/doc/filters/title.rst b/vendor/twig/twig/doc/filters/title.rst new file mode 100644 index 000000000..c5a318e85 --- /dev/null +++ b/vendor/twig/twig/doc/filters/title.rst @@ -0,0 +1,11 @@ +``title`` +========= + +The ``title`` filter returns a titlecased version of the value. Words will +start with uppercase letters, all remaining characters are lowercase: + +.. code-block:: jinja + + {{ 'my first car'|title }} + + {# outputs 'My First Car' #} diff --git a/vendor/twig/twig/doc/filters/trim.rst b/vendor/twig/twig/doc/filters/trim.rst new file mode 100644 index 000000000..b598363c2 --- /dev/null +++ b/vendor/twig/twig/doc/filters/trim.rst @@ -0,0 +1,45 @@ +``trim`` +======== + +.. versionadded:: 1.32 + The ``side`` argument was added in Twig 1.32. + +.. versionadded:: 1.6.2 + The ``trim`` filter was added in Twig 1.6.2. + +The ``trim`` filter strips whitespace (or other characters) from the beginning +and end of a string: + +.. code-block:: jinja + + {{ ' I like Twig. '|trim }} + + {# outputs 'I like Twig.' #} + + {{ ' I like Twig.'|trim('.') }} + + {# outputs ' I like Twig' #} + + {{ ' I like Twig. '|trim(side='left') }} + + {# outputs 'I like Twig. ' #} + + {{ ' I like Twig. '|trim(' ', 'right') }} + + {# outputs ' I like Twig.' #} + +.. note:: + + Internally, Twig uses the PHP `trim`_, `ltrim`_, and `rtrim`_ functions. + +Arguments +--------- + +* ``character_mask``: The characters to strip + +* ``side``: The default is to strip from the left and the right (`both`) sides, but `left` + and `right` will strip from either the left side or right side only + +.. _`trim`: http://php.net/trim +.. _`ltrim`: http://php.net/ltrim +.. _`rtrim`: http://php.net/rtrim diff --git a/vendor/twig/twig/doc/filters/upper.rst b/vendor/twig/twig/doc/filters/upper.rst new file mode 100644 index 000000000..561cebe33 --- /dev/null +++ b/vendor/twig/twig/doc/filters/upper.rst @@ -0,0 +1,10 @@ +``upper`` +========= + +The ``upper`` filter converts a value to uppercase: + +.. code-block:: jinja + + {{ 'welcome'|upper }} + + {# outputs 'WELCOME' #} diff --git a/vendor/twig/twig/doc/filters/url_encode.rst b/vendor/twig/twig/doc/filters/url_encode.rst new file mode 100644 index 000000000..5944e59cd --- /dev/null +++ b/vendor/twig/twig/doc/filters/url_encode.rst @@ -0,0 +1,34 @@ +``url_encode`` +============== + +.. versionadded:: 1.12.3 + Support for encoding an array as query string was added in Twig 1.12.3. + +.. versionadded:: 1.16.0 + The ``raw`` argument was removed in Twig 1.16.0. Twig now always encodes + according to RFC 3986. + +The ``url_encode`` filter percent encodes a given string as URL segment +or an array as query string: + +.. code-block:: jinja + + {{ "path-seg*ment"|url_encode }} + {# outputs "path-seg%2Ament" #} + + {{ "string with spaces"|url_encode }} + {# outputs "string%20with%20spaces" #} + + {{ {'param': 'value', 'foo': 'bar'}|url_encode }} + {# outputs "param=value&foo=bar" #} + +.. note:: + + Internally, Twig uses the PHP `urlencode`_ (or `rawurlencode`_ if you pass + ``true`` as the first parameter) or the `http_build_query`_ function. Note + that as of Twig 1.16.0, ``urlencode`` **always** uses ``rawurlencode`` (the + ``raw`` argument was removed.) + +.. _`urlencode`: http://php.net/urlencode +.. _`rawurlencode`: http://php.net/rawurlencode +.. _`http_build_query`: http://php.net/http_build_query diff --git a/vendor/twig/twig/doc/functions/attribute.rst b/vendor/twig/twig/doc/functions/attribute.rst new file mode 100644 index 000000000..ceba96b05 --- /dev/null +++ b/vendor/twig/twig/doc/functions/attribute.rst @@ -0,0 +1,26 @@ +``attribute`` +============= + +.. versionadded:: 1.2 + The ``attribute`` function was added in Twig 1.2. + +The ``attribute`` function can be used to access a "dynamic" attribute of a +variable: + +.. code-block:: jinja + + {{ attribute(object, method) }} + {{ attribute(object, method, arguments) }} + {{ attribute(array, item) }} + +In addition, the ``defined`` test can check for the existence of a dynamic +attribute: + +.. code-block:: jinja + + {{ attribute(object, method) is defined ? 'Method exists' : 'Method does not exist' }} + +.. note:: + + The resolution algorithm is the same as the one used for the ``.`` + notation, except that the item can be any valid expression. diff --git a/vendor/twig/twig/doc/functions/block.rst b/vendor/twig/twig/doc/functions/block.rst new file mode 100644 index 000000000..f5d683c73 --- /dev/null +++ b/vendor/twig/twig/doc/functions/block.rst @@ -0,0 +1,41 @@ +``block`` +========= + +.. versionadded: 1.28 + Using ``block`` with the ``defined`` test was added in Twig 1.28. + +.. versionadded: 1.28 + Support for the template argument was added in Twig 1.28. + +When a template uses inheritance and if you want to print a block multiple +times, use the ``block`` function: + +.. code-block:: jinja + + {% block title %}{% endblock %} + +

{{ block('title') }}

+ + {% block body %}{% endblock %} + +The ``block`` function can also be used to display one block of another +template: + +.. code-block:: jinja + + {{ block("title", "common_blocks.twig") }} + +Use the ``defined`` test to check if a block exists in the context of the +current template: + +.. code-block:: jinja + + {% if block("footer") is defined %} + ... + {% endif %} + + {% if block("footer", "common_blocks.twig") is defined %} + ... + {% endif %} + +.. seealso:: :doc:`extends<../tags/extends>`, :doc:`parent<../functions/parent>` diff --git a/vendor/twig/twig/doc/functions/constant.rst b/vendor/twig/twig/doc/functions/constant.rst new file mode 100644 index 000000000..97aa5c8f3 --- /dev/null +++ b/vendor/twig/twig/doc/functions/constant.rst @@ -0,0 +1,29 @@ +``constant`` +============ + +.. versionadded: 1.12.1 + constant now accepts object instances as the second argument. + +.. versionadded: 1.28 + Using ``constant`` with the ``defined`` test was added in Twig 1.28. + +``constant`` returns the constant value for a given string: + +.. code-block:: jinja + + {{ some_date|date(constant('DATE_W3C')) }} + {{ constant('Namespace\\Classname::CONSTANT_NAME') }} + +As of 1.12.1 you can read constants from object instances as well: + +.. code-block:: jinja + + {{ constant('RSS', date) }} + +Use the ``defined`` test to check if a constant is defined: + +.. code-block:: jinja + + {% if constant('SOME_CONST') is defined %} + ... + {% endif %} diff --git a/vendor/twig/twig/doc/functions/cycle.rst b/vendor/twig/twig/doc/functions/cycle.rst new file mode 100644 index 000000000..e34349323 --- /dev/null +++ b/vendor/twig/twig/doc/functions/cycle.rst @@ -0,0 +1,28 @@ +``cycle`` +========= + +The ``cycle`` function cycles on an array of values: + +.. code-block:: jinja + + {% set start_year = date() | date('Y') %} + {% set end_year = start_year + 5 %} + + {% for year in start_year..end_year %} + {{ cycle(['odd', 'even'], loop.index0) }} + {% endfor %} + +The array can contain any number of values: + +.. code-block:: jinja + + {% set fruits = ['apple', 'orange', 'citrus'] %} + + {% for i in 0..10 %} + {{ cycle(fruits, i) }} + {% endfor %} + +Arguments +--------- + +* ``position``: The cycle position diff --git a/vendor/twig/twig/doc/functions/date.rst b/vendor/twig/twig/doc/functions/date.rst new file mode 100644 index 000000000..158dd6a65 --- /dev/null +++ b/vendor/twig/twig/doc/functions/date.rst @@ -0,0 +1,55 @@ +``date`` +======== + +.. versionadded:: 1.6 + The date function has been added in Twig 1.6. + +.. versionadded:: 1.6.1 + The default timezone support has been added in Twig 1.6.1. + +Converts an argument to a date to allow date comparison: + +.. code-block:: jinja + + {% if date(user.created_at) < date('-2days') %} + {# do something #} + {% endif %} + +The argument must be in one of PHP’s supported `date and time formats`_. + +You can pass a timezone as the second argument: + +.. code-block:: jinja + + {% if date(user.created_at) < date('-2days', 'Europe/Paris') %} + {# do something #} + {% endif %} + +If no argument is passed, the function returns the current date: + +.. code-block:: jinja + + {% if date(user.created_at) < date() %} + {# always! #} + {% endif %} + +.. note:: + + You can set the default timezone globally by calling ``setTimezone()`` on + the ``core`` extension instance: + + .. code-block:: php + + $twig = new Twig_Environment($loader); + $twig->getExtension('Twig_Extension_Core')->setTimezone('Europe/Paris'); + + // before Twig 1.26 + $twig->getExtension('core')->setTimezone('Europe/Paris'); + +Arguments +--------- + +* ``date``: The date +* ``timezone``: The timezone + +.. _`date and time formats`: http://php.net/manual/en/datetime.formats.php diff --git a/vendor/twig/twig/doc/functions/dump.rst b/vendor/twig/twig/doc/functions/dump.rst new file mode 100644 index 000000000..a231f089e --- /dev/null +++ b/vendor/twig/twig/doc/functions/dump.rst @@ -0,0 +1,69 @@ +``dump`` +======== + +.. versionadded:: 1.5 + The ``dump`` function was added in Twig 1.5. + +The ``dump`` function dumps information about a template variable. This is +mostly useful to debug a template that does not behave as expected by +introspecting its variables: + +.. code-block:: jinja + + {{ dump(user) }} + +.. note:: + + The ``dump`` function is not available by default. You must add the + ``Twig_Extension_Debug`` extension explicitly when creating your Twig + environment:: + + $twig = new Twig_Environment($loader, array( + 'debug' => true, + // ... + )); + $twig->addExtension(new Twig_Extension_Debug()); + + Even when enabled, the ``dump`` function won't display anything if the + ``debug`` option on the environment is not enabled (to avoid leaking debug + information on a production server). + +In an HTML context, wrap the output with a ``pre`` tag to make it easier to +read: + +.. code-block:: jinja + +
+        {{ dump(user) }}
+    
+ +.. tip:: + + Using a ``pre`` tag is not needed when `XDebug`_ is enabled and + ``html_errors`` is ``on``; as a bonus, the output is also nicer with + XDebug enabled. + +You can debug several variables by passing them as additional arguments: + +.. code-block:: jinja + + {{ dump(user, categories) }} + +If you don't pass any value, all variables from the current context are +dumped: + +.. code-block:: jinja + + {{ dump() }} + +.. note:: + + Internally, Twig uses the PHP `var_dump`_ function. + +Arguments +--------- + +* ``context``: The context to dump + +.. _`XDebug`: http://xdebug.org/docs/display +.. _`var_dump`: http://php.net/var_dump diff --git a/vendor/twig/twig/doc/functions/include.rst b/vendor/twig/twig/doc/functions/include.rst new file mode 100644 index 000000000..2f88ed776 --- /dev/null +++ b/vendor/twig/twig/doc/functions/include.rst @@ -0,0 +1,84 @@ +``include`` +=========== + +.. versionadded:: 1.12 + The ``include`` function was added in Twig 1.12. + +The ``include`` function returns the rendered content of a template: + +.. code-block:: jinja + + {{ include('template.html') }} + {{ include(some_var) }} + +Included templates have access to the variables of the active context. + +If you are using the filesystem loader, the templates are looked for in the +paths defined by it. + +The context is passed by default to the template but you can also pass +additional variables: + +.. code-block:: jinja + + {# template.html will have access to the variables from the current context and the additional ones provided #} + {{ include('template.html', {foo: 'bar'}) }} + +You can disable access to the context by setting ``with_context`` to +``false``: + +.. code-block:: jinja + + {# only the foo variable will be accessible #} + {{ include('template.html', {foo: 'bar'}, with_context = false) }} + +.. code-block:: jinja + + {# no variables will be accessible #} + {{ include('template.html', with_context = false) }} + +And if the expression evaluates to a ``Twig_Template`` or a +``Twig_TemplateWrapper`` instance, Twig will use it directly:: + + // {{ include(template) }} + + // deprecated as of Twig 1.28 + $template = $twig->loadTemplate('some_template.twig'); + + // as of Twig 1.28 + $template = $twig->load('some_template.twig'); + + $twig->display('template.twig', array('template' => $template)); + +When you set the ``ignore_missing`` flag, Twig will return an empty string if +the template does not exist: + +.. code-block:: jinja + + {{ include('sidebar.html', ignore_missing = true) }} + +You can also provide a list of templates that are checked for existence before +inclusion. The first template that exists will be rendered: + +.. code-block:: jinja + + {{ include(['page_detailed.html', 'page.html']) }} + +If ``ignore_missing`` is set, it will fall back to rendering nothing if none +of the templates exist, otherwise it will throw an exception. + +When including a template created by an end user, you should consider +sandboxing it: + +.. code-block:: jinja + + {{ include('page.html', sandboxed = true) }} + +Arguments +--------- + +* ``template``: The template to render +* ``variables``: The variables to pass to the template +* ``with_context``: Whether to pass the current context variables or not +* ``ignore_missing``: Whether to ignore missing templates or not +* ``sandboxed``: Whether to sandbox the template or not diff --git a/vendor/twig/twig/doc/functions/index.rst b/vendor/twig/twig/doc/functions/index.rst new file mode 100644 index 000000000..07214a76c --- /dev/null +++ b/vendor/twig/twig/doc/functions/index.rst @@ -0,0 +1,20 @@ +Functions +========= + +.. toctree:: + :maxdepth: 1 + + attribute + block + constant + cycle + date + dump + include + max + min + parent + random + range + source + template_from_string diff --git a/vendor/twig/twig/doc/functions/max.rst b/vendor/twig/twig/doc/functions/max.rst new file mode 100644 index 000000000..6f3cfc535 --- /dev/null +++ b/vendor/twig/twig/doc/functions/max.rst @@ -0,0 +1,20 @@ +``max`` +======= + +.. versionadded:: 1.15 + The ``max`` function was added in Twig 1.15. + +``max`` returns the biggest value of a sequence or a set of values: + +.. code-block:: jinja + + {{ max(1, 3, 2) }} + {{ max([1, 3, 2]) }} + +When called with a mapping, max ignores keys and only compares values: + +.. code-block:: jinja + + {{ max({2: "e", 1: "a", 3: "b", 5: "d", 4: "c"}) }} + {# returns "e" #} + diff --git a/vendor/twig/twig/doc/functions/min.rst b/vendor/twig/twig/doc/functions/min.rst new file mode 100644 index 000000000..7b6a65e10 --- /dev/null +++ b/vendor/twig/twig/doc/functions/min.rst @@ -0,0 +1,20 @@ +``min`` +======= + +.. versionadded:: 1.15 + The ``min`` function was added in Twig 1.15. + +``min`` returns the lowest value of a sequence or a set of values: + +.. code-block:: jinja + + {{ min(1, 3, 2) }} + {{ min([1, 3, 2]) }} + +When called with a mapping, min ignores keys and only compares values: + +.. code-block:: jinja + + {{ min({2: "e", 3: "a", 1: "b", 5: "d", 4: "c"}) }} + {# returns "a" #} + diff --git a/vendor/twig/twig/doc/functions/parent.rst b/vendor/twig/twig/doc/functions/parent.rst new file mode 100644 index 000000000..f5bd20010 --- /dev/null +++ b/vendor/twig/twig/doc/functions/parent.rst @@ -0,0 +1,20 @@ +``parent`` +========== + +When a template uses inheritance, it's possible to render the contents of the +parent block when overriding a block by using the ``parent`` function: + +.. code-block:: jinja + + {% extends "base.html" %} + + {% block sidebar %} +

Table Of Contents

+ ... + {{ parent() }} + {% endblock %} + +The ``parent()`` call will return the content of the ``sidebar`` block as +defined in the ``base.html`` template. + +.. seealso:: :doc:`extends<../tags/extends>`, :doc:`block<../functions/block>`, :doc:`block<../tags/block>` diff --git a/vendor/twig/twig/doc/functions/random.rst b/vendor/twig/twig/doc/functions/random.rst new file mode 100644 index 000000000..168e74f8f --- /dev/null +++ b/vendor/twig/twig/doc/functions/random.rst @@ -0,0 +1,29 @@ +``random`` +========== + +.. versionadded:: 1.5 + The ``random`` function was added in Twig 1.5. + +.. versionadded:: 1.6 + String and integer handling was added in Twig 1.6. + +The ``random`` function returns a random value depending on the supplied +parameter type: + +* a random item from a sequence; +* a random character from a string; +* a random integer between 0 and the integer parameter (inclusive). + +.. code-block:: jinja + + {{ random(['apple', 'orange', 'citrus']) }} {# example output: orange #} + {{ random('ABC') }} {# example output: C #} + {{ random() }} {# example output: 15386094 (works as the native PHP mt_rand function) #} + {{ random(5) }} {# example output: 3 #} + +Arguments +--------- + +* ``values``: The values + +.. _`mt_rand`: http://php.net/mt_rand diff --git a/vendor/twig/twig/doc/functions/range.rst b/vendor/twig/twig/doc/functions/range.rst new file mode 100644 index 000000000..5c9db0892 --- /dev/null +++ b/vendor/twig/twig/doc/functions/range.rst @@ -0,0 +1,58 @@ +``range`` +========= + +Returns a list containing an arithmetic progression of integers: + +.. code-block:: jinja + + {% for i in range(0, 3) %} + {{ i }}, + {% endfor %} + + {# outputs 0, 1, 2, 3, #} + +When step is given (as the third parameter), it specifies the increment (or +decrement for negative values): + +.. code-block:: jinja + + {% for i in range(0, 6, 2) %} + {{ i }}, + {% endfor %} + + {# outputs 0, 2, 4, 6, #} + +.. note:: + + Note that if the start is greater than the end, ``range`` assumes a step of + ``-1``: + + .. code-block:: jinja + + {% for i in range(3, 0) %} + {{ i }}, + {% endfor %} + + {# outputs 3, 2, 1, 0, #} + +The Twig built-in ``..`` operator is just syntactic sugar for the ``range`` +function (with a step of ``1``, or ``-1`` if the start is greater than the end): + +.. code-block:: jinja + + {% for i in 0..3 %} + {{ i }}, + {% endfor %} + +.. tip:: + + The ``range`` function works as the native PHP `range`_ function. + +Arguments +--------- + +* ``low``: The first value of the sequence. +* ``high``: The highest possible value of the sequence. +* ``step``: The increment between elements of the sequence. + +.. _`range`: http://php.net/range diff --git a/vendor/twig/twig/doc/functions/source.rst b/vendor/twig/twig/doc/functions/source.rst new file mode 100644 index 000000000..3c921b1cf --- /dev/null +++ b/vendor/twig/twig/doc/functions/source.rst @@ -0,0 +1,32 @@ +``source`` +========== + +.. versionadded:: 1.15 + The ``source`` function was added in Twig 1.15. + +.. versionadded:: 1.18.3 + The ``ignore_missing`` flag was added in Twig 1.18.3. + +The ``source`` function returns the content of a template without rendering it: + +.. code-block:: jinja + + {{ source('template.html') }} + {{ source(some_var) }} + +When you set the ``ignore_missing`` flag, Twig will return an empty string if +the template does not exist: + +.. code-block:: jinja + + {{ source('template.html', ignore_missing = true) }} + +The function uses the same template loaders as the ones used to include +templates. So, if you are using the filesystem loader, the templates are looked +for in the paths defined by it. + +Arguments +--------- + +* ``name``: The name of the template to read +* ``ignore_missing``: Whether to ignore missing templates or not diff --git a/vendor/twig/twig/doc/functions/template_from_string.rst b/vendor/twig/twig/doc/functions/template_from_string.rst new file mode 100644 index 000000000..ce6a60dc0 --- /dev/null +++ b/vendor/twig/twig/doc/functions/template_from_string.rst @@ -0,0 +1,32 @@ +``template_from_string`` +======================== + +.. versionadded:: 1.11 + The ``template_from_string`` function was added in Twig 1.11. + +The ``template_from_string`` function loads a template from a string: + +.. code-block:: jinja + + {{ include(template_from_string("Hello {{ name }}")) }} + {{ include(template_from_string(page.template)) }} + +.. note:: + + The ``template_from_string`` function is not available by default. You + must add the ``Twig_Extension_StringLoader`` extension explicitly when + creating your Twig environment:: + + $twig = new Twig_Environment(...); + $twig->addExtension(new Twig_Extension_StringLoader()); + +.. note:: + + Even if you will probably always use the ``template_from_string`` function + with the ``include`` function, you can use it with any tag or function that + takes a template as an argument (like the ``embed`` or ``extends`` tags). + +Arguments +--------- + +* ``template``: The template diff --git a/vendor/twig/twig/doc/index.rst b/vendor/twig/twig/doc/index.rst new file mode 100644 index 000000000..358bd738e --- /dev/null +++ b/vendor/twig/twig/doc/index.rst @@ -0,0 +1,19 @@ +Twig +==== + +.. toctree:: + :maxdepth: 2 + + intro + installation + templates + api + advanced + internals + deprecated + recipes + coding_standards + tags/index + filters/index + functions/index + tests/index diff --git a/vendor/twig/twig/doc/installation.rst b/vendor/twig/twig/doc/installation.rst new file mode 100644 index 000000000..afdcf1659 --- /dev/null +++ b/vendor/twig/twig/doc/installation.rst @@ -0,0 +1,116 @@ +Installation +============ + +You have multiple ways to install Twig. + +Installing the Twig PHP package +------------------------------- + +Installing via Composer (recommended) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Install `Composer`_ and run the following command to get the latest version: + +.. code-block:: bash + + composer require twig/twig:~1.0 + +Installing from the tarball release +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Download the most recent tarball from the `download page`_ +2. Verify the integrity of the tarball http://fabien.potencier.org/article/73/signing-project-releases +3. Unpack the tarball +4. Move the files somewhere in your project + +Installing the development version +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: bash + + git clone git://github.com/twigphp/Twig.git + +Installing the PEAR package +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. note:: + + Using PEAR for installing Twig is deprecated and Twig 1.15.1 was the last + version published on the PEAR channel; use Composer instead. + +.. code-block:: bash + + pear channel-discover pear.twig-project.org + pear install twig/Twig + +Installing the C extension +-------------------------- + +.. versionadded:: 1.4 + The C extension was added in Twig 1.4. + +.. note:: + + The C extension is **optional** but it brings some nice performance + improvements. Note that the extension is not a replacement for the PHP + code; it only implements a small part of the PHP code to improve the + performance at runtime; you must still install the regular PHP code. + +Twig comes with a C extension that enhances the performance of the Twig +runtime engine; install it like any other PHP extensions: + +.. code-block:: bash + + cd ext/twig + phpize + ./configure + make + make install + +.. note:: + + You can also install the C extension via PEAR (note that this method is + deprecated and newer versions of Twig are not available on the PEAR + channel): + + .. code-block:: bash + + pear channel-discover pear.twig-project.org + pear install twig/CTwig + +For Windows: + +1. Setup the build environment following the `PHP documentation`_ +2. Put Twig's C extension source code into ``C:\php-sdk\phpdev\vcXX\x86\php-source-directory\ext\twig`` +3. Use the ``configure --disable-all --enable-cli --enable-twig=shared`` command instead of step 14 +4. ``nmake`` +5. Copy the ``C:\php-sdk\phpdev\vcXX\x86\php-source-directory\Release_TS\php_twig.dll`` file to your PHP setup. + +.. tip:: + + For Windows ZendServer, ZTS is not enabled as mentioned in `Zend Server + FAQ`_. + + You have to use ``configure --disable-all --disable-zts --enable-cli + --enable-twig=shared`` to be able to build the twig C extension for + ZendServer. + + The built DLL will be available in + ``C:\\php-sdk\\phpdev\\vcXX\\x86\\php-source-directory\\Release`` + +Finally, enable the extension in your ``php.ini`` configuration file: + +.. code-block:: ini + + extension=twig.so #For Unix systems + extension=php_twig.dll #For Windows systems + +And from now on, Twig will automatically compile your templates to take +advantage of the C extension. Note that this extension does not replace the +PHP code but only provides an optimized version of the +``Twig_Template::getAttribute()`` method. + +.. _`download page`: https://github.com/twigphp/Twig/tags +.. _`Composer`: https://getcomposer.org/download/ +.. _`PHP documentation`: https://wiki.php.net/internals/windows/stepbystepbuild +.. _`Zend Server FAQ`: http://www.zend.com/en/products/server/faq#faqD6 diff --git a/vendor/twig/twig/doc/internals.rst b/vendor/twig/twig/doc/internals.rst new file mode 100644 index 000000000..f38089fdc --- /dev/null +++ b/vendor/twig/twig/doc/internals.rst @@ -0,0 +1,142 @@ +Twig Internals +============== + +Twig is very extensible and you can easily hack it. Keep in mind that you +should probably try to create an extension before hacking the core, as most +features and enhancements can be handled with extensions. This chapter is also +useful for people who want to understand how Twig works under the hood. + +How does Twig work? +------------------- + +The rendering of a Twig template can be summarized into four key steps: + +* **Load** the template: If the template is already compiled, load it and go + to the *evaluation* step, otherwise: + + * First, the **lexer** tokenizes the template source code into small pieces + for easier processing; + * Then, the **parser** converts the token stream into a meaningful tree + of nodes (the Abstract Syntax Tree); + * Eventually, the *compiler* transforms the AST into PHP code. + +* **Evaluate** the template: It basically means calling the ``display()`` + method of the compiled template and passing it the context. + +The Lexer +--------- + +The lexer tokenizes a template source code into a token stream (each token is +an instance of ``Twig_Token``, and the stream is an instance of +``Twig_TokenStream``). The default lexer recognizes 13 different token types: + +* ``Twig_Token::BLOCK_START_TYPE``, ``Twig_Token::BLOCK_END_TYPE``: Delimiters for blocks (``{% %}``) +* ``Twig_Token::VAR_START_TYPE``, ``Twig_Token::VAR_END_TYPE``: Delimiters for variables (``{{ }}``) +* ``Twig_Token::TEXT_TYPE``: A text outside an expression; +* ``Twig_Token::NAME_TYPE``: A name in an expression; +* ``Twig_Token::NUMBER_TYPE``: A number in an expression; +* ``Twig_Token::STRING_TYPE``: A string in an expression; +* ``Twig_Token::OPERATOR_TYPE``: An operator; +* ``Twig_Token::PUNCTUATION_TYPE``: A punctuation sign; +* ``Twig_Token::INTERPOLATION_START_TYPE``, ``Twig_Token::INTERPOLATION_END_TYPE`` (as of Twig 1.5): Delimiters for string interpolation; +* ``Twig_Token::EOF_TYPE``: Ends of template. + +You can manually convert a source code into a token stream by calling the +``tokenize()`` method of an environment:: + + $stream = $twig->tokenize(new Twig_Source($source, $identifier)); + +.. versionadded:: 1.27 + ``Twig_Source`` was introduced in version 1.27, pass the source and the + identifier directly on previous versions. + +As the stream has a ``__toString()`` method, you can have a textual +representation of it by echoing the object:: + + echo $stream."\n"; + +Here is the output for the ``Hello {{ name }}`` template: + +.. code-block:: text + + TEXT_TYPE(Hello ) + VAR_START_TYPE() + NAME_TYPE(name) + VAR_END_TYPE() + EOF_TYPE() + +.. note:: + + The default lexer (``Twig_Lexer``) can be changed by calling + the ``setLexer()`` method:: + + $twig->setLexer($lexer); + +The Parser +---------- + +The parser converts the token stream into an AST (Abstract Syntax Tree), or a +node tree (an instance of ``Twig_Node_Module``). The core extension defines +the basic nodes like: ``for``, ``if``, ... and the expression nodes. + +You can manually convert a token stream into a node tree by calling the +``parse()`` method of an environment:: + + $nodes = $twig->parse($stream); + +Echoing the node object gives you a nice representation of the tree:: + + echo $nodes."\n"; + +Here is the output for the ``Hello {{ name }}`` template: + +.. code-block:: text + + Twig_Node_Module( + Twig_Node_Text(Hello ) + Twig_Node_Print( + Twig_Node_Expression_Name(name) + ) + ) + +.. note:: + + The default parser (``Twig_TokenParser``) can be changed by calling the + ``setParser()`` method:: + + $twig->setParser($parser); + +The Compiler +------------ + +The last step is done by the compiler. It takes a node tree as an input and +generates PHP code usable for runtime execution of the template. + +You can manually compile a node tree to PHP code with the ``compile()`` method +of an environment:: + + $php = $twig->compile($nodes); + +The generated template for a ``Hello {{ name }}`` template reads as follows +(the actual output can differ depending on the version of Twig you are +using):: + + /* Hello {{ name }} */ + class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template + { + protected function doDisplay(array $context, array $blocks = array()) + { + // line 1 + echo "Hello "; + echo twig_escape_filter($this->env, isset($context["name"]) ? $context["name"] : null), "html", null, true); + } + + // some more code + } + +.. note:: + + The default compiler (``Twig_Compiler``) can be changed by calling the + ``setCompiler()`` method:: + + $twig->setCompiler($compiler); diff --git a/vendor/twig/twig/doc/intro.rst b/vendor/twig/twig/doc/intro.rst new file mode 100644 index 000000000..d631430f7 --- /dev/null +++ b/vendor/twig/twig/doc/intro.rst @@ -0,0 +1,86 @@ +Introduction +============ + +This is the documentation for Twig, the flexible, fast, and secure template +engine for PHP. + +If you have any exposure to other text-based template languages, such as +Smarty, Django, or Jinja, you should feel right at home with Twig. It's both +designer and developer friendly by sticking to PHP's principles and adding +functionality useful for templating environments. + +The key-features are... + +* *Fast*: Twig compiles templates down to plain optimized PHP code. The + overhead compared to regular PHP code was reduced to the very minimum. + +* *Secure*: Twig has a sandbox mode to evaluate untrusted template code. This + allows Twig to be used as a template language for applications where users + may modify the template design. + +* *Flexible*: Twig is powered by a flexible lexer and parser. This allows the + developer to define their own custom tags and filters, and to create their own DSL. + +Twig is used by many Open-Source projects like Symfony, Drupal8, eZPublish, +phpBB, Piwik, OroCRM; and many frameworks have support for it as well like +Slim, Yii, Laravel, Codeigniter and Kohana — just to name a few. + +Prerequisites +------------- + +Twig needs at least **PHP 5.2.7** to run. As of 1.34, the minimum requirement +was bumped to **PHP 5.3.3**. + +Installation +------------ + +The recommended way to install Twig is via Composer: + +.. code-block:: bash + + composer require "twig/twig:~1.0" + +.. note:: + + To learn more about the other installation methods, read the + :doc:`installation` chapter; it also explains how to install + the Twig C extension. + +Basic API Usage +--------------- + +This section gives you a brief introduction to the PHP API for Twig. + +.. code-block:: php + + require_once '/path/to/vendor/autoload.php'; + + $loader = new Twig_Loader_Array(array( + 'index' => 'Hello {{ name }}!', + )); + $twig = new Twig_Environment($loader); + + echo $twig->render('index', array('name' => 'Fabien')); + +Twig uses a loader (``Twig_Loader_Array``) to locate templates, and an +environment (``Twig_Environment``) to store the configuration. + +The ``render()`` method loads the template passed as a first argument and +renders it with the variables passed as a second argument. + +As templates are generally stored on the filesystem, Twig also comes with a +filesystem loader:: + + $loader = new Twig_Loader_Filesystem('/path/to/templates'); + $twig = new Twig_Environment($loader, array( + 'cache' => '/path/to/compilation_cache', + )); + + echo $twig->render('index.html', array('name' => 'Fabien')); + +.. tip:: + + If you are not using Composer, use the Twig built-in autoloader:: + + require_once '/path/to/lib/Twig/Autoloader.php'; + Twig_Autoloader::register(); diff --git a/vendor/twig/twig/doc/recipes.rst b/vendor/twig/twig/doc/recipes.rst new file mode 100644 index 000000000..b3ba7f4d7 --- /dev/null +++ b/vendor/twig/twig/doc/recipes.rst @@ -0,0 +1,568 @@ +Recipes +======= + +.. _deprecation-notices: + +Displaying Deprecation Notices +------------------------------ + +.. versionadded:: 1.21 + This works as of Twig 1.21. + +Deprecated features generate deprecation notices (via a call to the +``trigger_error()`` PHP function). By default, they are silenced and never +displayed nor logged. + +To easily remove all deprecated feature usages from your templates, write and +run a script along the lines of the following:: + + require_once __DIR__.'/vendor/autoload.php'; + + $twig = create_your_twig_env(); + + $deprecations = new Twig_Util_DeprecationCollector($twig); + + print_r($deprecations->collectDir(__DIR__.'/templates')); + +The ``collectDir()`` method compiles all templates found in a directory, +catches deprecation notices, and return them. + +.. tip:: + + If your templates are not stored on the filesystem, use the ``collect()`` + method instead. ``collect()`` takes a ``Traversable`` which must return + template names as keys and template contents as values (as done by + ``Twig_Util_TemplateDirIterator``). + +However, this code won't find all deprecations (like using deprecated some Twig +classes). To catch all notices, register a custom error handler like the one +below:: + + $deprecations = array(); + set_error_handler(function ($type, $msg) use (&$deprecations) { + if (E_USER_DEPRECATED === $type) { + $deprecations[] = $msg; + } + }); + + // run your application + + print_r($deprecations); + +Note that most deprecation notices are triggered during **compilation**, so +they won't be generated when templates are already cached. + +.. tip:: + + If you want to manage the deprecation notices from your PHPUnit tests, have + a look at the `symfony/phpunit-bridge + `_ package, which eases the + process a lot. + +Making a Layout conditional +--------------------------- + +Working with Ajax means that the same content is sometimes displayed as is, +and sometimes decorated with a layout. As Twig layout template names can be +any valid expression, you can pass a variable that evaluates to ``true`` when +the request is made via Ajax and choose the layout accordingly: + +.. code-block:: jinja + + {% extends request.ajax ? "base_ajax.html" : "base.html" %} + + {% block content %} + This is the content to be displayed. + {% endblock %} + +Making an Include dynamic +------------------------- + +When including a template, its name does not need to be a string. For +instance, the name can depend on the value of a variable: + +.. code-block:: jinja + + {% include var ~ '_foo.html' %} + +If ``var`` evaluates to ``index``, the ``index_foo.html`` template will be +rendered. + +As a matter of fact, the template name can be any valid expression, such as +the following: + +.. code-block:: jinja + + {% include var|default('index') ~ '_foo.html' %} + +Overriding a Template that also extends itself +---------------------------------------------- + +A template can be customized in two different ways: + +* *Inheritance*: A template *extends* a parent template and overrides some + blocks; + +* *Replacement*: If you use the filesystem loader, Twig loads the first + template it finds in a list of configured directories; a template found in a + directory *replaces* another one from a directory further in the list. + +But how do you combine both: *replace* a template that also extends itself +(aka a template in a directory further in the list)? + +Let's say that your templates are loaded from both ``.../templates/mysite`` +and ``.../templates/default`` in this order. The ``page.twig`` template, +stored in ``.../templates/default`` reads as follows: + +.. code-block:: jinja + + {# page.twig #} + {% extends "layout.twig" %} + + {% block content %} + {% endblock %} + +You can replace this template by putting a file with the same name in +``.../templates/mysite``. And if you want to extend the original template, you +might be tempted to write the following: + +.. code-block:: jinja + + {# page.twig in .../templates/mysite #} + {% extends "page.twig" %} {# from .../templates/default #} + +Of course, this will not work as Twig will always load the template from +``.../templates/mysite``. + +It turns out it is possible to get this to work, by adding a directory right +at the end of your template directories, which is the parent of all of the +other directories: ``.../templates`` in our case. This has the effect of +making every template file within our system uniquely addressable. Most of the +time you will use the "normal" paths, but in the special case of wanting to +extend a template with an overriding version of itself we can reference its +parent's full, unambiguous template path in the extends tag: + +.. code-block:: jinja + + {# page.twig in .../templates/mysite #} + {% extends "default/page.twig" %} {# from .../templates #} + +.. note:: + + This recipe was inspired by the following Django wiki page: + http://code.djangoproject.com/wiki/ExtendingTemplates + +Customizing the Syntax +---------------------- + +Twig allows some syntax customization for the block delimiters. It's not +recommended to use this feature as templates will be tied with your custom +syntax. But for specific projects, it can make sense to change the defaults. + +To change the block delimiters, you need to create your own lexer object:: + + $twig = new Twig_Environment(); + + $lexer = new Twig_Lexer($twig, array( + 'tag_comment' => array('{#', '#}'), + 'tag_block' => array('{%', '%}'), + 'tag_variable' => array('{{', '}}'), + 'interpolation' => array('#{', '}'), + )); + $twig->setLexer($lexer); + +Here are some configuration example that simulates some other template engines +syntax:: + + // Ruby erb syntax + $lexer = new Twig_Lexer($twig, array( + 'tag_comment' => array('<%#', '%>'), + 'tag_block' => array('<%', '%>'), + 'tag_variable' => array('<%=', '%>'), + )); + + // SGML Comment Syntax + $lexer = new Twig_Lexer($twig, array( + 'tag_comment' => array(''), + 'tag_block' => array(''), + 'tag_variable' => array('${', '}'), + )); + + // Smarty like + $lexer = new Twig_Lexer($twig, array( + 'tag_comment' => array('{*', '*}'), + 'tag_block' => array('{', '}'), + 'tag_variable' => array('{$', '}'), + )); + +Using dynamic Object Properties +------------------------------- + +When Twig encounters a variable like ``article.title``, it tries to find a +``title`` public property in the ``article`` object. + +It also works if the property does not exist but is rather defined dynamically +thanks to the magic ``__get()`` method; you just need to also implement the +``__isset()`` magic method like shown in the following snippet of code:: + + class Article + { + public function __get($name) + { + if ('title' == $name) { + return 'The title'; + } + + // throw some kind of error + } + + public function __isset($name) + { + if ('title' == $name) { + return true; + } + + return false; + } + } + +Accessing the parent Context in Nested Loops +-------------------------------------------- + +Sometimes, when using nested loops, you need to access the parent context. The +parent context is always accessible via the ``loop.parent`` variable. For +instance, if you have the following template data:: + + $data = array( + 'topics' => array( + 'topic1' => array('Message 1 of topic 1', 'Message 2 of topic 1'), + 'topic2' => array('Message 1 of topic 2', 'Message 2 of topic 2'), + ), + ); + +And the following template to display all messages in all topics: + +.. code-block:: jinja + + {% for topic, messages in topics %} + * {{ loop.index }}: {{ topic }} + {% for message in messages %} + - {{ loop.parent.loop.index }}.{{ loop.index }}: {{ message }} + {% endfor %} + {% endfor %} + +The output will be similar to: + +.. code-block:: text + + * 1: topic1 + - 1.1: The message 1 of topic 1 + - 1.2: The message 2 of topic 1 + * 2: topic2 + - 2.1: The message 1 of topic 2 + - 2.2: The message 2 of topic 2 + +In the inner loop, the ``loop.parent`` variable is used to access the outer +context. So, the index of the current ``topic`` defined in the outer for loop +is accessible via the ``loop.parent.loop.index`` variable. + +Defining undefined Functions and Filters on the Fly +--------------------------------------------------- + +When a function (or a filter) is not defined, Twig defaults to throw a +``Twig_Error_Syntax`` exception. However, it can also call a `callback`_ (any +valid PHP callable) which should return a function (or a filter). + +For filters, register callbacks with ``registerUndefinedFilterCallback()``. +For functions, use ``registerUndefinedFunctionCallback()``:: + + // auto-register all native PHP functions as Twig functions + // don't try this at home as it's not secure at all! + $twig->registerUndefinedFunctionCallback(function ($name) { + if (function_exists($name)) { + return new Twig_SimpleFunction($name, $name); + } + + return false; + }); + +If the callable is not able to return a valid function (or filter), it must +return ``false``. + +If you register more than one callback, Twig will call them in turn until one +does not return ``false``. + +.. tip:: + + As the resolution of functions and filters is done during compilation, + there is no overhead when registering these callbacks. + +Validating the Template Syntax +------------------------------ + +When template code is provided by a third-party (through a web interface for +instance), it might be interesting to validate the template syntax before +saving it. If the template code is stored in a `$template` variable, here is +how you can do it:: + + try { + $twig->parse($twig->tokenize(new Twig_Source($template))); + + // the $template is valid + } catch (Twig_Error_Syntax $e) { + // $template contains one or more syntax errors + } + +If you iterate over a set of files, you can pass the filename to the +``tokenize()`` method to get the filename in the exception message:: + + foreach ($files as $file) { + try { + $twig->parse($twig->tokenize(new Twig_Source($template, $file->getFilename(), $file))); + + // the $template is valid + } catch (Twig_Error_Syntax $e) { + // $template contains one or more syntax errors + } + } + +.. versionadded:: 1.27 + ``Twig_Source`` was introduced in version 1.27, pass the source and the + identifier directly on previous versions. + +.. note:: + + This method won't catch any sandbox policy violations because the policy + is enforced during template rendering (as Twig needs the context for some + checks like allowed methods on objects). + +Refreshing modified Templates when OPcache or APC is enabled +------------------------------------------------------------ + +When using OPcache with ``opcache.validate_timestamps`` set to ``0`` or APC +with ``apc.stat`` set to ``0`` and Twig cache enabled, clearing the template +cache won't update the cache. + +To get around this, force Twig to invalidate the bytecode cache:: + + $twig = new Twig_Environment($loader, array( + 'cache' => new Twig_Cache_Filesystem('/some/cache/path', Twig_Cache_Filesystem::FORCE_BYTECODE_INVALIDATION), + // ... + )); + +.. note:: + + Before Twig 1.22, you should extend ``Twig_Environment`` instead:: + + class OpCacheAwareTwigEnvironment extends Twig_Environment + { + protected function writeCacheFile($file, $content) + { + parent::writeCacheFile($file, $content); + + // Compile cached file into bytecode cache + if (function_exists('opcache_invalidate')) { + opcache_invalidate($file, true); + } elseif (function_exists('apc_compile_file')) { + apc_compile_file($file); + } + } + } + +Reusing a stateful Node Visitor +------------------------------- + +When attaching a visitor to a ``Twig_Environment`` instance, Twig uses it to +visit *all* templates it compiles. If you need to keep some state information +around, you probably want to reset it when visiting a new template. + +This can be easily achieved with the following code:: + + protected $someTemplateState = array(); + + public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) + { + if ($node instanceof Twig_Node_Module) { + // reset the state as we are entering a new template + $this->someTemplateState = array(); + } + + // ... + + return $node; + } + +Using a Database to store Templates +----------------------------------- + +If you are developing a CMS, templates are usually stored in a database. This +recipe gives you a simple PDO template loader you can use as a starting point +for your own. + +First, let's create a temporary in-memory SQLite3 database to work with:: + + $dbh = new PDO('sqlite::memory:'); + $dbh->exec('CREATE TABLE templates (name STRING, source STRING, last_modified INTEGER)'); + $base = '{% block content %}{% endblock %}'; + $index = ' + {% extends "base.twig" %} + {% block content %}Hello {{ name }}{% endblock %} + '; + $now = time(); + $dbh->exec("INSERT INTO templates (name, source, last_modified) VALUES ('base.twig', '$base', $now)"); + $dbh->exec("INSERT INTO templates (name, source, last_modified) VALUES ('index.twig', '$index', $now)"); + +We have created a simple ``templates`` table that hosts two templates: +``base.twig`` and ``index.twig``. + +Now, let's define a loader able to use this database:: + + class DatabaseTwigLoader implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface + { + protected $dbh; + + public function __construct(PDO $dbh) + { + $this->dbh = $dbh; + } + + public function getSource($name) + { + if (false === $source = $this->getValue('source', $name)) { + throw new Twig_Error_Loader(sprintf('Template "%s" does not exist.', $name)); + } + + return $source; + } + + // Twig_SourceContextLoaderInterface as of Twig 1.27 + public function getSourceContext($name) + { + if (false === $source = $this->getValue('source', $name)) { + throw new Twig_Error_Loader(sprintf('Template "%s" does not exist.', $name)); + } + + return new Twig_Source($source, $name); + } + + // Twig_ExistsLoaderInterface as of Twig 1.11 + public function exists($name) + { + return $name === $this->getValue('name', $name); + } + + public function getCacheKey($name) + { + return $name; + } + + public function isFresh($name, $time) + { + if (false === $lastModified = $this->getValue('last_modified', $name)) { + return false; + } + + return $lastModified <= $time; + } + + protected function getValue($column, $name) + { + $sth = $this->dbh->prepare('SELECT '.$column.' FROM templates WHERE name = :name'); + $sth->execute(array(':name' => (string) $name)); + + return $sth->fetchColumn(); + } + } + +Finally, here is an example on how you can use it:: + + $loader = new DatabaseTwigLoader($dbh); + $twig = new Twig_Environment($loader); + + echo $twig->render('index.twig', array('name' => 'Fabien')); + +Using different Template Sources +-------------------------------- + +This recipe is the continuation of the previous one. Even if you store the +contributed templates in a database, you might want to keep the original/base +templates on the filesystem. When templates can be loaded from different +sources, you need to use the ``Twig_Loader_Chain`` loader. + +As you can see in the previous recipe, we reference the template in the exact +same way as we would have done it with a regular filesystem loader. This is +the key to be able to mix and match templates coming from the database, the +filesystem, or any other loader for that matter: the template name should be a +logical name, and not the path from the filesystem:: + + $loader1 = new DatabaseTwigLoader($dbh); + $loader2 = new Twig_Loader_Array(array( + 'base.twig' => '{% block content %}{% endblock %}', + )); + $loader = new Twig_Loader_Chain(array($loader1, $loader2)); + + $twig = new Twig_Environment($loader); + + echo $twig->render('index.twig', array('name' => 'Fabien')); + +Now that the ``base.twig`` templates is defined in an array loader, you can +remove it from the database, and everything else will still work as before. + +Loading a Template from a String +-------------------------------- + +From a template, you can easily load a template stored in a string via the +``template_from_string`` function (available as of Twig 1.11 via the +``Twig_Extension_StringLoader`` extension): + +.. code-block:: jinja + + {{ include(template_from_string("Hello {{ name }}")) }} + +From PHP, it's also possible to load a template stored in a string via +``Twig_Environment::createTemplate()`` (available as of Twig 1.18):: + + $template = $twig->createTemplate('hello {{ name }}'); + echo $template->render(array('name' => 'Fabien')); + +.. note:: + + Never use the ``Twig_Loader_String`` loader, which has severe limitations. + +Using Twig and AngularJS in the same Templates +---------------------------------------------- + +Mixing different template syntaxes in the same file is not a recommended +practice as both AngularJS and Twig use the same delimiters in their syntax: +``{{`` and ``}}``. + +Still, if you want to use AngularJS and Twig in the same template, there are +two ways to make it work depending on the amount of AngularJS you need to +include in your templates: + +* Escaping the AngularJS delimiters by wrapping AngularJS sections with the + ``{% verbatim %}`` tag or by escaping each delimiter via ``{{ '{{' }}`` and + ``{{ '}}' }}``; + +* Changing the delimiters of one of the template engines (depending on which + engine you introduced last): + + * For AngularJS, change the interpolation tags using the + ``interpolateProvider`` service, for instance at the module initialization + time: + + .. code-block:: javascript + + angular.module('myApp', []).config(function($interpolateProvider) { + $interpolateProvider.startSymbol('{[').endSymbol(']}'); + }); + + * For Twig, change the delimiters via the ``tag_variable`` Lexer option: + + .. code-block:: php + + $env->setLexer(new Twig_Lexer($env, array( + 'tag_variable' => array('{[', ']}'), + ))); + +.. _callback: http://www.php.net/manual/en/function.is-callable.php diff --git a/vendor/twig/twig/doc/tags/autoescape.rst b/vendor/twig/twig/doc/tags/autoescape.rst new file mode 100644 index 000000000..8aa8c75d1 --- /dev/null +++ b/vendor/twig/twig/doc/tags/autoescape.rst @@ -0,0 +1,81 @@ +``autoescape`` +============== + +Whether automatic escaping is enabled or not, you can mark a section of a +template to be escaped or not by using the ``autoescape`` tag: + +.. code-block:: jinja + + {% autoescape %} + Everything will be automatically escaped in this block + using the HTML strategy + {% endautoescape %} + + {% autoescape 'html' %} + Everything will be automatically escaped in this block + using the HTML strategy + {% endautoescape %} + + {% autoescape 'js' %} + Everything will be automatically escaped in this block + using the js escaping strategy + {% endautoescape %} + + {% autoescape false %} + Everything will be outputted as is in this block + {% endautoescape %} + +.. note:: + + Before Twig 1.8, the syntax was different: + + .. code-block:: jinja + + {% autoescape true %} + Everything will be automatically escaped in this block + using the HTML strategy + {% endautoescape %} + + {% autoescape false %} + Everything will be outputted as is in this block + {% endautoescape %} + + {% autoescape true js %} + Everything will be automatically escaped in this block + using the js escaping strategy + {% endautoescape %} + +When automatic escaping is enabled everything is escaped by default except for +values explicitly marked as safe. Those can be marked in the template by using +the :doc:`raw<../filters/raw>` filter: + +.. code-block:: jinja + + {% autoescape %} + {{ safe_value|raw }} + {% endautoescape %} + +Functions returning template data (like :doc:`macros` and +:doc:`parent<../functions/parent>`) always return safe markup. + +.. note:: + + Twig is smart enough to not escape an already escaped value by the + :doc:`escape<../filters/escape>` filter. + +.. note:: + + Twig does not escape static expressions: + + .. code-block:: jinja + + {% set hello = "Hello" %} + {{ hello }} + {{ "world" }} + + Will be rendered "Hello **world**". + +.. note:: + + The chapter :doc:`Twig for Developers<../api>` gives more information + about when and how automatic escaping is applied. diff --git a/vendor/twig/twig/doc/tags/block.rst b/vendor/twig/twig/doc/tags/block.rst new file mode 100644 index 000000000..e38048232 --- /dev/null +++ b/vendor/twig/twig/doc/tags/block.rst @@ -0,0 +1,11 @@ +``block`` +========= + +Blocks are used for inheritance and act as placeholders and replacements at +the same time. They are documented in detail in the documentation for the +:doc:`extends<../tags/extends>` tag. + +Block names should consist of alphanumeric characters, and underscores. Dashes +are not permitted. + +.. seealso:: :doc:`block<../functions/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`, :doc:`extends<../tags/extends>` diff --git a/vendor/twig/twig/doc/tags/do.rst b/vendor/twig/twig/doc/tags/do.rst new file mode 100644 index 000000000..1c344e302 --- /dev/null +++ b/vendor/twig/twig/doc/tags/do.rst @@ -0,0 +1,12 @@ +``do`` +====== + +.. versionadded:: 1.5 + The ``do`` tag was added in Twig 1.5. + +The ``do`` tag works exactly like the regular variable expression (``{{ ... +}}``) just that it doesn't print anything: + +.. code-block:: jinja + + {% do 1 + 2 %} diff --git a/vendor/twig/twig/doc/tags/embed.rst b/vendor/twig/twig/doc/tags/embed.rst new file mode 100644 index 000000000..66fc21b5f --- /dev/null +++ b/vendor/twig/twig/doc/tags/embed.rst @@ -0,0 +1,178 @@ +``embed`` +========= + +.. versionadded:: 1.8 + The ``embed`` tag was added in Twig 1.8. + +The ``embed`` tag combines the behaviour of :doc:`include` and +:doc:`extends`. +It allows you to include another template's contents, just like ``include`` +does. But it also allows you to override any block defined inside the +included template, like when extending a template. + +Think of an embedded template as a "micro layout skeleton". + +.. code-block:: jinja + + {% embed "teasers_skeleton.twig" %} + {# These blocks are defined in "teasers_skeleton.twig" #} + {# and we override them right here: #} + {% block left_teaser %} + Some content for the left teaser box + {% endblock %} + {% block right_teaser %} + Some content for the right teaser box + {% endblock %} + {% endembed %} + +The ``embed`` tag takes the idea of template inheritance to the level of +content fragments. While template inheritance allows for "document skeletons", +which are filled with life by child templates, the ``embed`` tag allows you to +create "skeletons" for smaller units of content and re-use and fill them +anywhere you like. + +Since the use case may not be obvious, let's look at a simplified example. +Imagine a base template shared by multiple HTML pages, defining a single block +named "content": + +.. code-block:: text + + ┌─── page layout ─────────────────────┐ + │ │ + │ ┌── block "content" ──┐ │ + │ │ │ │ + │ │ │ │ + │ │ (child template to │ │ + │ │ put content here) │ │ + │ │ │ │ + │ │ │ │ + │ └─────────────────────┘ │ + │ │ + └─────────────────────────────────────┘ + +Some pages ("foo" and "bar") share the same content structure - +two vertically stacked boxes: + +.. code-block:: text + + ┌─── page layout ─────────────────────┐ + │ │ + │ ┌── block "content" ──┐ │ + │ │ ┌─ block "top" ───┐ │ │ + │ │ │ │ │ │ + │ │ └─────────────────┘ │ │ + │ │ ┌─ block "bottom" ┐ │ │ + │ │ │ │ │ │ + │ │ └─────────────────┘ │ │ + │ └─────────────────────┘ │ + │ │ + └─────────────────────────────────────┘ + +While other pages ("boom" and "baz") share a different content structure - +two boxes side by side: + +.. code-block:: text + + ┌─── page layout ─────────────────────┐ + │ │ + │ ┌── block "content" ──┐ │ + │ │ │ │ + │ │ ┌ block ┐ ┌ block ┐ │ │ + │ │ │"left" │ │"right"│ │ │ + │ │ │ │ │ │ │ │ + │ │ │ │ │ │ │ │ + │ │ └───────┘ └───────┘ │ │ + │ └─────────────────────┘ │ + │ │ + └─────────────────────────────────────┘ + +Without the ``embed`` tag, you have two ways to design your templates: + + * Create two "intermediate" base templates that extend the master layout + template: one with vertically stacked boxes to be used by the "foo" and + "bar" pages and another one with side-by-side boxes for the "boom" and + "baz" pages. + + * Embed the markup for the top/bottom and left/right boxes into each page + template directly. + +These two solutions do not scale well because they each have a major drawback: + + * The first solution may indeed work for this simplified example. But imagine + we add a sidebar, which may again contain different, recurring structures + of content. Now we would need to create intermediate base templates for + all occurring combinations of content structure and sidebar structure... + and so on. + + * The second solution involves duplication of common code with all its negative + consequences: any change involves finding and editing all affected copies + of the structure, correctness has to be verified for each copy, copies may + go out of sync by careless modifications etc. + +In such a situation, the ``embed`` tag comes in handy. The common layout +code can live in a single base template, and the two different content structures, +let's call them "micro layouts" go into separate templates which are embedded +as necessary: + +Page template ``foo.twig``: + +.. code-block:: jinja + + {% extends "layout_skeleton.twig" %} + + {% block content %} + {% embed "vertical_boxes_skeleton.twig" %} + {% block top %} + Some content for the top box + {% endblock %} + + {% block bottom %} + Some content for the bottom box + {% endblock %} + {% endembed %} + {% endblock %} + +And here is the code for ``vertical_boxes_skeleton.twig``: + +.. code-block:: html+jinja + +
+ {% block top %} + Top box default content + {% endblock %} +
+ +
+ {% block bottom %} + Bottom box default content + {% endblock %} +
+ +The goal of the ``vertical_boxes_skeleton.twig`` template being to factor +out the HTML markup for the boxes. + +The ``embed`` tag takes the exact same arguments as the ``include`` tag: + +.. code-block:: jinja + + {% embed "base" with {'foo': 'bar'} %} + ... + {% endembed %} + + {% embed "base" with {'foo': 'bar'} only %} + ... + {% endembed %} + + {% embed "base" ignore missing %} + ... + {% endembed %} + +.. warning:: + + As embedded templates do not have "names", auto-escaping strategies based + on the template name won't work as expected if you change the context (for + instance, if you embed a CSS/JavaScript template into an HTML one). In that + case, explicitly set the default auto-escaping strategy with the + ``autoescape`` tag. + +.. seealso:: :doc:`include<../tags/include>` diff --git a/vendor/twig/twig/doc/tags/extends.rst b/vendor/twig/twig/doc/tags/extends.rst new file mode 100644 index 000000000..8bf29c4f9 --- /dev/null +++ b/vendor/twig/twig/doc/tags/extends.rst @@ -0,0 +1,272 @@ +``extends`` +=========== + +The ``extends`` tag can be used to extend a template from another one. + +.. note:: + + Like PHP, Twig does not support multiple inheritance. So you can only have + one extends tag called per rendering. However, Twig supports horizontal + :doc:`reuse`. + +Let's define a base template, ``base.html``, which defines a simple HTML +skeleton document: + +.. code-block:: html+jinja + + + + + {% block head %} + + {% block title %}{% endblock %} - My Webpage + {% endblock %} + + +
{% block content %}{% endblock %}
+ + + + +In this example, the :doc:`block` tags define four blocks that child +templates can fill in. + +All the ``block`` tag does is to tell the template engine that a child +template may override those portions of the template. + +Child Template +-------------- + +A child template might look like this: + +.. code-block:: jinja + + {% extends "base.html" %} + + {% block title %}Index{% endblock %} + {% block head %} + {{ parent() }} + + {% endblock %} + {% block content %} +

Index

+

+ Welcome on my awesome homepage. +

+ {% endblock %} + +The ``extends`` tag is the key here. It tells the template engine that this +template "extends" another template. When the template system evaluates this +template, first it locates the parent. The extends tag should be the first tag +in the template. + +Note that since the child template doesn't define the ``footer`` block, the +value from the parent template is used instead. + +You can't define multiple ``block`` tags with the same name in the same +template. This limitation exists because a block tag works in "both" +directions. That is, a block tag doesn't just provide a hole to fill - it also +defines the content that fills the hole in the *parent*. If there were two +similarly-named ``block`` tags in a template, that template's parent wouldn't +know which one of the blocks' content to use. + +If you want to print a block multiple times you can however use the +``block`` function: + +.. code-block:: jinja + + {% block title %}{% endblock %} +

{{ block('title') }}

+ {% block body %}{% endblock %} + +Parent Blocks +------------- + +It's possible to render the contents of the parent block by using the +:doc:`parent<../functions/parent>` function. This gives back the results of +the parent block: + +.. code-block:: jinja + + {% block sidebar %} +

Table Of Contents

+ ... + {{ parent() }} + {% endblock %} + +Named Block End-Tags +-------------------- + +Twig allows you to put the name of the block after the end tag for better +readability: + +.. code-block:: jinja + + {% block sidebar %} + {% block inner_sidebar %} + ... + {% endblock inner_sidebar %} + {% endblock sidebar %} + +Of course, the name after the ``endblock`` word must match the block name. + +Block Nesting and Scope +----------------------- + +Blocks can be nested for more complex layouts. Per default, blocks have access +to variables from outer scopes: + +.. code-block:: jinja + + {% for item in seq %} +
  • {% block loop_item %}{{ item }}{% endblock %}
  • + {% endfor %} + +Block Shortcuts +--------------- + +For blocks with little content, it's possible to use a shortcut syntax. The +following constructs do the same thing: + +.. code-block:: jinja + + {% block title %} + {{ page_title|title }} + {% endblock %} + +.. code-block:: jinja + + {% block title page_title|title %} + +Dynamic Inheritance +------------------- + +Twig supports dynamic inheritance by using a variable as the base template: + +.. code-block:: jinja + + {% extends some_var %} + +If the variable evaluates to a ``Twig_Template`` or a ``Twig_TemplateWrapper`` +instance, Twig will use it as the parent template:: + + // {% extends layout %} + + // deprecated as of Twig 1.28 + $layout = $twig->loadTemplate('some_layout_template.twig'); + + // as of Twig 1.28 + $layout = $twig->load('some_layout_template.twig'); + + $twig->display('template.twig', array('layout' => $layout)); + +.. versionadded:: 1.2 + The possibility to pass an array of templates has been added in Twig 1.2. + +You can also provide a list of templates that are checked for existence. The +first template that exists will be used as a parent: + +.. code-block:: jinja + + {% extends ['layout.html', 'base_layout.html'] %} + +Conditional Inheritance +----------------------- + +As the template name for the parent can be any valid Twig expression, it's +possible to make the inheritance mechanism conditional: + +.. code-block:: jinja + + {% extends standalone ? "minimum.html" : "base.html" %} + +In this example, the template will extend the "minimum.html" layout template +if the ``standalone`` variable evaluates to ``true``, and "base.html" +otherwise. + +How do blocks work? +------------------- + +A block provides a way to change how a certain part of a template is rendered +but it does not interfere in any way with the logic around it. + +Let's take the following example to illustrate how a block works and more +importantly, how it does not work: + +.. code-block:: jinja + + {# base.twig #} + + {% for post in posts %} + {% block post %} +

    {{ post.title }}

    +

    {{ post.body }}

    + {% endblock %} + {% endfor %} + +If you render this template, the result would be exactly the same with or +without the ``block`` tag. The ``block`` inside the ``for`` loop is just a way +to make it overridable by a child template: + +.. code-block:: jinja + + {# child.twig #} + + {% extends "base.twig" %} + + {% block post %} +
    +
    {{ post.title }}
    +
    {{ post.text }}
    +
    + {% endblock %} + +Now, when rendering the child template, the loop is going to use the block +defined in the child template instead of the one defined in the base one; the +executed template is then equivalent to the following one: + +.. code-block:: jinja + + {% for post in posts %} +
    +
    {{ post.title }}
    +
    {{ post.text }}
    +
    + {% endfor %} + +Let's take another example: a block included within an ``if`` statement: + +.. code-block:: jinja + + {% if posts is empty %} + {% block head %} + {{ parent() }} + + + {% endblock head %} + {% endif %} + +Contrary to what you might think, this template does not define a block +conditionally; it just makes overridable by a child template the output of +what will be rendered when the condition is ``true``. + +If you want the output to be displayed conditionally, use the following +instead: + +.. code-block:: jinja + + {% block head %} + {{ parent() }} + + {% if posts is empty %} + + {% endif %} + {% endblock head %} + +.. seealso:: :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>` diff --git a/vendor/twig/twig/doc/tags/filter.rst b/vendor/twig/twig/doc/tags/filter.rst new file mode 100644 index 000000000..82ca5c62f --- /dev/null +++ b/vendor/twig/twig/doc/tags/filter.rst @@ -0,0 +1,21 @@ +``filter`` +========== + +Filter sections allow you to apply regular Twig filters on a block of template +data. Just wrap the code in the special ``filter`` section: + +.. code-block:: jinja + + {% filter upper %} + This text becomes uppercase + {% endfilter %} + +You can also chain filters: + +.. code-block:: jinja + + {% filter lower|escape %} + SOME TEXT + {% endfilter %} + + {# outputs "<strong>some text</strong>" #} diff --git a/vendor/twig/twig/doc/tags/flush.rst b/vendor/twig/twig/doc/tags/flush.rst new file mode 100644 index 000000000..55ef593a9 --- /dev/null +++ b/vendor/twig/twig/doc/tags/flush.rst @@ -0,0 +1,17 @@ +``flush`` +========= + +.. versionadded:: 1.5 + The flush tag was added in Twig 1.5. + +The ``flush`` tag tells Twig to flush the output buffer: + +.. code-block:: jinja + + {% flush %} + +.. note:: + + Internally, Twig uses the PHP `flush`_ function. + +.. _`flush`: http://php.net/flush diff --git a/vendor/twig/twig/doc/tags/for.rst b/vendor/twig/twig/doc/tags/for.rst new file mode 100644 index 000000000..0673b5511 --- /dev/null +++ b/vendor/twig/twig/doc/tags/for.rst @@ -0,0 +1,172 @@ +``for`` +======= + +Loop over each item in a sequence. For example, to display a list of users +provided in a variable called ``users``: + +.. code-block:: jinja + +

    Members

    +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    + +.. note:: + + A sequence can be either an array or an object implementing the + ``Traversable`` interface. + +If you do need to iterate over a sequence of numbers, you can use the ``..`` +operator: + +.. code-block:: jinja + + {% for i in 0..10 %} + * {{ i }} + {% endfor %} + +The above snippet of code would print all numbers from 0 to 10. + +It can be also useful with letters: + +.. code-block:: jinja + + {% for letter in 'a'..'z' %} + * {{ letter }} + {% endfor %} + +The ``..`` operator can take any expression at both sides: + +.. code-block:: jinja + + {% for letter in 'a'|upper..'z'|upper %} + * {{ letter }} + {% endfor %} + +.. tip: + + If you need a step different from 1, you can use the ``range`` function + instead. + +The `loop` variable +------------------- + +Inside of a ``for`` loop block you can access some special variables: + +===================== ============================================================= +Variable Description +===================== ============================================================= +``loop.index`` The current iteration of the loop. (1 indexed) +``loop.index0`` The current iteration of the loop. (0 indexed) +``loop.revindex`` The number of iterations from the end of the loop (1 indexed) +``loop.revindex0`` The number of iterations from the end of the loop (0 indexed) +``loop.first`` True if first iteration +``loop.last`` True if last iteration +``loop.length`` The number of items in the sequence +``loop.parent`` The parent context +===================== ============================================================= + +.. code-block:: jinja + + {% for user in users %} + {{ loop.index }} - {{ user.username }} + {% endfor %} + +.. note:: + + The ``loop.length``, ``loop.revindex``, ``loop.revindex0``, and + ``loop.last`` variables are only available for PHP arrays, or objects that + implement the ``Countable`` interface. They are also not available when + looping with a condition. + +.. versionadded:: 1.2 + The ``if`` modifier support has been added in Twig 1.2. + +Adding a condition +------------------ + +Unlike in PHP, it's not possible to ``break`` or ``continue`` in a loop. You +can however filter the sequence during iteration which allows you to skip +items. The following example skips all the users which are not active: + +.. code-block:: jinja + +
      + {% for user in users if user.active %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    + +The advantage is that the special loop variable will count correctly thus not +counting the users not iterated over. Keep in mind that properties like +``loop.last`` will not be defined when using loop conditions. + +.. note:: + + Using the ``loop`` variable within the condition is not recommended as it + will probably not be doing what you expect it to. For instance, adding a + condition like ``loop.index > 4`` won't work as the index is only + incremented when the condition is true (so the condition will never + match). + +The `else` Clause +----------------- + +If no iteration took place because the sequence was empty, you can render a +replacement block by using ``else``: + +.. code-block:: jinja + +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% else %} +
    • no user found
    • + {% endfor %} +
    + +Iterating over Keys +------------------- + +By default, a loop iterates over the values of the sequence. You can iterate +on keys by using the ``keys`` filter: + +.. code-block:: jinja + +

    Members

    +
      + {% for key in users|keys %} +
    • {{ key }}
    • + {% endfor %} +
    + +Iterating over Keys and Values +------------------------------ + +You can also access both keys and values: + +.. code-block:: jinja + +

    Members

    +
      + {% for key, user in users %} +
    • {{ key }}: {{ user.username|e }}
    • + {% endfor %} +
    + +Iterating over a Subset +----------------------- + +You might want to iterate over a subset of values. This can be achieved using +the :doc:`slice <../filters/slice>` filter: + +.. code-block:: jinja + +

    Top Ten Members

    +
      + {% for user in users|slice(0, 10) %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    diff --git a/vendor/twig/twig/doc/tags/from.rst b/vendor/twig/twig/doc/tags/from.rst new file mode 100644 index 000000000..39334fdde --- /dev/null +++ b/vendor/twig/twig/doc/tags/from.rst @@ -0,0 +1,8 @@ +``from`` +======== + +The ``from`` tag imports :doc:`macro<../tags/macro>` names into the current +namespace. The tag is documented in detail in the documentation for the +:doc:`import<../tags/import>` tag. + +.. seealso:: :doc:`macro<../tags/macro>`, :doc:`import<../tags/import>` diff --git a/vendor/twig/twig/doc/tags/if.rst b/vendor/twig/twig/doc/tags/if.rst new file mode 100644 index 000000000..12edf980d --- /dev/null +++ b/vendor/twig/twig/doc/tags/if.rst @@ -0,0 +1,76 @@ +``if`` +====== + +The ``if`` statement in Twig is comparable with the if statements of PHP. + +In the simplest form you can use it to test if an expression evaluates to +``true``: + +.. code-block:: jinja + + {% if online == false %} +

    Our website is in maintenance mode. Please, come back later.

    + {% endif %} + +You can also test if an array is not empty: + +.. code-block:: jinja + + {% if users %} +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    + {% endif %} + +.. note:: + + If you want to test if the variable is defined, use ``if users is + defined`` instead. + +You can also use ``not`` to check for values that evaluate to ``false``: + +.. code-block:: jinja + + {% if not user.subscribed %} +

    You are not subscribed to our mailing list.

    + {% endif %} + +For multiple conditions, ``and`` and ``or`` can be used: + +.. code-block:: jinja + + {% if temperature > 18 and temperature < 27 %} +

    It's a nice day for a walk in the park.

    + {% endif %} + +For multiple branches ``elseif`` and ``else`` can be used like in PHP. You can +use more complex ``expressions`` there too: + +.. code-block:: jinja + + {% if kenny.sick %} + Kenny is sick. + {% elseif kenny.dead %} + You killed Kenny! You bastard!!! + {% else %} + Kenny looks okay --- so far + {% endif %} + +.. note:: + + The rules to determine if an expression is ``true`` or ``false`` are the + same as in PHP; here are the edge cases rules: + + ====================== ==================== + Value Boolean evaluation + ====================== ==================== + empty string false + numeric zero false + whitespace-only string true + empty array false + null false + non-empty array true + object true + ====================== ==================== diff --git a/vendor/twig/twig/doc/tags/import.rst b/vendor/twig/twig/doc/tags/import.rst new file mode 100644 index 000000000..21a1e1980 --- /dev/null +++ b/vendor/twig/twig/doc/tags/import.rst @@ -0,0 +1,57 @@ +``import`` +========== + +Twig supports putting often used code into :doc:`macros<../tags/macro>`. These +macros can go into different templates and get imported from there. + +There are two ways to import templates. You can import the complete template +into a variable or request specific macros from it. + +Imagine we have a helper module that renders forms (called ``forms.html``): + +.. code-block:: jinja + + {% macro input(name, value, type, size) %} + + {% endmacro %} + + {% macro textarea(name, value, rows, cols) %} + + {% endmacro %} + +The easiest and most flexible is importing the whole module into a variable. +That way you can access the attributes: + +.. code-block:: jinja + + {% import 'forms.html' as forms %} + +
    +
    Username
    +
    {{ forms.input('username') }}
    +
    Password
    +
    {{ forms.input('password', null, 'password') }}
    +
    +

    {{ forms.textarea('comment') }}

    + +Alternatively you can import names from the template into the current +namespace: + +.. code-block:: jinja + + {% from 'forms.html' import input as input_field, textarea %} + +
    +
    Username
    +
    {{ input_field('username') }}
    +
    Password
    +
    {{ input_field('password', '', 'password') }}
    +
    +

    {{ textarea('comment') }}

    + +.. tip:: + + To import macros from the current file, use the special ``_self`` variable + for the source. + +.. seealso:: :doc:`macro<../tags/macro>`, :doc:`from<../tags/from>` diff --git a/vendor/twig/twig/doc/tags/include.rst b/vendor/twig/twig/doc/tags/include.rst new file mode 100644 index 000000000..24ff24db6 --- /dev/null +++ b/vendor/twig/twig/doc/tags/include.rst @@ -0,0 +1,90 @@ +``include`` +=========== + +The ``include`` statement includes a template and returns the rendered content +of that file into the current namespace: + +.. code-block:: jinja + + {% include 'header.html' %} + Body + {% include 'footer.html' %} + +Included templates have access to the variables of the active context. + +If you are using the filesystem loader, the templates are looked for in the +paths defined by it. + +You can add additional variables by passing them after the ``with`` keyword: + +.. code-block:: jinja + + {# template.html will have access to the variables from the current context and the additional ones provided #} + {% include 'template.html' with {'foo': 'bar'} %} + + {% set vars = {'foo': 'bar'} %} + {% include 'template.html' with vars %} + +You can disable access to the context by appending the ``only`` keyword: + +.. code-block:: jinja + + {# only the foo variable will be accessible #} + {% include 'template.html' with {'foo': 'bar'} only %} + +.. code-block:: jinja + + {# no variables will be accessible #} + {% include 'template.html' only %} + +.. tip:: + + When including a template created by an end user, you should consider + sandboxing it. More information in the :doc:`Twig for Developers<../api>` + chapter and in the :doc:`sandbox<../tags/sandbox>` tag documentation. + +The template name can be any valid Twig expression: + +.. code-block:: jinja + + {% include some_var %} + {% include ajax ? 'ajax.html' : 'not_ajax.html' %} + +And if the expression evaluates to a ``Twig_Template`` or a +``Twig_TemplateWrapper`` instance, Twig will use it directly:: + + // {% include template %} + + // deprecated as of Twig 1.28 + $template = $twig->loadTemplate('some_template.twig'); + + // as of Twig 1.28 + $template = $twig->load('some_template.twig'); + + $twig->display('template.twig', array('template' => $template)); + +.. versionadded:: 1.2 + The ``ignore missing`` feature has been added in Twig 1.2. + +You can mark an include with ``ignore missing`` in which case Twig will ignore +the statement if the template to be included does not exist. It has to be +placed just after the template name. Here some valid examples: + +.. code-block:: jinja + + {% include 'sidebar.html' ignore missing %} + {% include 'sidebar.html' ignore missing with {'foo': 'bar'} %} + {% include 'sidebar.html' ignore missing only %} + +.. versionadded:: 1.2 + The possibility to pass an array of templates has been added in Twig 1.2. + +You can also provide a list of templates that are checked for existence before +inclusion. The first template that exists will be included: + +.. code-block:: jinja + + {% include ['page_detailed.html', 'page.html'] %} + +If ``ignore missing`` is given, it will fall back to rendering nothing if none +of the templates exist, otherwise it will throw an exception. diff --git a/vendor/twig/twig/doc/tags/index.rst b/vendor/twig/twig/doc/tags/index.rst new file mode 100644 index 000000000..dbe2459e3 --- /dev/null +++ b/vendor/twig/twig/doc/tags/index.rst @@ -0,0 +1,25 @@ +Tags +==== + +.. toctree:: + :maxdepth: 1 + + autoescape + block + do + embed + extends + filter + flush + for + from + if + import + include + macro + sandbox + set + spaceless + use + verbatim + with diff --git a/vendor/twig/twig/doc/tags/macro.rst b/vendor/twig/twig/doc/tags/macro.rst new file mode 100644 index 000000000..a8aa76fd9 --- /dev/null +++ b/vendor/twig/twig/doc/tags/macro.rst @@ -0,0 +1,103 @@ +``macro`` +========= + +Macros are comparable with functions in regular programming languages. They +are useful to put often used HTML idioms into reusable elements to not repeat +yourself. + +Here is a small example of a macro that renders a form element: + +.. code-block:: jinja + + {% macro input(name, value, type, size) %} + + {% endmacro %} + +Macros differ from native PHP functions in a few ways: + +* Default argument values are defined by using the ``default`` filter in the + macro body; + +* Arguments of a macro are always optional. + +* If extra positional arguments are passed to a macro, they end up in the + special ``varargs`` variable as a list of values. + +But as with PHP functions, macros don't have access to the current template +variables. + +.. tip:: + + You can pass the whole context as an argument by using the special + ``_context`` variable. + +Import +------ + +Macros can be defined in any template, and need to be "imported" before being +used (see the documentation for the :doc:`import<../tags/import>` tag for more +information): + +.. code-block:: jinja + + {% import "forms.html" as forms %} + +The above ``import`` call imports the "forms.html" file (which can contain only +macros, or a template and some macros), and import the functions as items of +the ``forms`` variable. + +The macro can then be called at will: + +.. code-block:: jinja + +

    {{ forms.input('username') }}

    +

    {{ forms.input('password', null, 'password') }}

    + +If macros are defined and used in the same template, you can use the +special ``_self`` variable to import them: + +.. code-block:: jinja + + {% import _self as forms %} + +

    {{ forms.input('username') }}

    + +.. warning:: + + When you define a macro in the template where you are going to use it, you + might be tempted to call the macro directly via ``_self.input()`` instead + of importing it; even if seems to work, this is just a side-effect of the + current implementation and it won't work anymore in Twig 2.x. + +When you want to use a macro in another macro from the same file, you need to +import it locally: + +.. code-block:: jinja + + {% macro input(name, value, type, size) %} + + {% endmacro %} + + {% macro wrapped_input(name, value, type, size) %} + {% import _self as forms %} + +
    + {{ forms.input(name, value, type, size) }} +
    + {% endmacro %} + +Named Macro End-Tags +-------------------- + +Twig allows you to put the name of the macro after the end tag for better +readability: + +.. code-block:: jinja + + {% macro input() %} + ... + {% endmacro input %} + +Of course, the name after the ``endmacro`` word must match the macro name. + +.. seealso:: :doc:`from<../tags/from>`, :doc:`import<../tags/import>` diff --git a/vendor/twig/twig/doc/tags/sandbox.rst b/vendor/twig/twig/doc/tags/sandbox.rst new file mode 100644 index 000000000..e186726c2 --- /dev/null +++ b/vendor/twig/twig/doc/tags/sandbox.rst @@ -0,0 +1,30 @@ +``sandbox`` +=========== + +The ``sandbox`` tag can be used to enable the sandboxing mode for an included +template, when sandboxing is not enabled globally for the Twig environment: + +.. code-block:: jinja + + {% sandbox %} + {% include 'user.html' %} + {% endsandbox %} + +.. warning:: + + The ``sandbox`` tag is only available when the sandbox extension is + enabled (see the :doc:`Twig for Developers<../api>` chapter). + +.. note:: + + The ``sandbox`` tag can only be used to sandbox an include tag and it + cannot be used to sandbox a section of a template. The following example + won't work: + + .. code-block:: jinja + + {% sandbox %} + {% for i in 1..2 %} + {{ i }} + {% endfor %} + {% endsandbox %} diff --git a/vendor/twig/twig/doc/tags/set.rst b/vendor/twig/twig/doc/tags/set.rst new file mode 100644 index 000000000..3eba239a9 --- /dev/null +++ b/vendor/twig/twig/doc/tags/set.rst @@ -0,0 +1,78 @@ +``set`` +======= + +Inside code blocks you can also assign values to variables. Assignments use +the ``set`` tag and can have multiple targets. + +Here is how you can assign the ``bar`` value to the ``foo`` variable: + +.. code-block:: jinja + + {% set foo = 'bar' %} + +After the ``set`` call, the ``foo`` variable is available in the template like +any other ones: + +.. code-block:: jinja + + {# displays bar #} + {{ foo }} + +The assigned value can be any valid :ref:`Twig expressions +`: + +.. code-block:: jinja + + {% set foo = [1, 2] %} + {% set foo = {'foo': 'bar'} %} + {% set foo = 'foo' ~ 'bar' %} + +Several variables can be assigned in one block: + +.. code-block:: jinja + + {% set foo, bar = 'foo', 'bar' %} + + {# is equivalent to #} + + {% set foo = 'foo' %} + {% set bar = 'bar' %} + +The ``set`` tag can also be used to 'capture' chunks of text: + +.. code-block:: jinja + + {% set foo %} + + {% endset %} + +.. caution:: + + If you enable automatic output escaping, Twig will only consider the + content to be safe when capturing chunks of text. + +.. note:: + + Note that loops are scoped in Twig; therefore a variable declared inside a + ``for`` loop is not accessible outside the loop itself: + + .. code-block:: jinja + + {% for item in list %} + {% set foo = item %} + {% endfor %} + + {# foo is NOT available #} + + If you want to access the variable, just declare it before the loop: + + .. code-block:: jinja + + {% set foo = "" %} + {% for item in list %} + {% set foo = item %} + {% endfor %} + + {# foo is available #} diff --git a/vendor/twig/twig/doc/tags/spaceless.rst b/vendor/twig/twig/doc/tags/spaceless.rst new file mode 100644 index 000000000..b39cb27ef --- /dev/null +++ b/vendor/twig/twig/doc/tags/spaceless.rst @@ -0,0 +1,37 @@ +``spaceless`` +============= + +Use the ``spaceless`` tag to remove whitespace *between HTML tags*, not +whitespace within HTML tags or whitespace in plain text: + +.. code-block:: jinja + + {% spaceless %} +
    + foo +
    + {% endspaceless %} + + {# output will be
    foo
    #} + +This tag is not meant to "optimize" the size of the generated HTML content but +merely to avoid extra whitespace between HTML tags to avoid browser rendering +quirks under some circumstances. + +.. tip:: + + If you want to optimize the size of the generated HTML content, gzip + compress the output instead. + +.. tip:: + + If you want to create a tag that actually removes all extra whitespace in + an HTML string, be warned that this is not as easy as it seems to be + (think of ``textarea`` or ``pre`` tags for instance). Using a third-party + library like Tidy is probably a better idea. + +.. tip:: + + For more information on whitespace control, read the + :ref:`dedicated section ` of the documentation and learn how + you can also use the whitespace control modifier on your tags. diff --git a/vendor/twig/twig/doc/tags/use.rst b/vendor/twig/twig/doc/tags/use.rst new file mode 100644 index 000000000..a6fdefb46 --- /dev/null +++ b/vendor/twig/twig/doc/tags/use.rst @@ -0,0 +1,124 @@ +``use`` +======= + +.. versionadded:: 1.1 + Horizontal reuse was added in Twig 1.1. + +.. note:: + + Horizontal reuse is an advanced Twig feature that is hardly ever needed in + regular templates. It is mainly used by projects that need to make + template blocks reusable without using inheritance. + +Template inheritance is one of the most powerful features of Twig but it is +limited to single inheritance; a template can only extend one other template. +This limitation makes template inheritance simple to understand and easy to +debug: + +.. code-block:: jinja + + {% extends "base.html" %} + + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +Horizontal reuse is a way to achieve the same goal as multiple inheritance, +but without the associated complexity: + +.. code-block:: jinja + + {% extends "base.html" %} + + {% use "blocks.html" %} + + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +The ``use`` statement tells Twig to import the blocks defined in +``blocks.html`` into the current template (it's like macros, but for blocks): + +.. code-block:: jinja + + {# blocks.html #} + + {% block sidebar %}{% endblock %} + +In this example, the ``use`` statement imports the ``sidebar`` block into the +main template. The code is mostly equivalent to the following one (the +imported blocks are not outputted automatically): + +.. code-block:: jinja + + {% extends "base.html" %} + + {% block sidebar %}{% endblock %} + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +.. note:: + + The ``use`` tag only imports a template if it does not extend another + template, if it does not define macros, and if the body is empty. But it + can *use* other templates. + +.. note:: + + Because ``use`` statements are resolved independently of the context + passed to the template, the template reference cannot be an expression. + +The main template can also override any imported block. If the template +already defines the ``sidebar`` block, then the one defined in ``blocks.html`` +is ignored. To avoid name conflicts, you can rename imported blocks: + +.. code-block:: jinja + + {% extends "base.html" %} + + {% use "blocks.html" with sidebar as base_sidebar, title as base_title %} + + {% block sidebar %}{% endblock %} + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +.. versionadded:: 1.3 + The ``parent()`` support was added in Twig 1.3. + +The ``parent()`` function automatically determines the correct inheritance +tree, so it can be used when overriding a block defined in an imported +template: + +.. code-block:: jinja + + {% extends "base.html" %} + + {% use "blocks.html" %} + + {% block sidebar %} + {{ parent() }} + {% endblock %} + + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +In this example, ``parent()`` will correctly call the ``sidebar`` block from +the ``blocks.html`` template. + +.. tip:: + + In Twig 1.2, renaming allows you to simulate inheritance by calling the + "parent" block: + + .. code-block:: jinja + + {% extends "base.html" %} + + {% use "blocks.html" with sidebar as parent_sidebar %} + + {% block sidebar %} + {{ block('parent_sidebar') }} + {% endblock %} + +.. note:: + + You can use as many ``use`` statements as you want in any given template. + If two imported templates define the same block, the latest one wins. diff --git a/vendor/twig/twig/doc/tags/verbatim.rst b/vendor/twig/twig/doc/tags/verbatim.rst new file mode 100644 index 000000000..fe61ca1b0 --- /dev/null +++ b/vendor/twig/twig/doc/tags/verbatim.rst @@ -0,0 +1,24 @@ +``verbatim`` +============ + +.. versionadded:: 1.12 + The ``verbatim`` tag was added in Twig 1.12 (it was named ``raw`` before). + +The ``verbatim`` tag marks sections as being raw text that should not be +parsed. For example to put Twig syntax as example into a template you can use +this snippet: + +.. code-block:: jinja + + {% verbatim %} +
      + {% for item in seq %} +
    • {{ item }}
    • + {% endfor %} +
    + {% endverbatim %} + +.. note:: + + The ``verbatim`` tag works in the exact same way as the old ``raw`` tag, + but was renamed to avoid confusion with the ``raw`` filter. \ No newline at end of file diff --git a/vendor/twig/twig/doc/tags/with.rst b/vendor/twig/twig/doc/tags/with.rst new file mode 100644 index 000000000..815b06992 --- /dev/null +++ b/vendor/twig/twig/doc/tags/with.rst @@ -0,0 +1,44 @@ +``with`` +======== + +.. versionadded:: 1.28 + The ``with`` tag was added in Twig 1.28. + +Use the ``with`` tag to create a new inner scope. Variables set within this +scope are not visible outside of the scope: + +.. code-block:: jinja + + {% with %} + {% set foo = 42 %} + {{ foo }} foo is 42 here + {% endwith %} + foo is not visible here any longer + +Instead of defining variables at the beginning of the scope, you can pass a +hash of variables you want to define in the ``with`` tag; the previous example +is equivalent to the following one: + +.. code-block:: jinja + + {% with { foo: 42 } %} + {{ foo }} foo is 42 here + {% endwith %} + foo is not visible here any longer + + {# it works with any expression that resolves to a hash #} + {% set vars = { foo: 42 } %} + {% with vars %} + ... + {% endwith %} + +By default, the inner scope has access to the outer scope context; you can +disable this behavior by appending the ``only`` keyword: + +.. code-block:: jinja + + {% set bar = 'bar' %} + {% with { foo: 42 } only %} + {# only foo is defined #} + {# bar is not defined #} + {% endwith %} diff --git a/vendor/twig/twig/doc/templates.rst b/vendor/twig/twig/doc/templates.rst new file mode 100644 index 000000000..d4dbe32d6 --- /dev/null +++ b/vendor/twig/twig/doc/templates.rst @@ -0,0 +1,908 @@ +Twig for Template Designers +=========================== + +This document describes the syntax and semantics of the template engine and +will be most useful as reference to those creating Twig templates. + +Synopsis +-------- + +A template is simply a text file. It can generate any text-based format (HTML, +XML, CSV, LaTeX, etc.). It doesn't have a specific extension, ``.html`` or +``.xml`` are just fine. + +A template contains **variables** or **expressions**, which get replaced with +values when the template is evaluated, and **tags**, which control the logic +of the template. + +Below is a minimal template that illustrates a few basics. We will cover further +details later on: + +.. code-block:: html+jinja + + + + + My Webpage + + + + +

    My Webpage

    + {{ a_variable }} + + + +There are two kinds of delimiters: ``{% ... %}`` and ``{{ ... }}``. The first +one is used to execute statements such as for-loops, the latter prints the +result of an expression to the template. + +IDEs Integration +---------------- + +Many IDEs support syntax highlighting and auto-completion for Twig: + +* *Textmate* via the `Twig bundle`_ +* *Vim* via the `Jinja syntax plugin`_ or the `vim-twig plugin`_ +* *Netbeans* via the `Twig syntax plugin`_ (until 7.1, native as of 7.2) +* *PhpStorm* (native as of 2.1) +* *Eclipse* via the `Twig plugin`_ +* *Sublime Text* via the `Twig bundle`_ +* *GtkSourceView* via the `Twig language definition`_ (used by gedit and other projects) +* *Coda* and *SubEthaEdit* via the `Twig syntax mode`_ +* *Coda 2* via the `other Twig syntax mode`_ +* *Komodo* and *Komodo Edit* via the Twig highlight/syntax check mode +* *Notepad++* via the `Notepad++ Twig Highlighter`_ +* *Emacs* via `web-mode.el`_ +* *Atom* via the `PHP-twig for atom`_ +* *Visual Studio Code* via the `Twig pack`_ + +Also, `TwigFiddle`_ is an online service that allows you to execute Twig templates +from a browser; it supports all versions of Twig. + +Variables +--------- + +The application passes variables to the templates for manipulation in the +template. Variables may have attributes or elements you can access, +too. The visual representation of a variable depends heavily on the application providing +it. + +You can use a dot (``.``) to access attributes of a variable (methods or +properties of a PHP object, or items of a PHP array), or the so-called +"subscript" syntax (``[]``): + +.. code-block:: jinja + + {{ foo.bar }} + {{ foo['bar'] }} + +When the attribute contains special characters (like ``-`` that would be +interpreted as the minus operator), use the ``attribute`` function instead to +access the variable attribute: + +.. code-block:: jinja + + {# equivalent to the non-working foo.data-foo #} + {{ attribute(foo, 'data-foo') }} + +.. note:: + + It's important to know that the curly braces are *not* part of the + variable but the print statement. When accessing variables inside tags, + don't put the braces around them. + +If a variable or attribute does not exist, you will receive a ``null`` value +when the ``strict_variables`` option is set to ``false``; alternatively, if ``strict_variables`` +is set, Twig will throw an error (see :ref:`environment options`). + +.. sidebar:: Implementation + + For convenience's sake ``foo.bar`` does the following things on the PHP + layer: + + * check if ``foo`` is an array and ``bar`` a valid element; + * if not, and if ``foo`` is an object, check that ``bar`` is a valid property; + * if not, and if ``foo`` is an object, check that ``bar`` is a valid method + (even if ``bar`` is the constructor - use ``__construct()`` instead); + * if not, and if ``foo`` is an object, check that ``getBar`` is a valid method; + * if not, and if ``foo`` is an object, check that ``isBar`` is a valid method; + * if not, return a ``null`` value. + + ``foo['bar']`` on the other hand only works with PHP arrays: + + * check if ``foo`` is an array and ``bar`` a valid element; + * if not, return a ``null`` value. + +.. note:: + + If you want to access a dynamic attribute of a variable, use the + :doc:`attribute` function instead. + +Global Variables +~~~~~~~~~~~~~~~~ + +The following variables are always available in templates: + +* ``_self``: references the current template; +* ``_context``: references the current context; +* ``_charset``: references the current charset. + +Setting Variables +~~~~~~~~~~~~~~~~~ + +You can assign values to variables inside code blocks. Assignments use the +:doc:`set` tag: + +.. code-block:: jinja + + {% set foo = 'foo' %} + {% set foo = [1, 2] %} + {% set foo = {'foo': 'bar'} %} + +Filters +------- + +Variables can be modified by **filters**. Filters are separated from the +variable by a pipe symbol (``|``) and may have optional arguments in +parentheses. Multiple filters can be chained. The output of one filter is +applied to the next. + +The following example removes all HTML tags from the ``name`` and title-cases +it: + +.. code-block:: jinja + + {{ name|striptags|title }} + +Filters that accept arguments have parentheses around the arguments. This +example will join a list by commas: + +.. code-block:: jinja + + {{ list|join(', ') }} + +To apply a filter on a section of code, wrap it in the +:doc:`filter` tag: + +.. code-block:: jinja + + {% filter upper %} + This text becomes uppercase + {% endfilter %} + +Go to the :doc:`filters` page to learn more about built-in +filters. + +Functions +--------- + +Functions can be called to generate content. Functions are called by their +name followed by parentheses (``()``) and may have arguments. + +For instance, the ``range`` function returns a list containing an arithmetic +progression of integers: + +.. code-block:: jinja + + {% for i in range(0, 3) %} + {{ i }}, + {% endfor %} + +Go to the :doc:`functions` page to learn more about the +built-in functions. + +Named Arguments +--------------- + +.. versionadded:: 1.12 + Support for named arguments was added in Twig 1.12. + +.. code-block:: jinja + + {% for i in range(low=1, high=10, step=2) %} + {{ i }}, + {% endfor %} + +Using named arguments makes your templates more explicit about the meaning of +the values you pass as arguments: + +.. code-block:: jinja + + {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }} + + {# versus #} + + {{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }} + +Named arguments also allow you to skip some arguments for which you don't want +to change the default value: + +.. code-block:: jinja + + {# the first argument is the date format, which defaults to the global date format if null is passed #} + {{ "now"|date(null, "Europe/Paris") }} + + {# or skip the format value by using a named argument for the time zone #} + {{ "now"|date(timezone="Europe/Paris") }} + +You can also use both positional and named arguments in one call, in which +case positional arguments must always come before named arguments: + +.. code-block:: jinja + + {{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }} + +.. tip:: + + Each function and filter documentation page has a section where the names + of all arguments are listed when supported. + +Control Structure +----------------- + +A control structure refers to all those things that control the flow of a +program - conditionals (i.e. ``if``/``elseif``/``else``), ``for``-loops, as +well as things like blocks. Control structures appear inside ``{% ... %}`` +blocks. + +For example, to display a list of users provided in a variable called +``users``, use the :doc:`for` tag: + +.. code-block:: jinja + +

    Members

    +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    + +The :doc:`if` tag can be used to test an expression: + +.. code-block:: jinja + + {% if users|length > 0 %} +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    + {% endif %} + +Go to the :doc:`tags` page to learn more about the built-in tags. + +Comments +-------- + +To comment-out part of a line in a template, use the comment syntax ``{# ... +#}``. This is useful for debugging or to add information for other template +designers or yourself: + +.. code-block:: jinja + + {# note: disabled template because we no longer use this + {% for user in users %} + ... + {% endfor %} + #} + +Including other Templates +------------------------- + +The :doc:`include` function is useful to include a template +and return the rendered content of that template into the current one: + +.. code-block:: jinja + + {{ include('sidebar.html') }} + +By default, included templates have access to the same context as the template +which includes them. This means that any variable defined in the main template +will be available in the included template too: + +.. code-block:: jinja + + {% for box in boxes %} + {{ include('render_box.html') }} + {% endfor %} + +The included template ``render_box.html`` is able to access the ``box`` variable. + +The filename of the template depends on the template loader. For instance, the +``Twig_Loader_Filesystem`` allows you to access other templates by giving the +filename. You can access templates in subdirectories with a slash: + +.. code-block:: jinja + + {{ include('sections/articles/sidebar.html') }} + +This behavior depends on the application embedding Twig. + +Template Inheritance +-------------------- + +The most powerful part of Twig is template inheritance. Template inheritance +allows you to build a base "skeleton" template that contains all the common +elements of your site and defines **blocks** that child templates can +override. + +Sounds complicated but it is very basic. It's easier to understand it by +starting with an example. + +Let's define a base template, ``base.html``, which defines a simple HTML +skeleton document that you might use for a simple two-column page: + +.. code-block:: html+jinja + + + + + {% block head %} + + {% block title %}{% endblock %} - My Webpage + {% endblock %} + + +
    {% block content %}{% endblock %}
    + + + + +In this example, the :doc:`block` tags define four blocks that +child templates can fill in. All the ``block`` tag does is to tell the +template engine that a child template may override those portions of the +template. + +A child template might look like this: + +.. code-block:: jinja + + {% extends "base.html" %} + + {% block title %}Index{% endblock %} + {% block head %} + {{ parent() }} + + {% endblock %} + {% block content %} +

    Index

    +

    + Welcome to my awesome homepage. +

    + {% endblock %} + +The :doc:`extends` tag is the key here. It tells the template +engine that this template "extends" another template. When the template system +evaluates this template, first it locates the parent. The extends tag should +be the first tag in the template. + +Note that since the child template doesn't define the ``footer`` block, the +value from the parent template is used instead. + +It's possible to render the contents of the parent block by using the +:doc:`parent` function. This gives back the results of the +parent block: + +.. code-block:: jinja + + {% block sidebar %} +

    Table Of Contents

    + ... + {{ parent() }} + {% endblock %} + +.. tip:: + + The documentation page for the :doc:`extends` tag describes + more advanced features like block nesting, scope, dynamic inheritance, and + conditional inheritance. + +.. note:: + + Twig also supports multiple inheritance with the so called horizontal reuse + with the help of the :doc:`use` tag. This is an advanced feature + hardly ever needed in regular templates. + +HTML Escaping +------------- + +When generating HTML from templates, there's always a risk that a variable +will include characters that affect the resulting HTML. There are two +approaches: manually escaping each variable or automatically escaping +everything by default. + +Twig supports both, automatic escaping is enabled by default. + +The automatic escaping strategy can be configured via the +:ref:`autoescape` option and defaults to ``html``. + +Working with Manual Escaping +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If manual escaping is enabled, it is **your** responsibility to escape +variables if needed. What to escape? Any variable you don't trust. + +Escaping works by piping the variable through the +:doc:`escape` or ``e`` filter: + +.. code-block:: jinja + + {{ user.username|e }} + +By default, the ``escape`` filter uses the ``html`` strategy, but depending on +the escaping context, you might want to explicitly use any other available +strategies: + +.. code-block:: jinja + + {{ user.username|e('js') }} + {{ user.username|e('css') }} + {{ user.username|e('url') }} + {{ user.username|e('html_attr') }} + +Working with Automatic Escaping +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Whether automatic escaping is enabled or not, you can mark a section of a +template to be escaped or not by using the :doc:`autoescape` +tag: + +.. code-block:: jinja + + {% autoescape %} + Everything will be automatically escaped in this block (using the HTML strategy) + {% endautoescape %} + +By default, auto-escaping uses the ``html`` escaping strategy. If you output +variables in other contexts, you need to explicitly escape them with the +appropriate escaping strategy: + +.. code-block:: jinja + + {% autoescape 'js' %} + Everything will be automatically escaped in this block (using the JS strategy) + {% endautoescape %} + +Escaping +-------- + +It is sometimes desirable or even necessary to have Twig ignore parts it would +otherwise handle as variables or blocks. For example if the default syntax is +used and you want to use ``{{`` as raw string in the template and not start a +variable you have to use a trick. + +The easiest way is to output the variable delimiter (``{{``) by using a variable +expression: + +.. code-block:: jinja + + {{ '{{' }} + +For bigger sections it makes sense to mark a block +:doc:`verbatim`. + +Macros +------ + +.. versionadded:: 1.12 + Support for default argument values was added in Twig 1.12. + +Macros are comparable with functions in regular programming languages. They +are useful to reuse often used HTML fragments to not repeat yourself. + +A macro is defined via the :doc:`macro` tag. Here is a small example +(subsequently called ``forms.html``) of a macro that renders a form element: + +.. code-block:: jinja + + {% macro input(name, value, type, size) %} + + {% endmacro %} + +Macros can be defined in any template, and need to be "imported" via the +:doc:`import` tag before being used: + +.. code-block:: jinja + + {% import "forms.html" as forms %} + +

    {{ forms.input('username') }}

    + +Alternatively, you can import individual macro names from a template into the +current namespace via the :doc:`from` tag and optionally alias them: + +.. code-block:: jinja + + {% from 'forms.html' import input as input_field %} + +
    +
    Username
    +
    {{ input_field('username') }}
    +
    Password
    +
    {{ input_field('password', '', 'password') }}
    +
    + +A default value can also be defined for macro arguments when not provided in a +macro call: + +.. code-block:: jinja + + {% macro input(name, value = "", type = "text", size = 20) %} + + {% endmacro %} + +If extra positional arguments are passed to a macro call, they end up in the +special ``varargs`` variable as a list of values. + +.. _twig-expressions: + +Expressions +----------- + +Twig allows expressions everywhere. These work very similar to regular PHP and +even if you're not working with PHP you should feel comfortable with it. + +.. note:: + + The operator precedence is as follows, with the lowest-precedence + operators listed first: ``b-and``, ``b-xor``, ``b-or``, ``or``, ``and``, + ``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``, ``in``, ``matches``, + ``starts with``, ``ends with``, ``..``, ``+``, ``-``, ``~``, ``*``, ``/``, + ``//``, ``%``, ``is``, ``**``, ``|``, ``[]``, and ``.``: + + .. code-block:: jinja + + {% set greeting = 'Hello ' %} + {% set name = 'Fabien' %} + + {{ greeting ~ name|lower }} {# Hello fabien #} + + {# use parenthesis to change precedence #} + {{ (greeting ~ name)|lower }} {# hello fabien #} + +Literals +~~~~~~~~ + +.. versionadded:: 1.5 + Support for hash keys as names and expressions was added in Twig 1.5. + +The simplest form of expressions are literals. Literals are representations +for PHP types such as strings, numbers, and arrays. The following literals +exist: + +* ``"Hello World"``: Everything between two double or single quotes is a + string. They are useful whenever you need a string in the template (for + example as arguments to function calls, filters or just to extend or include + a template). A string can contain a delimiter if it is preceded by a + backslash (``\``) -- like in ``'It\'s good'``. If the string contains a + backslash (e.g. ``'c:\Program Files'``) escape it by doubling it + (e.g. ``'c:\\Program Files'``). + +* ``42`` / ``42.23``: Integers and floating point numbers are created by just + writing the number down. If a dot is present the number is a float, + otherwise an integer. + +* ``["foo", "bar"]``: Arrays are defined by a sequence of expressions + separated by a comma (``,``) and wrapped with squared brackets (``[]``). + +* ``{"foo": "bar"}``: Hashes are defined by a list of keys and values + separated by a comma (``,``) and wrapped with curly braces (``{}``): + + .. code-block:: jinja + + {# keys as string #} + { 'foo': 'foo', 'bar': 'bar' } + + {# keys as names (equivalent to the previous hash) -- as of Twig 1.5 #} + { foo: 'foo', bar: 'bar' } + + {# keys as integer #} + { 2: 'foo', 4: 'bar' } + + {# keys as expressions (the expression must be enclosed into parentheses) -- as of Twig 1.5 #} + { (1 + 1): 'foo', (a ~ 'b'): 'bar' } + +* ``true`` / ``false``: ``true`` represents the true value, ``false`` + represents the false value. + +* ``null``: ``null`` represents no specific value. This is the value returned + when a variable does not exist. ``none`` is an alias for ``null``. + +Arrays and hashes can be nested: + +.. code-block:: jinja + + {% set foo = [1, {"foo": "bar"}] %} + +.. tip:: + + Using double-quoted or single-quoted strings has no impact on performance + but string interpolation is only supported in double-quoted strings. + +Math +~~~~ + +Twig allows you to calculate with values. This is rarely useful in templates +but exists for completeness' sake. The following operators are supported: + +* ``+``: Adds two objects together (the operands are casted to numbers). ``{{ + 1 + 1 }}`` is ``2``. + +* ``-``: Subtracts the second number from the first one. ``{{ 3 - 2 }}`` is + ``1``. + +* ``/``: Divides two numbers. The returned value will be a floating point + number. ``{{ 1 / 2 }}`` is ``{{ 0.5 }}``. + +* ``%``: Calculates the remainder of an integer division. ``{{ 11 % 7 }}`` is + ``4``. + +* ``//``: Divides two numbers and returns the floored integer result. ``{{ 20 + // 7 }}`` is ``2``, ``{{ -20 // 7 }}`` is ``-3`` (this is just syntactic + sugar for the :doc:`round` filter). + +* ``*``: Multiplies the left operand with the right one. ``{{ 2 * 2 }}`` would + return ``4``. + +* ``**``: Raises the left operand to the power of the right operand. ``{{ 2 ** + 3 }}`` would return ``8``. + +Logic +~~~~~ + +You can combine multiple expressions with the following operators: + +* ``and``: Returns true if the left and the right operands are both true. + +* ``or``: Returns true if the left or the right operand is true. + +* ``not``: Negates a statement. + +* ``(expr)``: Groups an expression. + +.. note:: + + Twig also support bitwise operators (``b-and``, ``b-xor``, and ``b-or``). + +.. note:: + + Operators are case sensitive. + +Comparisons +~~~~~~~~~~~ + +The following comparison operators are supported in any expression: ``==``, +``!=``, ``<``, ``>``, ``>=``, and ``<=``. + +You can also check if a string ``starts with`` or ``ends with`` another +string: + +.. code-block:: jinja + + {% if 'Fabien' starts with 'F' %} + {% endif %} + + {% if 'Fabien' ends with 'n' %} + {% endif %} + +.. note:: + + For complex string comparisons, the ``matches`` operator allows you to use + `regular expressions`_: + + .. code-block:: jinja + + {% if phone matches '/^[\\d\\.]+$/' %} + {% endif %} + +Containment Operator +~~~~~~~~~~~~~~~~~~~~ + +The ``in`` operator performs containment test. + +It returns ``true`` if the left operand is contained in the right: + +.. code-block:: jinja + + {# returns true #} + + {{ 1 in [1, 2, 3] }} + + {{ 'cd' in 'abcde' }} + +.. tip:: + + You can use this filter to perform a containment test on strings, arrays, + or objects implementing the ``Traversable`` interface. + +To perform a negative test, use the ``not in`` operator: + +.. code-block:: jinja + + {% if 1 not in [1, 2, 3] %} + + {# is equivalent to #} + {% if not (1 in [1, 2, 3]) %} + +Test Operator +~~~~~~~~~~~~~ + +The ``is`` operator performs tests. Tests can be used to test a variable against +a common expression. The right operand is name of the test: + +.. code-block:: jinja + + {# find out if a variable is odd #} + + {{ name is odd }} + +Tests can accept arguments too: + +.. code-block:: jinja + + {% if post.status is constant('Post::PUBLISHED') %} + +Tests can be negated by using the ``is not`` operator: + +.. code-block:: jinja + + {% if post.status is not constant('Post::PUBLISHED') %} + + {# is equivalent to #} + {% if not (post.status is constant('Post::PUBLISHED')) %} + +Go to the :doc:`tests` page to learn more about the built-in +tests. + +Other Operators +~~~~~~~~~~~~~~~ + +.. versionadded:: 1.12.0 + Support for the extended ternary operator was added in Twig 1.12.0. + +The following operators don't fit into any of the other categories: + +* ``|``: Applies a filter. + +* ``..``: Creates a sequence based on the operand before and after the operator + (this is just syntactic sugar for the :doc:`range` function): + + .. code-block:: jinja + + {{ 1..5 }} + + {# equivalent to #} + {{ range(1, 5) }} + + Note that you must use parentheses when combining it with the filter operator + due to the :ref:`operator precedence rules `: + + .. code-block:: jinja + + (1..5)|join(', ') + +* ``~``: Converts all operands into strings and concatenates them. ``{{ "Hello + " ~ name ~ "!" }}`` would return (assuming ``name`` is ``'John'``) ``Hello + John!``. + +* ``.``, ``[]``: Gets an attribute of an object. + +* ``?:``: The ternary operator: + + .. code-block:: jinja + + {{ foo ? 'yes' : 'no' }} + + {# as of Twig 1.12.0 #} + {{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }} + {{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }} + +* ``??``: The null-coalescing operator: + + .. code-block:: jinja + + {# returns the value of foo if it is defined and not null, 'no' otherwise #} + {{ foo ?? 'no' }} + +String Interpolation +~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.5 + String interpolation was added in Twig 1.5. + +String interpolation (``#{expression}``) allows any valid expression to appear +within a *double-quoted string*. The result of evaluating that expression is +inserted into the string: + +.. code-block:: jinja + + {{ "foo #{bar} baz" }} + {{ "foo #{1 + 2} baz" }} + +.. _templates-whitespace-control: + +Whitespace Control +------------------ + +.. versionadded:: 1.1 + Tag level whitespace control was added in Twig 1.1. + +The first newline after a template tag is removed automatically (like in PHP.) +Whitespace is not further modified by the template engine, so each whitespace +(spaces, tabs, newlines etc.) is returned unchanged. + +Use the ``spaceless`` tag to remove whitespace *between HTML tags*: + +.. code-block:: jinja + + {% spaceless %} +
    + foo bar +
    + {% endspaceless %} + + {# output will be
    foo bar
    #} + +In addition to the spaceless tag you can also control whitespace on a per tag +level. By using the whitespace control modifier on your tags, you can trim +leading and or trailing whitespace: + +.. code-block:: jinja + + {% set value = 'no spaces' %} + {#- No leading/trailing whitespace -#} + {%- if true -%} + {{- value -}} + {%- endif -%} + + {# output 'no spaces' #} + +The above sample shows the default whitespace control modifier, and how you can +use it to remove whitespace around tags. Trimming space will consume all whitespace +for that side of the tag. It is possible to use whitespace trimming on one side +of a tag: + +.. code-block:: jinja + + {% set value = 'no spaces' %} +
  • {{- value }}
  • + + {# outputs '
  • no spaces
  • ' #} + +Extensions +---------- + +Twig can be easily extended. + +If you are looking for new tags, filters, or functions, have a look at the Twig official +`extension repository`_. + +If you want to create your own, read the :ref:`Creating an +Extension` chapter. + +.. _`Twig bundle`: https://github.com/Anomareh/PHP-Twig.tmbundle +.. _`Jinja syntax plugin`: http://jinja.pocoo.org/docs/integration/#vim +.. _`vim-twig plugin`: https://github.com/lumiliet/vim-twig +.. _`Twig syntax plugin`: http://plugins.netbeans.org/plugin/37069/php-twig +.. _`Twig plugin`: https://github.com/pulse00/Twig-Eclipse-Plugin +.. _`Twig language definition`: https://github.com/gabrielcorpse/gedit-twig-template-language +.. _`extension repository`: http://github.com/twigphp/Twig-extensions +.. _`Twig syntax mode`: https://github.com/bobthecow/Twig-HTML.mode +.. _`other Twig syntax mode`: https://github.com/muxx/Twig-HTML.mode +.. _`Notepad++ Twig Highlighter`: https://github.com/Banane9/notepadplusplus-twig +.. _`web-mode.el`: http://web-mode.org/ +.. _`regular expressions`: http://php.net/manual/en/pcre.pattern.php +.. _`PHP-twig for atom`: https://github.com/reesef/php-twig +.. _`TwigFiddle`: http://twigfiddle.com/ +.. _`Twig pack`: https://marketplace.visualstudio.com/items?itemName=bajdzis.vscode-twig-pack diff --git a/vendor/twig/twig/doc/tests/constant.rst b/vendor/twig/twig/doc/tests/constant.rst new file mode 100644 index 000000000..8d0724a80 --- /dev/null +++ b/vendor/twig/twig/doc/tests/constant.rst @@ -0,0 +1,22 @@ +``constant`` +============ + +.. versionadded: 1.13.1 + constant now accepts object instances as the second argument. + +``constant`` checks if a variable has the exact same value as a constant. You +can use either global constants or class constants: + +.. code-block:: jinja + + {% if post.status is constant('Post::PUBLISHED') %} + the status attribute is exactly the same as Post::PUBLISHED + {% endif %} + +You can test constants from object instances as well: + +.. code-block:: jinja + + {% if post.status is constant('PUBLISHED', post) %} + the status attribute is exactly the same as Post::PUBLISHED + {% endif %} diff --git a/vendor/twig/twig/doc/tests/defined.rst b/vendor/twig/twig/doc/tests/defined.rst new file mode 100644 index 000000000..702ce7256 --- /dev/null +++ b/vendor/twig/twig/doc/tests/defined.rst @@ -0,0 +1,30 @@ +``defined`` +=========== + +``defined`` checks if a variable is defined in the current context. This is very +useful if you use the ``strict_variables`` option: + +.. code-block:: jinja + + {# defined works with variable names #} + {% if foo is defined %} + ... + {% endif %} + + {# and attributes on variables names #} + {% if foo.bar is defined %} + ... + {% endif %} + + {% if foo['bar'] is defined %} + ... + {% endif %} + +When using the ``defined`` test on an expression that uses variables in some +method calls, be sure that they are all defined first: + +.. code-block:: jinja + + {% if var is defined and foo.method(var) is defined %} + ... + {% endif %} diff --git a/vendor/twig/twig/doc/tests/divisibleby.rst b/vendor/twig/twig/doc/tests/divisibleby.rst new file mode 100644 index 000000000..6c693b2b4 --- /dev/null +++ b/vendor/twig/twig/doc/tests/divisibleby.rst @@ -0,0 +1,14 @@ +``divisible by`` +================ + +.. versionadded:: 1.14.2 + The ``divisible by`` test was added in Twig 1.14.2 as an alias for + ``divisibleby``. + +``divisible by`` checks if a variable is divisible by a number: + +.. code-block:: jinja + + {% if loop.index is divisible by(3) %} + ... + {% endif %} diff --git a/vendor/twig/twig/doc/tests/empty.rst b/vendor/twig/twig/doc/tests/empty.rst new file mode 100644 index 000000000..639cdcc39 --- /dev/null +++ b/vendor/twig/twig/doc/tests/empty.rst @@ -0,0 +1,22 @@ +``empty`` +========= + +.. versionadded:: 1.33 + + Support for the ``__toString()`` magic method has been added in Twig 1.33. + +``empty`` checks if a variable is an empty string, an empty array, an empty +hash, exactly ``false``, or exactly ``null``. + +For objects that implement the ``Countable`` interface, ``empty`` will check the +return value of the ``count()`` method. + +For objects that implement the ``__toString()`` magic method (and not ``Countable``), +it will check if an empty string is returned. + +.. code-block:: jinja + + {% if foo is empty %} + ... + {% endif %} + diff --git a/vendor/twig/twig/doc/tests/even.rst b/vendor/twig/twig/doc/tests/even.rst new file mode 100644 index 000000000..6ab5cc39a --- /dev/null +++ b/vendor/twig/twig/doc/tests/even.rst @@ -0,0 +1,10 @@ +``even`` +======== + +``even`` returns ``true`` if the given number is even: + +.. code-block:: jinja + + {{ var is even }} + +.. seealso:: :doc:`odd<../tests/odd>` diff --git a/vendor/twig/twig/doc/tests/index.rst b/vendor/twig/twig/doc/tests/index.rst new file mode 100644 index 000000000..c63208ee7 --- /dev/null +++ b/vendor/twig/twig/doc/tests/index.rst @@ -0,0 +1,15 @@ +Tests +===== + +.. toctree:: + :maxdepth: 1 + + constant + defined + divisibleby + empty + even + iterable + null + odd + sameas diff --git a/vendor/twig/twig/doc/tests/iterable.rst b/vendor/twig/twig/doc/tests/iterable.rst new file mode 100644 index 000000000..89a172f74 --- /dev/null +++ b/vendor/twig/twig/doc/tests/iterable.rst @@ -0,0 +1,19 @@ +``iterable`` +============ + +.. versionadded:: 1.7 + The iterable test was added in Twig 1.7. + +``iterable`` checks if a variable is an array or a traversable object: + +.. code-block:: jinja + + {# evaluates to true if the foo variable is iterable #} + {% if users is iterable %} + {% for user in users %} + Hello {{ user }}! + {% endfor %} + {% else %} + {# users is probably a string #} + Hello {{ users }}! + {% endif %} diff --git a/vendor/twig/twig/doc/tests/null.rst b/vendor/twig/twig/doc/tests/null.rst new file mode 100644 index 000000000..44eec62e5 --- /dev/null +++ b/vendor/twig/twig/doc/tests/null.rst @@ -0,0 +1,12 @@ +``null`` +======== + +``null`` returns ``true`` if the variable is ``null``: + +.. code-block:: jinja + + {{ var is null }} + +.. note:: + + ``none`` is an alias for ``null``. diff --git a/vendor/twig/twig/doc/tests/odd.rst b/vendor/twig/twig/doc/tests/odd.rst new file mode 100644 index 000000000..9eece7776 --- /dev/null +++ b/vendor/twig/twig/doc/tests/odd.rst @@ -0,0 +1,10 @@ +``odd`` +======= + +``odd`` returns ``true`` if the given number is odd: + +.. code-block:: jinja + + {{ var is odd }} + +.. seealso:: :doc:`even<../tests/even>` diff --git a/vendor/twig/twig/doc/tests/sameas.rst b/vendor/twig/twig/doc/tests/sameas.rst new file mode 100644 index 000000000..16f904d5c --- /dev/null +++ b/vendor/twig/twig/doc/tests/sameas.rst @@ -0,0 +1,14 @@ +``same as`` +=========== + +.. versionadded:: 1.14.2 + The ``same as`` test was added in Twig 1.14.2 as an alias for ``sameas``. + +``same as`` checks if a variable is the same as another variable. +This is the equivalent to ``===`` in PHP: + +.. code-block:: jinja + + {% if foo.attribute is same as(false) %} + the foo attribute really is the 'false' PHP value + {% endif %} diff --git a/vendor/twig/twig/ext/twig/.gitignore b/vendor/twig/twig/ext/twig/.gitignore new file mode 100644 index 000000000..56ea76cc2 --- /dev/null +++ b/vendor/twig/twig/ext/twig/.gitignore @@ -0,0 +1,30 @@ +*.sw* +.deps +Makefile +Makefile.fragments +Makefile.global +Makefile.objects +acinclude.m4 +aclocal.m4 +build/ +config.cache +config.guess +config.h +config.h.in +config.log +config.nice +config.status +config.sub +configure +configure.in +install-sh +libtool +ltmain.sh +missing +mkinstalldirs +run-tests.php +twig.loT +.libs/ +modules/ +twig.la +twig.lo diff --git a/vendor/twig/twig/ext/twig/config.m4 b/vendor/twig/twig/ext/twig/config.m4 new file mode 100644 index 000000000..83486be4c --- /dev/null +++ b/vendor/twig/twig/ext/twig/config.m4 @@ -0,0 +1,8 @@ +dnl config.m4 for extension twig + +PHP_ARG_ENABLE(twig, whether to enable twig support, +[ --enable-twig Enable twig support]) + +if test "$PHP_TWIG" != "no"; then + PHP_NEW_EXTENSION(twig, twig.c, $ext_shared) +fi diff --git a/vendor/twig/twig/ext/twig/config.w32 b/vendor/twig/twig/ext/twig/config.w32 new file mode 100644 index 000000000..cb287b99b --- /dev/null +++ b/vendor/twig/twig/ext/twig/config.w32 @@ -0,0 +1,8 @@ +// vim:ft=javascript + +ARG_ENABLE("twig", "Twig support", "no"); + +if (PHP_TWIG != "no") { + AC_DEFINE('HAVE_TWIG', 1); + EXTENSION('twig', 'twig.c'); +} diff --git a/vendor/twig/twig/ext/twig/php_twig.h b/vendor/twig/twig/ext/twig/php_twig.h new file mode 100644 index 000000000..e29106324 --- /dev/null +++ b/vendor/twig/twig/ext/twig/php_twig.h @@ -0,0 +1,35 @@ +/* + +----------------------------------------------------------------------+ + | Twig Extension | + +----------------------------------------------------------------------+ + | Copyright (c) 2011 Derick Rethans | + +----------------------------------------------------------------------+ + | Redistribution and use in source and binary forms, with or without | + | modification, are permitted provided that the conditions mentioned | + | in the accompanying LICENSE file are met (BSD-3-Clause). | + +----------------------------------------------------------------------+ + | Author: Derick Rethans | + +----------------------------------------------------------------------+ + */ + +#ifndef PHP_TWIG_H +#define PHP_TWIG_H + +#define PHP_TWIG_VERSION "1.34.3" + +#include "php.h" + +extern zend_module_entry twig_module_entry; +#define phpext_twig_ptr &twig_module_entry +#ifndef PHP_WIN32 +zend_module_entry *get_module(void); +#endif + +#ifdef ZTS +#include "TSRM.h" +#endif + +PHP_FUNCTION(twig_template_get_attributes); +PHP_RSHUTDOWN_FUNCTION(twig); + +#endif diff --git a/vendor/twig/twig/ext/twig/twig.c b/vendor/twig/twig/ext/twig/twig.c new file mode 100644 index 000000000..6173c0067 --- /dev/null +++ b/vendor/twig/twig/ext/twig/twig.c @@ -0,0 +1,1215 @@ +/* + +----------------------------------------------------------------------+ + | Twig Extension | + +----------------------------------------------------------------------+ + | Copyright (c) 2011 Derick Rethans | + +----------------------------------------------------------------------+ + | Redistribution and use in source and binary forms, with or without | + | modification, are permitted provided that the conditions mentioned | + | in the accompanying LICENSE file are met (BSD-3-Clause). | + +----------------------------------------------------------------------+ + | Author: Derick Rethans | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_twig.h" +#include "ext/standard/php_var.h" +#include "ext/standard/php_string.h" +#include "ext/standard/php_smart_str.h" +#include "ext/spl/spl_exceptions.h" + +#include "Zend/zend_object_handlers.h" +#include "Zend/zend_interfaces.h" +#include "Zend/zend_exceptions.h" + +#ifndef Z_ADDREF_P +#define Z_ADDREF_P(pz) (pz)->refcount++ +#endif + +#ifndef E_USER_DEPRECATED +#define E_USER_DEPRECATED (1<<14L) +#endif + +#define FREE_DTOR(z) \ + zval_dtor(z); \ + efree(z); + +#if PHP_VERSION_ID >= 50300 + #define APPLY_TSRMLS_DC TSRMLS_DC + #define APPLY_TSRMLS_CC TSRMLS_CC + #define APPLY_TSRMLS_FETCH() +#else + #define APPLY_TSRMLS_DC + #define APPLY_TSRMLS_CC + #define APPLY_TSRMLS_FETCH() TSRMLS_FETCH() +#endif + +ZEND_BEGIN_ARG_INFO_EX(twig_template_get_attribute_args, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 6) + ZEND_ARG_INFO(0, template) + ZEND_ARG_INFO(0, object) + ZEND_ARG_INFO(0, item) + ZEND_ARG_INFO(0, arguments) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, isDefinedTest) +ZEND_END_ARG_INFO() + +#ifndef PHP_FE_END +#define PHP_FE_END { NULL, NULL, NULL} +#endif + +static const zend_function_entry twig_functions[] = { + PHP_FE(twig_template_get_attributes, twig_template_get_attribute_args) + PHP_FE_END +}; + +PHP_RSHUTDOWN_FUNCTION(twig) +{ +#if ZEND_DEBUG + CG(unclean_shutdown) = 0; /* get rid of PHPUnit's exit() and report memleaks */ +#endif + return SUCCESS; +} + +zend_module_entry twig_module_entry = { + STANDARD_MODULE_HEADER, + "twig", + twig_functions, + NULL, + NULL, + NULL, + PHP_RSHUTDOWN(twig), + NULL, + PHP_TWIG_VERSION, + STANDARD_MODULE_PROPERTIES +}; + + +#ifdef COMPILE_DL_TWIG +ZEND_GET_MODULE(twig) +#endif + +static int TWIG_ARRAY_KEY_EXISTS(zval *array, zval *key) +{ + if (Z_TYPE_P(array) != IS_ARRAY) { + return 0; + } + + switch (Z_TYPE_P(key)) { + case IS_NULL: + return zend_hash_exists(Z_ARRVAL_P(array), "", 1); + + case IS_BOOL: + case IS_DOUBLE: + convert_to_long(key); + case IS_LONG: + return zend_hash_index_exists(Z_ARRVAL_P(array), Z_LVAL_P(key)); + + default: + convert_to_string(key); + return zend_symtable_exists(Z_ARRVAL_P(array), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1); + } +} + +static int TWIG_INSTANCE_OF(zval *object, zend_class_entry *interface TSRMLS_DC) +{ + if (Z_TYPE_P(object) != IS_OBJECT) { + return 0; + } + return instanceof_function(Z_OBJCE_P(object), interface TSRMLS_CC); +} + +static int TWIG_INSTANCE_OF_USERLAND(zval *object, char *interface TSRMLS_DC) +{ + zend_class_entry **pce; + if (Z_TYPE_P(object) != IS_OBJECT) { + return 0; + } + if (zend_lookup_class(interface, strlen(interface), &pce TSRMLS_CC) == FAILURE) { + return 0; + } + return instanceof_function(Z_OBJCE_P(object), *pce TSRMLS_CC); +} + +static zval *TWIG_GET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC) +{ + zend_class_entry *ce = Z_OBJCE_P(object); + zval *retval; + + if (Z_TYPE_P(object) == IS_OBJECT) { + SEPARATE_ARG_IF_REF(offset); + zend_call_method_with_1_params(&object, ce, NULL, "offsetget", &retval, offset); + + zval_ptr_dtor(&offset); + + if (!retval) { + if (!EG(exception)) { + zend_error(E_ERROR, "Undefined offset for object of type %s used as array.", ce->name); + } + return NULL; + } + + return retval; + } + return NULL; +} + +static int TWIG_ISSET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC) +{ + zend_class_entry *ce = Z_OBJCE_P(object); + zval *retval; + + if (Z_TYPE_P(object) == IS_OBJECT) { + SEPARATE_ARG_IF_REF(offset); + zend_call_method_with_1_params(&object, ce, NULL, "offsetexists", &retval, offset); + + zval_ptr_dtor(&offset); + + if (!retval) { + if (!EG(exception)) { + zend_error(E_ERROR, "Undefined offset for object of type %s used as array.", ce->name); + } + return 0; + } + + return (retval && Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval)); + } + return 0; +} + +static char *TWIG_STRTOLOWER(const char *str, int str_len) +{ + char *item_dup; + + item_dup = estrndup(str, str_len); + php_strtolower(item_dup, str_len); + return item_dup; +} + +static zval *TWIG_CALL_USER_FUNC_ARRAY(zval *object, char *function, zval *arguments TSRMLS_DC) +{ + zend_fcall_info fci; + zval ***args = NULL; + int arg_count = 0; + HashTable *table; + HashPosition pos; + int i = 0; + zval *retval_ptr; + zval *zfunction; + + if (arguments) { + table = HASH_OF(arguments); + args = safe_emalloc(sizeof(zval **), table->nNumOfElements, 0); + + zend_hash_internal_pointer_reset_ex(table, &pos); + + while (zend_hash_get_current_data_ex(table, (void **)&args[i], &pos) == SUCCESS) { + i++; + zend_hash_move_forward_ex(table, &pos); + } + arg_count = table->nNumOfElements; + } + + MAKE_STD_ZVAL(zfunction); + ZVAL_STRING(zfunction, function, 1); + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = zfunction; + fci.symbol_table = NULL; +#if PHP_VERSION_ID >= 50300 + fci.object_ptr = object; +#else + fci.object_pp = &object; +#endif + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = arg_count; + fci.params = args; + fci.no_separation = 0; + + if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) { + ALLOC_INIT_ZVAL(retval_ptr); + ZVAL_BOOL(retval_ptr, 0); + } + + if (args) { + efree(fci.params); + } + FREE_DTOR(zfunction); + return retval_ptr; +} + +static int TWIG_CALL_BOOLEAN(zval *object, char *functionName TSRMLS_DC) +{ + zval *ret; + int res; + + ret = TWIG_CALL_USER_FUNC_ARRAY(object, functionName, NULL TSRMLS_CC); + res = Z_LVAL_P(ret); + zval_ptr_dtor(&ret); + return res; +} + +static zval *TWIG_GET_STATIC_PROPERTY(zval *class, char *prop_name TSRMLS_DC) +{ + zval **tmp_zval; + zend_class_entry *ce; + + if (class == NULL || Z_TYPE_P(class) != IS_OBJECT) { + return NULL; + } + + ce = zend_get_class_entry(class TSRMLS_CC); +#if PHP_VERSION_ID >= 50400 + tmp_zval = zend_std_get_static_property(ce, prop_name, strlen(prop_name), 0, NULL TSRMLS_CC); +#else + tmp_zval = zend_std_get_static_property(ce, prop_name, strlen(prop_name), 0 TSRMLS_CC); +#endif + return *tmp_zval; +} + +static zval *TWIG_GET_ARRAY_ELEMENT_ZVAL(zval *class, zval *prop_name TSRMLS_DC) +{ + zval **tmp_zval; + + if (class == NULL || Z_TYPE_P(class) != IS_ARRAY) { + if (class != NULL && Z_TYPE_P(class) == IS_OBJECT && TWIG_INSTANCE_OF(class, zend_ce_arrayaccess TSRMLS_CC)) { + // array access object + return TWIG_GET_ARRAYOBJECT_ELEMENT(class, prop_name TSRMLS_CC); + } + return NULL; + } + + switch(Z_TYPE_P(prop_name)) { + case IS_NULL: + zend_hash_find(HASH_OF(class), "", 1, (void**) &tmp_zval); + return *tmp_zval; + + case IS_BOOL: + case IS_DOUBLE: + convert_to_long(prop_name); + case IS_LONG: + zend_hash_index_find(HASH_OF(class), Z_LVAL_P(prop_name), (void **) &tmp_zval); + return *tmp_zval; + + case IS_STRING: + zend_symtable_find(HASH_OF(class), Z_STRVAL_P(prop_name), Z_STRLEN_P(prop_name) + 1, (void**) &tmp_zval); + return *tmp_zval; + } + + return NULL; +} + +static zval *TWIG_GET_ARRAY_ELEMENT(zval *class, char *prop_name, int prop_name_length TSRMLS_DC) +{ + zval **tmp_zval; + + if (class == NULL/* || Z_TYPE_P(class) != IS_ARRAY*/) { + return NULL; + } + + if (class != NULL && Z_TYPE_P(class) == IS_OBJECT && TWIG_INSTANCE_OF(class, zend_ce_arrayaccess TSRMLS_CC)) { + // array access object + zval *tmp_name_zval; + zval *tmp_ret_zval; + + ALLOC_INIT_ZVAL(tmp_name_zval); + ZVAL_STRING(tmp_name_zval, prop_name, 1); + tmp_ret_zval = TWIG_GET_ARRAYOBJECT_ELEMENT(class, tmp_name_zval TSRMLS_CC); + FREE_DTOR(tmp_name_zval); + return tmp_ret_zval; + } + + if (zend_symtable_find(HASH_OF(class), prop_name, prop_name_length+1, (void**)&tmp_zval) == SUCCESS) { + return *tmp_zval; + } + return NULL; +} + +static zval *TWIG_PROPERTY(zval *object, zval *propname TSRMLS_DC) +{ + zval *tmp = NULL; + + if (Z_OBJ_HT_P(object)->read_property) { +#if PHP_VERSION_ID >= 50400 + tmp = Z_OBJ_HT_P(object)->read_property(object, propname, BP_VAR_IS, NULL TSRMLS_CC); +#else + tmp = Z_OBJ_HT_P(object)->read_property(object, propname, BP_VAR_IS TSRMLS_CC); +#endif + if (tmp == EG(uninitialized_zval_ptr)) { + ZVAL_NULL(tmp); + } + } + return tmp; +} + +static int TWIG_HAS_PROPERTY(zval *object, zval *propname TSRMLS_DC) +{ + if (Z_OBJ_HT_P(object)->has_property) { +#if PHP_VERSION_ID >= 50400 + return Z_OBJ_HT_P(object)->has_property(object, propname, 0, NULL TSRMLS_CC); +#else + return Z_OBJ_HT_P(object)->has_property(object, propname, 0 TSRMLS_CC); +#endif + } + return 0; +} + +static int TWIG_HAS_DYNAMIC_PROPERTY(zval *object, char *prop, int prop_len TSRMLS_DC) +{ + if (Z_OBJ_HT_P(object)->get_properties) { + return zend_hash_quick_exists( + Z_OBJ_HT_P(object)->get_properties(object TSRMLS_CC), // the properties hash + prop, // property name + prop_len + 1, // property length + zend_get_hash_value(prop, prop_len + 1) // hash value + ); + } + return 0; +} + +static zval *TWIG_PROPERTY_CHAR(zval *object, char *propname TSRMLS_DC) +{ + zval *tmp_name_zval, *tmp; + + ALLOC_INIT_ZVAL(tmp_name_zval); + ZVAL_STRING(tmp_name_zval, propname, 1); + tmp = TWIG_PROPERTY(object, tmp_name_zval TSRMLS_CC); + FREE_DTOR(tmp_name_zval); + return tmp; +} + +static zval *TWIG_CALL_S(zval *object, char *method, char *arg0 TSRMLS_DC) +{ + zend_fcall_info fci; + zval **args[1]; + zval *argument; + zval *zfunction; + zval *retval_ptr; + + MAKE_STD_ZVAL(argument); + ZVAL_STRING(argument, arg0, 1); + args[0] = &argument; + + MAKE_STD_ZVAL(zfunction); + ZVAL_STRING(zfunction, method, 1); + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = zfunction; + fci.symbol_table = NULL; +#if PHP_VERSION_ID >= 50300 + fci.object_ptr = object; +#else + fci.object_pp = &object; +#endif + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 1; + fci.params = args; + fci.no_separation = 0; + + if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) { + FREE_DTOR(zfunction); + zval_ptr_dtor(&argument); + return 0; + } + FREE_DTOR(zfunction); + zval_ptr_dtor(&argument); + return retval_ptr; +} + +static int TWIG_CALL_SB(zval *object, char *method, char *arg0 TSRMLS_DC) +{ + zval *retval_ptr; + int success; + + retval_ptr = TWIG_CALL_S(object, method, arg0 TSRMLS_CC); + success = (retval_ptr && (Z_TYPE_P(retval_ptr) == IS_BOOL) && Z_LVAL_P(retval_ptr)); + + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + + return success; +} + +static int TWIG_CALL_ZZ(zval *object, char *method, zval *arg1, zval *arg2 TSRMLS_DC) +{ + zend_fcall_info fci; + zval **args[2]; + zval *zfunction; + zval *retval_ptr; + int success; + + args[0] = &arg1; + args[1] = &arg2; + + MAKE_STD_ZVAL(zfunction); + ZVAL_STRING(zfunction, method, 1); + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = zfunction; + fci.symbol_table = NULL; +#if PHP_VERSION_ID >= 50300 + fci.object_ptr = object; +#else + fci.object_pp = &object; +#endif + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 2; + fci.params = args; + fci.no_separation = 0; + + if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) { + FREE_DTOR(zfunction); + return 0; + } + + FREE_DTOR(zfunction); + + success = (retval_ptr && (Z_TYPE_P(retval_ptr) == IS_BOOL) && Z_LVAL_P(retval_ptr)); + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + + return success; +} + +#ifndef Z_SET_REFCOUNT_P +# define Z_SET_REFCOUNT_P(pz, rc) pz->refcount = rc +# define Z_UNSET_ISREF_P(pz) pz->is_ref = 0 +#endif + +static void TWIG_NEW(zval *object, char *class, zval *arg0, zval *arg1 TSRMLS_DC) +{ + zend_class_entry **pce; + + if (zend_lookup_class(class, strlen(class), &pce TSRMLS_CC) == FAILURE) { + return; + } + + Z_TYPE_P(object) = IS_OBJECT; + object_init_ex(object, *pce); + Z_SET_REFCOUNT_P(object, 1); + Z_UNSET_ISREF_P(object); + + TWIG_CALL_ZZ(object, "__construct", arg0, arg1 TSRMLS_CC); +} + +static int twig_add_array_key_to_string(void *pDest APPLY_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +{ + smart_str *buf; + char *joiner; + APPLY_TSRMLS_FETCH(); + + buf = va_arg(args, smart_str*); + joiner = va_arg(args, char*); + + if (buf->len != 0) { + smart_str_appends(buf, joiner); + } + + if (hash_key->nKeyLength == 0) { + smart_str_append_long(buf, (long) hash_key->h); + } else { + char *key, *tmp_str; + int key_len, tmp_len; + key = php_addcslashes(hash_key->arKey, hash_key->nKeyLength - 1, &key_len, 0, "'\\", 2 TSRMLS_CC); + tmp_str = php_str_to_str_ex(key, key_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len, 0, NULL); + + smart_str_appendl(buf, tmp_str, tmp_len); + efree(key); + efree(tmp_str); + } + + return 0; +} + +static char *TWIG_IMPLODE_ARRAY_KEYS(char *joiner, zval *array TSRMLS_DC) +{ + smart_str collector = { 0, 0, 0 }; + + smart_str_appendl(&collector, "", 0); + zend_hash_apply_with_arguments(HASH_OF(array) APPLY_TSRMLS_CC, twig_add_array_key_to_string, 2, &collector, joiner); + smart_str_0(&collector); + + return collector.c; +} + +static void TWIG_RUNTIME_ERROR(zval *template TSRMLS_DC, char *message, ...) +{ + char *buffer; + va_list args; + zend_class_entry **pce; + zval *ex; + zval *constructor; + zval *zmessage; + zval *lineno; + zval *filename_func; + zval *filename; + zval *constructor_args[3]; + zval *constructor_retval; + + if (zend_lookup_class("Twig_Error_Runtime", strlen("Twig_Error_Runtime"), &pce TSRMLS_CC) == FAILURE) { + return; + } + + va_start(args, message); + vspprintf(&buffer, 0, message, args); + va_end(args); + + MAKE_STD_ZVAL(ex); + object_init_ex(ex, *pce); + + // Call Twig_Error constructor + MAKE_STD_ZVAL(constructor); + MAKE_STD_ZVAL(zmessage); + MAKE_STD_ZVAL(lineno); + MAKE_STD_ZVAL(filename); + MAKE_STD_ZVAL(filename_func); + MAKE_STD_ZVAL(constructor_retval); + + ZVAL_STRINGL(constructor, "__construct", sizeof("__construct")-1, 1); + ZVAL_STRING(zmessage, buffer, 1); + ZVAL_LONG(lineno, -1); + + // Get template filename + ZVAL_STRINGL(filename_func, "getTemplateName", sizeof("getTemplateName")-1, 1); + call_user_function(EG(function_table), &template, filename_func, filename, 0, 0 TSRMLS_CC); + + constructor_args[0] = zmessage; + constructor_args[1] = lineno; + constructor_args[2] = filename; + call_user_function(EG(function_table), &ex, constructor, constructor_retval, 3, constructor_args TSRMLS_CC); + + zval_ptr_dtor(&constructor_retval); + zval_ptr_dtor(&zmessage); + zval_ptr_dtor(&lineno); + zval_ptr_dtor(&filename); + FREE_DTOR(constructor); + FREE_DTOR(filename_func); + efree(buffer); + + zend_throw_exception_object(ex TSRMLS_CC); +} + +static char *TWIG_GET_CLASS_NAME(zval *object TSRMLS_DC) +{ + char *class_name; + zend_uint class_name_len; + + if (Z_TYPE_P(object) != IS_OBJECT) { + return ""; + } +#if PHP_API_VERSION >= 20100412 + zend_get_object_classname(object, (const char **) &class_name, &class_name_len TSRMLS_CC); +#else + zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC); +#endif + return class_name; +} + +static int twig_add_method_to_class(void *pDest APPLY_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +{ + zend_class_entry *ce; + zval *retval; + char *item; + size_t item_len; + zend_function *mptr = (zend_function *) pDest; + APPLY_TSRMLS_FETCH(); + + if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)) { + return 0; + } + + ce = *va_arg(args, zend_class_entry**); + retval = va_arg(args, zval*); + + item_len = strlen(mptr->common.function_name); + item = estrndup(mptr->common.function_name, item_len); + php_strtolower(item, item_len); + + if (strcmp("getenvironment", item) == 0) { + zend_class_entry **twig_template_ce; + if (zend_lookup_class("Twig_Template", strlen("Twig_Template"), &twig_template_ce TSRMLS_CC) == FAILURE) { + return 0; + } + if (instanceof_function(ce, *twig_template_ce TSRMLS_CC)) { + return 0; + } + } + + add_assoc_stringl_ex(retval, item, item_len+1, item, item_len, 0); + + return 0; +} + +static int twig_add_property_to_class(void *pDest APPLY_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +{ + zend_class_entry *ce; + zval *retval; + char *class_name, *prop_name; + zend_property_info *pptr = (zend_property_info *) pDest; + APPLY_TSRMLS_FETCH(); + + if (!(pptr->flags & ZEND_ACC_PUBLIC) || (pptr->flags & ZEND_ACC_STATIC)) { + return 0; + } + + ce = *va_arg(args, zend_class_entry**); + retval = va_arg(args, zval*); + +#if PHP_API_VERSION >= 20100412 + zend_unmangle_property_name(pptr->name, pptr->name_length, (const char **) &class_name, (const char **) &prop_name); +#else + zend_unmangle_property_name(pptr->name, pptr->name_length, &class_name, &prop_name); +#endif + + add_assoc_string(retval, prop_name, prop_name, 1); + + return 0; +} + +static void twig_add_class_to_cache(zval *cache, zval *object, char *class_name TSRMLS_DC) +{ + zval *class_info, *class_methods, *class_properties; + zend_class_entry *class_ce; + + class_ce = zend_get_class_entry(object TSRMLS_CC); + + ALLOC_INIT_ZVAL(class_info); + ALLOC_INIT_ZVAL(class_methods); + ALLOC_INIT_ZVAL(class_properties); + array_init(class_info); + array_init(class_methods); + array_init(class_properties); + // add all methods to self::cache[$class]['methods'] + zend_hash_apply_with_arguments(&class_ce->function_table APPLY_TSRMLS_CC, twig_add_method_to_class, 2, &class_ce, class_methods); + zend_hash_apply_with_arguments(&class_ce->properties_info APPLY_TSRMLS_CC, twig_add_property_to_class, 2, &class_ce, class_properties); + + add_assoc_zval(class_info, "methods", class_methods); + add_assoc_zval(class_info, "properties", class_properties); + add_assoc_zval(cache, class_name, class_info); +} + +/* {{{ proto mixed twig_template_get_attributes(TwigTemplate template, mixed object, mixed item, array arguments, string type, boolean isDefinedTest, boolean ignoreStrictCheck) + A C implementation of TwigTemplate::getAttribute() */ +PHP_FUNCTION(twig_template_get_attributes) +{ + zval *template; + zval *object; + char *item; + int item_len; + zval *zitem, ztmpitem; + zval *arguments = NULL; + zval *ret = NULL; + char *type = NULL; + int type_len = 0; + zend_bool isDefinedTest = 0; + zend_bool ignoreStrictCheck = 0; + int free_ret = 0; + zval *tmp_self_cache; + char *class_name = NULL; + zval *tmp_class; + char *type_name; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ozz|asbb", &template, &object, &zitem, &arguments, &type, &type_len, &isDefinedTest, &ignoreStrictCheck) == FAILURE) { + return; + } + + // convert the item to a string + ztmpitem = *zitem; + zval_copy_ctor(&ztmpitem); + convert_to_string(&ztmpitem); + item_len = Z_STRLEN(ztmpitem); + item = estrndup(Z_STRVAL(ztmpitem), item_len); + zval_dtor(&ztmpitem); + + if (!type) { + type = "any"; + } + +/* + // array + if (Twig_Template::METHOD_CALL !== $type) { + $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item; + + if ((is_array($object) && array_key_exists($arrayItem, $object)) + || ($object instanceof ArrayAccess && isset($object[$arrayItem])) + ) { + if ($isDefinedTest) { + return true; + } + + return $object[$arrayItem]; + } +*/ + + + if (strcmp("method", type) != 0) { + if ((TWIG_ARRAY_KEY_EXISTS(object, zitem)) + || (TWIG_INSTANCE_OF(object, zend_ce_arrayaccess TSRMLS_CC) && TWIG_ISSET_ARRAYOBJECT_ELEMENT(object, zitem TSRMLS_CC)) + ) { + + if (isDefinedTest) { + efree(item); + RETURN_TRUE; + } + + ret = TWIG_GET_ARRAY_ELEMENT_ZVAL(object, zitem TSRMLS_CC); + + if (!ret) { + ret = &EG(uninitialized_zval); + } + RETVAL_ZVAL(ret, 1, 0); + if (free_ret) { + zval_ptr_dtor(&ret); + } + efree(item); + return; + } +/* + if (Twig_Template::ARRAY_CALL === $type) { + if ($isDefinedTest) { + return false; + } + if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { + return null; + } +*/ + if (strcmp("array", type) == 0 || Z_TYPE_P(object) != IS_OBJECT) { + if (isDefinedTest) { + efree(item); + RETURN_FALSE; + } + if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) { + efree(item); + return; + } +/* + if ($object instanceof ArrayAccess) { + $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist', $arrayItem, get_class($object)); + } elseif (is_object($object)) { + $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object)); + } elseif (is_array($object)) { + if (empty($object)) { + $message = sprintf('Key "%s" does not exist as the array is empty', $arrayItem); + } else { + $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object))); + } + } elseif (Twig_Template::ARRAY_CALL === $type) { + if (null === $object) { + $message = sprintf('Impossible to access a key ("%s") on a null variable', $item); + } else { + $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object); + } + } elseif (null === $object) { + $message = sprintf('Impossible to access an attribute ("%s") on a null variable', $item); + } else { + $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object); + } + throw new Twig_Error_Runtime($message, -1, $this->getTemplateName()); + } + } +*/ + if (TWIG_INSTANCE_OF(object, zend_ce_arrayaccess TSRMLS_CC)) { + TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" in object with ArrayAccess of class \"%s\" does not exist.", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC)); + } else if (Z_TYPE_P(object) == IS_OBJECT) { + TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to access a key \"%s\" on an object of class \"%s\" that does not implement ArrayAccess interface.", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC)); + } else if (Z_TYPE_P(object) == IS_ARRAY) { + if (0 == zend_hash_num_elements(Z_ARRVAL_P(object))) { + TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" does not exist as the array is empty.", item); + } else { + char *array_keys = TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC); + TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist.", item, array_keys); + efree(array_keys); + } + } else { + char *type_name = zend_zval_type_name(object); + Z_ADDREF_P(object); + if (Z_TYPE_P(object) == IS_NULL) { + convert_to_string(object); + TWIG_RUNTIME_ERROR(template TSRMLS_CC, + (strcmp("array", type) == 0) + ? "Impossible to access a key (\"%s\") on a %s variable." + : "Impossible to access an attribute (\"%s\") on a %s variable.", + item, type_name); + } else { + convert_to_string(object); + TWIG_RUNTIME_ERROR(template TSRMLS_CC, + (strcmp("array", type) == 0) + ? "Impossible to access a key (\"%s\") on a %s variable (\"%s\")." + : "Impossible to access an attribute (\"%s\") on a %s variable (\"%s\").", + item, type_name, Z_STRVAL_P(object)); + } + zval_ptr_dtor(&object); + } + efree(item); + return; + } + } + +/* + if (!is_object($object)) { + if ($isDefinedTest) { + return false; + } +*/ + + if (Z_TYPE_P(object) != IS_OBJECT) { + if (isDefinedTest) { + efree(item); + RETURN_FALSE; + } +/* + if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { + return null; + } + + if (null === $object) { + $message = sprintf('Impossible to invoke a method ("%s") on a null variable', $item); + } else { + $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object); + } + + throw new Twig_Error_Runtime($message, -1, $this->getTemplateName()); + } +*/ + if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) { + efree(item); + return; + } + + type_name = zend_zval_type_name(object); + Z_ADDREF_P(object); + if (Z_TYPE_P(object) == IS_NULL) { + convert_to_string_ex(&object); + + TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable.", item, type_name); + } else { + convert_to_string_ex(&object); + + TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable (\"%s\").", item, type_name, Z_STRVAL_P(object)); + } + + zval_ptr_dtor(&object); + efree(item); + return; + } +/* + $class = get_class($object); +*/ + + class_name = TWIG_GET_CLASS_NAME(object TSRMLS_CC); + tmp_self_cache = TWIG_GET_STATIC_PROPERTY(template, "cache" TSRMLS_CC); + tmp_class = TWIG_GET_ARRAY_ELEMENT(tmp_self_cache, class_name, strlen(class_name) TSRMLS_CC); + + if (!tmp_class) { + twig_add_class_to_cache(tmp_self_cache, object, class_name TSRMLS_CC); + tmp_class = TWIG_GET_ARRAY_ELEMENT(tmp_self_cache, class_name, strlen(class_name) TSRMLS_CC); + } + efree(class_name); + +/* + // object property + if (Twig_Template::METHOD_CALL !== $type && !$object instanceof Twig_Template) { + if (isset($object->$item) || array_key_exists((string) $item, $object)) { + if ($isDefinedTest) { + return true; + } + + if ($this->env->hasExtension('Twig_Extension_Sandbox')) { + $this->env->getExtension('Twig_Extension_Sandbox')->checkPropertyAllowed($object, $item); + } + + return $object->$item; + } + } +*/ + if (strcmp("method", type) != 0 && !TWIG_INSTANCE_OF_USERLAND(object, "Twig_Template" TSRMLS_CC)) { + zval *tmp_properties, *tmp_item; + + tmp_properties = TWIG_GET_ARRAY_ELEMENT(tmp_class, "properties", strlen("properties") TSRMLS_CC); + tmp_item = TWIG_GET_ARRAY_ELEMENT(tmp_properties, item, item_len TSRMLS_CC); + + if (tmp_item || TWIG_HAS_PROPERTY(object, zitem TSRMLS_CC) || TWIG_HAS_DYNAMIC_PROPERTY(object, item, item_len TSRMLS_CC)) { + if (isDefinedTest) { + efree(item); + RETURN_TRUE; + } + if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "Twig_Extension_Sandbox" TSRMLS_CC)) { + TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "Twig_Extension_Sandbox" TSRMLS_CC), "checkPropertyAllowed", object, zitem TSRMLS_CC); + } + if (EG(exception)) { + efree(item); + return; + } + + ret = TWIG_PROPERTY(object, zitem TSRMLS_CC); + efree(item); + RETURN_ZVAL(ret, 1, 0); + } + } +/* + // object method + if (!isset(self::$cache[$class]['methods'])) { + if ($object instanceof self) { + $ref = new ReflectionClass($class); + $methods = array(); + + foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) { + $methodName = strtolower($refMethod->name); + + // Accessing the environment from templates is forbidden to prevent untrusted changes to the environment + if ('getenvironment' !== $methodName) { + $methods[$methodName] = true; + } + } + + self::$cache[$class]['methods'] = $methods; + } else { + self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object))); + } + } + + $call = false; + $lcItem = strtolower($item); + if (isset(self::$cache[$class]['methods'][$lcItem])) { + $method = (string) $item; + } elseif (isset(self::$cache[$class]['methods']['get'.$lcItem])) { + $method = 'get'.$item; + } elseif (isset(self::$cache[$class]['methods']['is'.$lcItem])) { + $method = 'is'.$item; + } elseif (isset(self::$cache[$class]['methods']['__call'])) { + $method = (string) $item; + $call = true; +*/ + { + int call = 0; + char *lcItem = TWIG_STRTOLOWER(item, item_len); + int lcItem_length; + char *method = NULL; + char *methodForDeprecation = NULL; + char *tmp_method_name_get; + char *tmp_method_name_is; + zval *zmethod; + zval *tmp_methods; + + lcItem_length = strlen(lcItem); + tmp_method_name_get = emalloc(4 + lcItem_length); + tmp_method_name_is = emalloc(3 + lcItem_length); + + sprintf(tmp_method_name_get, "get%s", lcItem); + sprintf(tmp_method_name_is, "is%s", lcItem); + + tmp_methods = TWIG_GET_ARRAY_ELEMENT(tmp_class, "methods", strlen("methods") TSRMLS_CC); + methodForDeprecation = emalloc(item_len + 1); + sprintf(methodForDeprecation, "%s", item); + + if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, lcItem, lcItem_length TSRMLS_CC)) { + method = item; + } else if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, tmp_method_name_get, lcItem_length + 3 TSRMLS_CC)) { + method = tmp_method_name_get; + } else if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, tmp_method_name_is, lcItem_length + 2 TSRMLS_CC)) { + method = tmp_method_name_is; + } else if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, "__call", 6 TSRMLS_CC)) { + method = item; + call = 1; +/* + } else { + if ($isDefinedTest) { + return false; + } + + if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { + return null; + } + + throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist.', $item, get_class($object)), -1, $this->getTemplateName()); + } + + if ($isDefinedTest) { + return true; + } +*/ + } else { + efree(tmp_method_name_get); + efree(tmp_method_name_is); + efree(lcItem); + + if (isDefinedTest) { + efree(item); + RETURN_FALSE; + } + if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) { + efree(item); + return; + } + TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Neither the property \"%s\" nor one of the methods \"%s()\", \"get%s()\"/\"is%s()\" or \"__call()\" exist and have public access in class \"%s\".", item, item, item, item, TWIG_GET_CLASS_NAME(object TSRMLS_CC)); + efree(item); + return; + } + + if (isDefinedTest) { + efree(tmp_method_name_get); + efree(tmp_method_name_is); + efree(lcItem);efree(item); + RETURN_TRUE; + } +/* + if ($this->env->hasExtension('Twig_Extension_Sandbox')) { + $this->env->getExtension('Twig_Extension_Sandbox')->checkMethodAllowed($object, $method); + } +*/ + MAKE_STD_ZVAL(zmethod); + ZVAL_STRING(zmethod, method, 1); + if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "Twig_Extension_Sandbox" TSRMLS_CC)) { + TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "Twig_Extension_Sandbox" TSRMLS_CC), "checkMethodAllowed", object, zmethod TSRMLS_CC); + } + zval_ptr_dtor(&zmethod); + if (EG(exception)) { + efree(tmp_method_name_get); + efree(tmp_method_name_is); + efree(lcItem);efree(item); + return; + } +/* + // Some objects throw exceptions when they have __call, and the method we try + // to call is not supported. If ignoreStrictCheck is true, we should return null. + try { + $ret = call_user_func_array(array($object, $method), $arguments); + } catch (BadMethodCallException $e) { + if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) { + return null; + } + throw $e; + } +*/ + ret = TWIG_CALL_USER_FUNC_ARRAY(object, method, arguments TSRMLS_CC); + if (EG(exception) && TWIG_INSTANCE_OF(EG(exception), spl_ce_BadMethodCallException TSRMLS_CC)) { + if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) { + efree(tmp_method_name_get); + efree(tmp_method_name_is); + efree(lcItem);efree(item); + zend_clear_exception(TSRMLS_C); + return; + } + } + free_ret = 1; + efree(tmp_method_name_get); + efree(tmp_method_name_is); + efree(lcItem); +/* + // @deprecated in 1.28 + if ($object instanceof Twig_TemplateInterface) { + $self = $object->getTemplateName() === $this->getTemplateName(); + $message = sprintf('Calling "%s" on template "%s" from template "%s" is deprecated since version 1.28 and won\'t be supported anymore in 2.0.', $item, $object->getTemplateName(), $this->getTemplateName()); + if ('renderBlock' === $method || 'displayBlock' === $method) { + $message .= sprintf(' Use block("%s"%s) instead).', $arguments[0], $self ? '' : ', template'); + } elseif ('hasBlock' === $method) { + $message .= sprintf(' Use "block("%s"%s) is defined" instead).', $arguments[0], $self ? '' : ', template'); + } elseif ('render' === $method || 'display' === $method) { + $message .= sprintf(' Use include("%s") instead).', $object->getTemplateName()); + } + @trigger_error($message, E_USER_DEPRECATED); + + return $ret === '' ? '' : new Twig_Markup($ret, $this->env->getCharset()); + } + + return $ret; +*/ + efree(item); + // ret can be null, if e.g. the called method throws an exception + if (ret) { + if (TWIG_INSTANCE_OF_USERLAND(object, "Twig_TemplateInterface" TSRMLS_CC)) { + int self; + int old_error_reporting; + zval *object_filename; + zval *this_filename; + zval *filename_func; + char *deprecation_message_complement = NULL; + char *deprecation_message = NULL; + + MAKE_STD_ZVAL(object_filename); + MAKE_STD_ZVAL(this_filename); + MAKE_STD_ZVAL(filename_func); + + // Get templates names + ZVAL_STRINGL(filename_func, "getTemplateName", sizeof("getTemplateName")-1, 1); + call_user_function(EG(function_table), &object, filename_func, object_filename, 0, 0 TSRMLS_CC); + ZVAL_STRINGL(filename_func, "getTemplateName", sizeof("getTemplateName")-1, 1); + call_user_function(EG(function_table), &template, filename_func, this_filename, 0, 0 TSRMLS_CC); + + self = (strcmp(Z_STRVAL_P(object_filename), Z_STRVAL_P(this_filename)) == 0); + + if (strcmp(methodForDeprecation, "renderBlock") == 0 || strcmp(methodForDeprecation, "displayBlock") == 0) { + zval **arg0; + zend_hash_index_find(HASH_OF(arguments), 0, (void **) &arg0); + asprintf( + &deprecation_message_complement, + " Use block(\"%s\"%s) instead).", + Z_STRVAL_PP(arg0), + self ? "" : ", template" + ); + } else if (strcmp(methodForDeprecation, "hasBlock") == 0) { + zval **arg0; + zend_hash_index_find(HASH_OF(arguments), 0, (void **) &arg0); + asprintf( + &deprecation_message_complement, + " Use \"block(\"%s\"%s) is defined\" instead).", + Z_STRVAL_PP(arg0), + self ? "" : ", template" + ); + } else if (strcmp(methodForDeprecation, "render") == 0 || strcmp(methodForDeprecation, "display") == 0) { + asprintf( + &deprecation_message_complement, + " Use include(\"%s\") instead).", + Z_STRVAL_P(object_filename) + ); + } else { + deprecation_message_complement = (char*)calloc(0, sizeof(char)); + } + + asprintf( + &deprecation_message, + "Calling \"%s\" on template \"%s\" from template \"%s\" is deprecated since version 1.28 and won't be supported anymore in 2.0.%s", + methodForDeprecation, + Z_STRVAL_P(object_filename), + Z_STRVAL_P(this_filename), + deprecation_message_complement + ); + + old_error_reporting = EG(error_reporting); + EG(error_reporting) = 0; + zend_error(E_USER_DEPRECATED, "%s", deprecation_message); + EG(error_reporting) = old_error_reporting; + + FREE_DTOR(filename_func) + FREE_DTOR(object_filename) + FREE_DTOR(this_filename) + free(deprecation_message); + free(deprecation_message_complement); + + if (Z_STRLEN_P(ret) != 0) { + zval *charset = TWIG_CALL_USER_FUNC_ARRAY(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getCharset", NULL TSRMLS_CC); + TWIG_NEW(return_value, "Twig_Markup", ret, charset TSRMLS_CC); + zval_ptr_dtor(&charset); + if (ret) { + zval_ptr_dtor(&ret); + } + efree(methodForDeprecation); + return; + } + } + + RETVAL_ZVAL(ret, 1, 0); + if (free_ret) { + zval_ptr_dtor(&ret); + } + } + + efree(methodForDeprecation); + } +} diff --git a/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php b/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php index 1c917d2fb..d8ef02fb2 100644 --- a/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php +++ b/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php @@ -48,3 +48,7 @@ abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface */ abstract protected function doLeaveNode(Twig_Node $node, Twig_Environment $env); } + +class_alias('Twig_BaseNodeVisitor', 'Twig\NodeVisitor\AbstractNodeVisitor', false); +class_exists('Twig_Environment'); +class_exists('Twig_Node'); diff --git a/vendor/twig/twig/lib/Twig/Cache/Filesystem.php b/vendor/twig/twig/lib/Twig/Cache/Filesystem.php index cb3fec468..65976282b 100644 --- a/vendor/twig/twig/lib/Twig/Cache/Filesystem.php +++ b/vendor/twig/twig/lib/Twig/Cache/Filesystem.php @@ -89,3 +89,5 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface return (int) @filemtime($key); } } + +class_alias('Twig_Cache_Filesystem', 'Twig\Cache\FilesystemCache', false); diff --git a/vendor/twig/twig/lib/Twig/Cache/Null.php b/vendor/twig/twig/lib/Twig/Cache/Null.php index 7a194950e..69d1d2f98 100644 --- a/vendor/twig/twig/lib/Twig/Cache/Null.php +++ b/vendor/twig/twig/lib/Twig/Cache/Null.php @@ -36,3 +36,5 @@ class Twig_Cache_Null implements Twig_CacheInterface return 0; } } + +class_alias('Twig_Cache_Null', 'Twig\Cache\NullCache', false); diff --git a/vendor/twig/twig/lib/Twig/CacheInterface.php b/vendor/twig/twig/lib/Twig/CacheInterface.php index 2a3f04dd0..776808bfe 100644 --- a/vendor/twig/twig/lib/Twig/CacheInterface.php +++ b/vendor/twig/twig/lib/Twig/CacheInterface.php @@ -54,3 +54,5 @@ interface Twig_CacheInterface */ public function getTimestamp($key); } + +class_alias('Twig_CacheInterface', 'Twig\Cache\CacheInterface', false); diff --git a/vendor/twig/twig/lib/Twig/Compiler.php b/vendor/twig/twig/lib/Twig/Compiler.php index 170fcb6dd..e90bc987d 100644 --- a/vendor/twig/twig/lib/Twig/Compiler.php +++ b/vendor/twig/twig/lib/Twig/Compiler.php @@ -279,3 +279,6 @@ class Twig_Compiler implements Twig_CompilerInterface return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false)); } } + +class_alias('Twig_Compiler', 'Twig\Compiler', false); +class_exists('Twig_Node'); diff --git a/vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php b/vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php index 3284569d8..814ab58bc 100644 --- a/vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php +++ b/vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php @@ -35,3 +35,5 @@ class Twig_ContainerRuntimeLoader implements Twig_RuntimeLoaderInterface } } } + +class_alias('Twig_ContainerRuntimeLoader', 'Twig\RuntimeLoader\ContainerRuntimeLoader', false); diff --git a/vendor/twig/twig/lib/Twig/Environment.php b/vendor/twig/twig/lib/Twig/Environment.php index 11c1f3846..c35b51b8e 100644 --- a/vendor/twig/twig/lib/Twig/Environment.php +++ b/vendor/twig/twig/lib/Twig/Environment.php @@ -16,11 +16,11 @@ */ class Twig_Environment { - const VERSION = '1.33.0'; - const VERSION_ID = 13300; + const VERSION = '1.34.3'; + const VERSION_ID = 13403; const MAJOR_VERSION = 1; - const MINOR_VERSION = 33; - const RELEASE_VERSION = 0; + const MINOR_VERSION = 34; + const RELEASE_VERSION = 3; const EXTRA_VERSION = ''; protected $charset; @@ -489,7 +489,7 @@ class Twig_Environment */ public function createTemplate($template) { - $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false)); + $name = sprintf('__string_template__%s', hash('sha256', $template, false)); $loader = new Twig_Loader_Chain(array( new Twig_Loader_Array(array($name => $template)), @@ -758,7 +758,7 @@ class Twig_Environment public function setLoader(Twig_LoaderInterface $loader) { - if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_Twig_LoaderInterface')) { + if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_')) { @trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED); } @@ -831,6 +831,12 @@ class Twig_Environment public function hasExtension($class) { $class = ltrim($class, '\\'); + if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) { + // For BC/FC with namespaced aliases + $class = new ReflectionClass($class); + $class = $class->name; + } + if (isset($this->extensions[$class])) { if ($class !== get_class($this->extensions[$class])) { @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED); @@ -860,6 +866,11 @@ class Twig_Environment public function getExtension($class) { $class = ltrim($class, '\\'); + if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) { + // For BC/FC with namespaced aliases + $class = new ReflectionClass($class); + $class = $class->name; + } if (isset($this->extensions[$class])) { if ($class !== get_class($this->extensions[$class])) { @@ -938,6 +949,12 @@ class Twig_Environment } $class = ltrim($name, '\\'); + if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) { + // For BC/FC with namespaced aliases + $class = new ReflectionClass($class); + $class = $class->name; + } + if (isset($this->extensions[$class])) { if ($class !== get_class($this->extensions[$class])) { @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED); @@ -1559,3 +1576,5 @@ class Twig_Environment $this->optionsHash = implode(':', $hashParts); } } + +class_alias('Twig_Environment', 'Twig\Environment', false); diff --git a/vendor/twig/twig/lib/Twig/Error.php b/vendor/twig/twig/lib/Twig/Error.php index 358a03b97..787e0d095 100644 --- a/vendor/twig/twig/lib/Twig/Error.php +++ b/vendor/twig/twig/lib/Twig/Error.php @@ -332,11 +332,6 @@ class Twig_Error extends Exception $r = new ReflectionObject($template); $file = $r->getFileName(); - // hhvm has a bug where eval'ed files comes out as the current directory - if (is_dir($file)) { - $file = ''; - } - $exceptions = array($e = $this); while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) { $exceptions[] = $e; @@ -363,3 +358,6 @@ class Twig_Error extends Exception } } } + +class_alias('Twig_Error', 'Twig\Error\Error', false); +class_exists('Twig_Source'); diff --git a/vendor/twig/twig/lib/Twig/Error/Loader.php b/vendor/twig/twig/lib/Twig/Error/Loader.php index 68297201a..df566dd78 100644 --- a/vendor/twig/twig/lib/Twig/Error/Loader.php +++ b/vendor/twig/twig/lib/Twig/Error/Loader.php @@ -36,3 +36,5 @@ class Twig_Error_Loader extends Twig_Error $this->setTemplateLine(false); } } + +class_alias('Twig_Error_Loader', 'Twig\Error\LoaderError', false); diff --git a/vendor/twig/twig/lib/Twig/Error/Runtime.php b/vendor/twig/twig/lib/Twig/Error/Runtime.php index c4e41b1d0..3b24ad3a4 100644 --- a/vendor/twig/twig/lib/Twig/Error/Runtime.php +++ b/vendor/twig/twig/lib/Twig/Error/Runtime.php @@ -18,3 +18,5 @@ class Twig_Error_Runtime extends Twig_Error { } + +class_alias('Twig_Error_Runtime', 'Twig\Error\RuntimeError', false); diff --git a/vendor/twig/twig/lib/Twig/Error/Syntax.php b/vendor/twig/twig/lib/Twig/Error/Syntax.php index bded07e56..9d09f2179 100644 --- a/vendor/twig/twig/lib/Twig/Error/Syntax.php +++ b/vendor/twig/twig/lib/Twig/Error/Syntax.php @@ -51,3 +51,5 @@ class Twig_Error_Syntax extends Twig_Error return array_keys($alternatives); } } + +class_alias('Twig_Error_Syntax', 'Twig\Error\SyntaxError', false); diff --git a/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php b/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php index 553fb4e5e..968cb21a4 100644 --- a/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php +++ b/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php @@ -27,3 +27,5 @@ interface Twig_ExistsLoaderInterface */ public function exists($name); } + +class_alias('Twig_ExistsLoaderInterface', 'Twig\Loader\ExistsLoaderInterface', false); diff --git a/vendor/twig/twig/lib/Twig/ExpressionParser.php b/vendor/twig/twig/lib/Twig/ExpressionParser.php index 517ad14c7..4906f903e 100644 --- a/vendor/twig/twig/lib/Twig/ExpressionParser.php +++ b/vendor/twig/twig/lib/Twig/ExpressionParser.php @@ -737,3 +737,5 @@ class Twig_ExpressionParser return true; } } + +class_alias('Twig_ExpressionParser', 'Twig\ExpressionParser', false); diff --git a/vendor/twig/twig/lib/Twig/Extension.php b/vendor/twig/twig/lib/Twig/Extension.php index 5d72634a6..38084495f 100644 --- a/vendor/twig/twig/lib/Twig/Extension.php +++ b/vendor/twig/twig/lib/Twig/Extension.php @@ -8,6 +8,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + abstract class Twig_Extension implements Twig_ExtensionInterface { /** @@ -63,3 +64,6 @@ abstract class Twig_Extension implements Twig_ExtensionInterface return get_class($this); } } + +class_alias('Twig_Extension', 'Twig\Extension\AbstractExtension', false); +class_exists('Twig_Environment'); diff --git a/vendor/twig/twig/lib/Twig/Extension/Core.php b/vendor/twig/twig/lib/Twig/Extension/Core.php index 4963a1679..34f9ef7d6 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Core.php +++ b/vendor/twig/twig/lib/Twig/Extension/Core.php @@ -1,8 +1,7 @@ true, 'UTF-8' => true); - } else { - $htmlspecialcharsCharsets = array( - 'ISO-8859-1' => true, 'ISO8859-1' => true, - 'ISO-8859-15' => true, 'ISO8859-15' => true, - 'utf-8' => true, 'UTF-8' => true, - 'CP866' => true, 'IBM866' => true, '866' => true, - 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true, - '1251' => true, - 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true, - 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true, - 'BIG5' => true, '950' => true, - 'GB2312' => true, '936' => true, - 'BIG5-HKSCS' => true, - 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true, - 'EUC-JP' => true, 'EUCJP' => true, - 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true, - ); - } - } + static $htmlspecialcharsCharsets = array( + 'ISO-8859-1' => true, 'ISO8859-1' => true, + 'ISO-8859-15' => true, 'ISO8859-15' => true, + 'utf-8' => true, 'UTF-8' => true, + 'CP866' => true, 'IBM866' => true, '866' => true, + 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true, + '1251' => true, + 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true, + 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true, + 'BIG5' => true, '950' => true, + 'GB2312' => true, '936' => true, + 'BIG5-HKSCS' => true, + 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true, + 'EUC-JP' => true, 'EUCJP' => true, + 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true, + ); if (isset($htmlspecialcharsCharsets[$charset])) { return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset); @@ -1264,15 +1255,23 @@ if (function_exists('mb_get_info')) { */ function twig_length_filter(Twig_Environment $env, $thing) { + if (null === $thing) { + return 0; + } + if (is_scalar($thing)) { return mb_strlen($thing, $env->getCharset()); } - if (method_exists($thing, '__toString') && !$thing instanceof \Countable) { + if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) { return mb_strlen((string) $thing, $env->getCharset()); } - return count($thing); + if ($thing instanceof \Countable || is_array($thing)) { + return count($thing); + } + + return 1; } /** @@ -1355,15 +1354,23 @@ else { */ function twig_length_filter(Twig_Environment $env, $thing) { + if (null === $thing) { + return 0; + } + if (is_scalar($thing)) { return strlen($thing); } - if (method_exists($thing, '__toString') && !$thing instanceof \Countable) { + if (is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) { return strlen((string) $thing); } - return count($thing); + if ($thing instanceof \Countable || is_array($thing)) { + return count($thing); + } + + return 1; } /** @@ -1425,7 +1432,7 @@ function twig_test_empty($value) return 0 == count($value); } - if (method_exists($value, '__toString')) { + if (is_object($value) && method_exists($value, '__toString')) { return '' === (string) $value; } @@ -1601,3 +1608,5 @@ function twig_array_batch($items, $size, $fill = null) return $result; } + +class_alias('Twig_Extension_Core', 'Twig\Extension\CoreExtension', false); diff --git a/vendor/twig/twig/lib/Twig/Extension/Debug.php b/vendor/twig/twig/lib/Twig/Extension/Debug.php index d22a38550..d0cd1962b 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Debug.php +++ b/vendor/twig/twig/lib/Twig/Extension/Debug.php @@ -23,7 +23,7 @@ class Twig_Extension_Debug extends Twig_Extension // false means that it was not set (and the default is on) or it explicitly enabled // xdebug.overload_var_dump produces HTML only when html_errors is also enabled && (false === ini_get('html_errors') || ini_get('html_errors')) - || 'cli' === php_sapi_name() + || 'cli' === PHP_SAPI ; return array( @@ -63,3 +63,5 @@ function twig_var_dump(Twig_Environment $env, $context) return ob_get_clean(); } + +class_alias('Twig_Extension_Debug', 'Twig\Extension\DebugExtension', false); diff --git a/vendor/twig/twig/lib/Twig/Extension/Escaper.php b/vendor/twig/twig/lib/Twig/Extension/Escaper.php index 118b6b367..46c2d84b6 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Escaper.php +++ b/vendor/twig/twig/lib/Twig/Extension/Escaper.php @@ -108,3 +108,5 @@ function twig_raw_filter($string) { return $string; } + +class_alias('Twig_Extension_Escaper', 'Twig\Extension\EscaperExtension', false); diff --git a/vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php b/vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php index 5370b8e2a..922cd2c93 100644 --- a/vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php +++ b/vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php @@ -20,3 +20,5 @@ interface Twig_Extension_GlobalsInterface { } + +class_alias('Twig_Extension_GlobalsInterface', 'Twig\Extension\GlobalsInterface', false); diff --git a/vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php b/vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php index 7a075822f..1549862f4 100644 --- a/vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php +++ b/vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php @@ -20,3 +20,5 @@ interface Twig_Extension_InitRuntimeInterface { } + +class_alias('Twig_Extension_InitRuntimeInterface', 'Twig\Extension\InitRuntimeInterface', false); diff --git a/vendor/twig/twig/lib/Twig/Extension/Optimizer.php b/vendor/twig/twig/lib/Twig/Extension/Optimizer.php index e100f0b54..6c62e3efc 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Optimizer.php +++ b/vendor/twig/twig/lib/Twig/Extension/Optimizer.php @@ -31,3 +31,5 @@ class Twig_Extension_Optimizer extends Twig_Extension return 'optimizer'; } } + +class_alias('Twig_Extension_Optimizer', 'Twig\Extension\OptimizerExtension', false); diff --git a/vendor/twig/twig/lib/Twig/Extension/Profiler.php b/vendor/twig/twig/lib/Twig/Extension/Profiler.php index 1d874ef8e..fcfc002ba 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Profiler.php +++ b/vendor/twig/twig/lib/Twig/Extension/Profiler.php @@ -44,3 +44,6 @@ class Twig_Extension_Profiler extends Twig_Extension return 'profiler'; } } + +class_alias('Twig_Extension_Profiler', 'Twig\Extension\ProfilerExtension', false); +class_exists('Twig_Profiler_Profile'); diff --git a/vendor/twig/twig/lib/Twig/Extension/Sandbox.php b/vendor/twig/twig/lib/Twig/Extension/Sandbox.php index 1469a1e04..5cb80a717 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Sandbox.php +++ b/vendor/twig/twig/lib/Twig/Extension/Sandbox.php @@ -99,3 +99,5 @@ class Twig_Extension_Sandbox extends Twig_Extension return 'sandbox'; } } + +class_alias('Twig_Extension_Sandbox', 'Twig\Extension\SandboxExtension', false); diff --git a/vendor/twig/twig/lib/Twig/Extension/Staging.php b/vendor/twig/twig/lib/Twig/Extension/Staging.php index 34b71d27e..d3a0f9c94 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Staging.php +++ b/vendor/twig/twig/lib/Twig/Extension/Staging.php @@ -108,3 +108,5 @@ class Twig_Extension_Staging extends Twig_Extension return 'staging'; } } + +class_alias('Twig_Extension_Staging', 'Twig\Extension\StagingExtension', false); diff --git a/vendor/twig/twig/lib/Twig/Extension/StringLoader.php b/vendor/twig/twig/lib/Twig/Extension/StringLoader.php index c41517397..2ce3c9924 100644 --- a/vendor/twig/twig/lib/Twig/Extension/StringLoader.php +++ b/vendor/twig/twig/lib/Twig/Extension/StringLoader.php @@ -43,3 +43,5 @@ function twig_template_from_string(Twig_Environment $env, $template) { return $env->createTemplate((string) $template); } + +class_alias('Twig_Extension_StringLoader', 'Twig\Extension\StringLoaderExtension', false); diff --git a/vendor/twig/twig/lib/Twig/ExtensionInterface.php b/vendor/twig/twig/lib/Twig/ExtensionInterface.php index c5214bd56..946df500a 100644 --- a/vendor/twig/twig/lib/Twig/ExtensionInterface.php +++ b/vendor/twig/twig/lib/Twig/ExtensionInterface.php @@ -85,3 +85,6 @@ interface Twig_ExtensionInterface */ public function getName(); } + +class_alias('Twig_ExtensionInterface', 'Twig\Extension\ExtensionInterface', false); +class_exists('Twig_Environment'); diff --git a/vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php b/vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php index f428047ca..2cdaded1d 100644 --- a/vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php +++ b/vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php @@ -35,3 +35,5 @@ class Twig_FactoryRuntimeLoader implements Twig_RuntimeLoaderInterface } } } + +class_alias('Twig_FactoryRuntimeLoader', 'Twig\RuntimeLoader\FactoryRuntimeLoader', false); diff --git a/vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php b/vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php index 47183726b..8f8cd2ee5 100644 --- a/vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php +++ b/vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php @@ -56,3 +56,5 @@ class Twig_FileExtensionEscapingStrategy } } } + +class_alias('Twig_FileExtensionEscapingStrategy', 'Twig\FileExtensionEscapingStrategy', false); diff --git a/vendor/twig/twig/lib/Twig/Lexer.php b/vendor/twig/twig/lib/Twig/Lexer.php index 834b54fbe..85390b28c 100644 --- a/vendor/twig/twig/lib/Twig/Lexer.php +++ b/vendor/twig/twig/lib/Twig/Lexer.php @@ -420,3 +420,5 @@ class Twig_Lexer implements Twig_LexerInterface $this->state = array_pop($this->states); } } + +class_alias('Twig_Lexer', 'Twig\Lexer', false); diff --git a/vendor/twig/twig/lib/Twig/Loader/Array.php b/vendor/twig/twig/lib/Twig/Loader/Array.php index 430efd060..0aac76900 100644 --- a/vendor/twig/twig/lib/Twig/Loader/Array.php +++ b/vendor/twig/twig/lib/Twig/Loader/Array.php @@ -80,7 +80,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); } - return $this->templates[$name]; + return $name.':'.$this->templates[$name]; } public function isFresh($name, $time) @@ -93,3 +93,5 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf return true; } } + +class_alias('Twig_Loader_Array', 'Twig\Loader\ArrayLoader', false); diff --git a/vendor/twig/twig/lib/Twig/Loader/Chain.php b/vendor/twig/twig/lib/Twig/Loader/Chain.php index ffa892b17..59a337969 100644 --- a/vendor/twig/twig/lib/Twig/Loader/Chain.php +++ b/vendor/twig/twig/lib/Twig/Loader/Chain.php @@ -147,3 +147,5 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); } } + +class_alias('Twig_Loader_Chain', 'Twig\Loader\ChainLoader', false); diff --git a/vendor/twig/twig/lib/Twig/Loader/Filesystem.php b/vendor/twig/twig/lib/Twig/Loader/Filesystem.php index 25be4e2d8..1275044f8 100644 --- a/vendor/twig/twig/lib/Twig/Loader/Filesystem.php +++ b/vendor/twig/twig/lib/Twig/Loader/Filesystem.php @@ -286,3 +286,5 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI ; } } + +class_alias('Twig_Loader_Filesystem', 'Twig\Loader\FilesystemLoader', false); diff --git a/vendor/twig/twig/lib/Twig/LoaderInterface.php b/vendor/twig/twig/lib/Twig/LoaderInterface.php index b02999723..459a70abb 100644 --- a/vendor/twig/twig/lib/Twig/LoaderInterface.php +++ b/vendor/twig/twig/lib/Twig/LoaderInterface.php @@ -53,3 +53,5 @@ interface Twig_LoaderInterface */ public function isFresh($name, $time); } + +class_alias('Twig_LoaderInterface', 'Twig\Loader\LoaderInterface', false); diff --git a/vendor/twig/twig/lib/Twig/Markup.php b/vendor/twig/twig/lib/Twig/Markup.php index 535ebe9e3..8591d1f93 100644 --- a/vendor/twig/twig/lib/Twig/Markup.php +++ b/vendor/twig/twig/lib/Twig/Markup.php @@ -35,3 +35,5 @@ class Twig_Markup implements Countable return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content); } } + +class_alias('Twig_Markup', 'Twig\Markup', false); diff --git a/vendor/twig/twig/lib/Twig/Node.php b/vendor/twig/twig/lib/Twig/Node.php index 807f198f2..89ada1449 100644 --- a/vendor/twig/twig/lib/Twig/Node.php +++ b/vendor/twig/twig/lib/Twig/Node.php @@ -251,3 +251,6 @@ class Twig_Node implements Twig_NodeInterface return $this->name; } } + +class_alias('Twig_Node', 'Twig\Node\Node', false); +class_exists('Twig_Compiler'); diff --git a/vendor/twig/twig/lib/Twig/Node/AutoEscape.php b/vendor/twig/twig/lib/Twig/Node/AutoEscape.php index 570f23e49..17e4e3813 100644 --- a/vendor/twig/twig/lib/Twig/Node/AutoEscape.php +++ b/vendor/twig/twig/lib/Twig/Node/AutoEscape.php @@ -32,3 +32,5 @@ class Twig_Node_AutoEscape extends Twig_Node $compiler->subcompile($this->getNode('body')); } } + +class_alias('Twig_Node_AutoEscape', 'Twig\Node\AutoEscapeNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Block.php b/vendor/twig/twig/lib/Twig/Node/Block.php index dfd8ceb8b..91752ad27 100644 --- a/vendor/twig/twig/lib/Twig/Node/Block.php +++ b/vendor/twig/twig/lib/Twig/Node/Block.php @@ -37,3 +37,5 @@ class Twig_Node_Block extends Twig_Node ; } } + +class_alias('Twig_Node_Block', 'Twig\Node\BlockNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/BlockReference.php b/vendor/twig/twig/lib/Twig/Node/BlockReference.php index d9b59378c..92a9f398a 100644 --- a/vendor/twig/twig/lib/Twig/Node/BlockReference.php +++ b/vendor/twig/twig/lib/Twig/Node/BlockReference.php @@ -30,3 +30,5 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter ; } } + +class_alias('Twig_Node_BlockReference', 'Twig\Node\BlockReferenceNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Body.php b/vendor/twig/twig/lib/Twig/Node/Body.php index 2314c9abd..07dfef8b5 100644 --- a/vendor/twig/twig/lib/Twig/Node/Body.php +++ b/vendor/twig/twig/lib/Twig/Node/Body.php @@ -17,3 +17,5 @@ class Twig_Node_Body extends Twig_Node { } + +class_alias('Twig_Node_Body', 'Twig\Node\BodyNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/CheckSecurity.php b/vendor/twig/twig/lib/Twig/Node/CheckSecurity.php index b9cf054aa..7258acb6a 100644 --- a/vendor/twig/twig/lib/Twig/Node/CheckSecurity.php +++ b/vendor/twig/twig/lib/Twig/Node/CheckSecurity.php @@ -76,3 +76,5 @@ class Twig_Node_CheckSecurity extends Twig_Node ; } } + +class_alias('Twig_Node_CheckSecurity', 'Twig\Node\CheckSecurityNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Do.php b/vendor/twig/twig/lib/Twig/Node/Do.php index 94305c7a5..cdd7e77a4 100644 --- a/vendor/twig/twig/lib/Twig/Node/Do.php +++ b/vendor/twig/twig/lib/Twig/Node/Do.php @@ -31,3 +31,5 @@ class Twig_Node_Do extends Twig_Node ; } } + +class_alias('Twig_Node_Do', 'Twig\Node\DoNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Embed.php b/vendor/twig/twig/lib/Twig/Node/Embed.php index 1786f36c6..3785d3a9f 100644 --- a/vendor/twig/twig/lib/Twig/Node/Embed.php +++ b/vendor/twig/twig/lib/Twig/Node/Embed.php @@ -42,3 +42,5 @@ class Twig_Node_Embed extends Twig_Node_Include ; } } + +class_alias('Twig_Node_Embed', 'Twig\Node\EmbedNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression.php b/vendor/twig/twig/lib/Twig/Node/Expression.php index e609d812f..a99c4e63a 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression.php @@ -18,3 +18,5 @@ abstract class Twig_Node_Expression extends Twig_Node { } + +class_alias('Twig_Node_Expression', 'Twig\Node\Expression\AbstractExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Array.php b/vendor/twig/twig/lib/Twig/Node/Expression/Array.php index 0c726c04b..0e77bb08b 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Array.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Array.php @@ -79,3 +79,5 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression $compiler->raw(')'); } } + +class_alias('Twig_Node_Expression_Array', 'Twig\Node\Expression\ArrayExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php b/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php index ceb728233..2e6b4c7ca 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php @@ -21,3 +21,5 @@ class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name ; } } + +class_alias('Twig_Node_Expression_AssignName', 'Twig\Node\Expression\AssignNameExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php index d4787698e..2b545d984 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php @@ -33,3 +33,5 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression abstract public function operator(Twig_Compiler $compiler); } + +class_alias('Twig_Node_Expression_Binary', 'Twig\Node\Expression\Binary\AbstractBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php index 51bba4809..5a09d8367 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary return $compiler->raw('+'); } } + +class_alias('Twig_Node_Expression_Binary_Add', 'Twig\Node\Expression\Binary\AddBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php index 9b3997dad..9ffddce6b 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary return $compiler->raw('&&'); } } + +class_alias('Twig_Node_Expression_Binary_And', 'Twig\Node\Expression\Binary\AndBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php index fa9729db0..e46e9ebfa 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseAnd extends Twig_Node_Expression_Binary return $compiler->raw('&'); } } + +class_alias('Twig_Node_Expression_Binary_BitwiseAnd', 'Twig\Node\Expression\Binary\BitwiseAndBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php index e3be54851..5d7f1b7c0 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseOr extends Twig_Node_Expression_Binary return $compiler->raw('|'); } } + +class_alias('Twig_Node_Expression_Binary_BitwiseOr', 'Twig\Node\Expression\Binary\BitwiseOrBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php index 9255d8f78..82edf516c 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseXor extends Twig_Node_Expression_Binary return $compiler->raw('^'); } } + +class_alias('Twig_Node_Expression_Binary_BitwiseXor', 'Twig\Node\Expression\Binary\BitwiseXorBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php index 7de9070eb..91abca602 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary return $compiler->raw('.'); } } + +class_alias('Twig_Node_Expression_Binary_Concat', 'Twig\Node\Expression\Binary\ConcatBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php index 386b4eabe..38ffa30c3 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary return $compiler->raw('/'); } } + +class_alias('Twig_Node_Expression_Binary_Div', 'Twig\Node\Expression\Binary\DivBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php index c24b720a4..85c529376 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php @@ -28,3 +28,5 @@ class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary return $compiler->raw(''); } } + +class_alias('Twig_Node_Expression_Binary_EndsWith', 'Twig\Node\Expression\Binary\EndsWithBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php index 4535cd082..a6a6946b6 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php @@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary return $compiler->raw('=='); } } + +class_alias('Twig_Node_Expression_Binary_Equal', 'Twig\Node\Expression\Binary\EqualBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php index b386ae357..7393bcb89 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php @@ -22,3 +22,5 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary return $compiler->raw('/'); } } + +class_alias('Twig_Node_Expression_Binary_FloorDiv', 'Twig\Node\Expression\Binary\FloorDivBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php index 52dcb3322..832f97977 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php @@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary return $compiler->raw('>'); } } + +class_alias('Twig_Node_Expression_Binary_Greater', 'Twig\Node\Expression\Binary\GreaterBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php index 1d66d6c42..c5f762457 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php @@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_GreaterEqual extends Twig_Node_Expression_Bina return $compiler->raw('>='); } } + +class_alias('Twig_Node_Expression_Binary_GreaterEqual', 'Twig\Node\Expression\Binary\GreaterEqualBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php index ba44961ac..af112448f 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php @@ -26,3 +26,5 @@ class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary return $compiler->raw('in'); } } + +class_alias('Twig_Node_Expression_Binary_In', 'Twig\Node\Expression\Binary\InBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php index c9d20c427..ab8fc1f9a 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php @@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Less extends Twig_Node_Expression_Binary return $compiler->raw('<'); } } + +class_alias('Twig_Node_Expression_Binary_Less', 'Twig\Node\Expression\Binary\LessBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php index 219b3bdbf..71a279e9c 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php @@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_LessEqual extends Twig_Node_Expression_Binary return $compiler->raw('<='); } } + +class_alias('Twig_Node_Expression_Binary_LessEqual', 'Twig\Node\Expression\Binary\LessEqualBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php index b22debf2f..5cb855842 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php @@ -26,3 +26,5 @@ class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary return $compiler->raw(''); } } + +class_alias('Twig_Node_Expression_Binary_Matches', 'Twig\Node\Expression\Binary\MatchesBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php index c99874ca3..28109633d 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Mod extends Twig_Node_Expression_Binary return $compiler->raw('%'); } } + +class_alias('Twig_Node_Expression_Binary_Mod', 'Twig\Node\Expression\Binary\ModBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php index 0d24cee4e..790c6a22d 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Mul extends Twig_Node_Expression_Binary return $compiler->raw('*'); } } + +class_alias('Twig_Node_Expression_Binary_Mul', 'Twig\Node\Expression\Binary\MulBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php index 69eae7e85..bb45c9ed5 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php @@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_NotEqual extends Twig_Node_Expression_Binary return $compiler->raw('!='); } } + +class_alias('Twig_Node_Expression_Binary_NotEqual', 'Twig\Node\Expression\Binary\NotEqualBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php index f276da7d6..9dedf92f9 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php @@ -26,3 +26,5 @@ class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary return $compiler->raw('not in'); } } + +class_alias('Twig_Node_Expression_Binary_NotIn', 'Twig\Node\Expression\Binary\NotInBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php index 7621763dd..dc9eece14 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Or extends Twig_Node_Expression_Binary return $compiler->raw('||'); } } + +class_alias('Twig_Node_Expression_Binary_Or', 'Twig\Node\Expression\Binary\OrBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php index d3225ded9..d24777bd5 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php @@ -30,3 +30,5 @@ class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary return $compiler->raw('**'); } } + +class_alias('Twig_Node_Expression_Binary_Power', 'Twig\Node\Expression\Binary\PowerBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php index 4261cdea7..187f67653 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php @@ -26,3 +26,5 @@ class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary return $compiler->raw('..'); } } + +class_alias('Twig_Node_Expression_Binary_Range', 'Twig\Node\Expression\Binary\RangeBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php index d1e9a5a7f..7e43b8de0 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php @@ -28,3 +28,5 @@ class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary return $compiler->raw(''); } } + +class_alias('Twig_Node_Expression_Binary_StartsWith', 'Twig\Node\Expression\Binary\StartsWithBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php index b423d3eef..cff8ed075 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Sub extends Twig_Node_Expression_Binary return $compiler->raw('-'); } } + +class_alias('Twig_Node_Expression_Binary_Sub', 'Twig\Node\Expression\Binary\SubBinary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php b/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php index 056d99185..37a3983d6 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php @@ -89,3 +89,5 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression return $compiler->raw(')'); } } + +class_alias('Twig_Node_Expression_BlockReference', 'Twig\Node\Expression\BlockReferenceExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Call.php b/vendor/twig/twig/lib/Twig/Node/Expression/Call.php index 277679724..d962b6a50 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Call.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Call.php @@ -287,3 +287,5 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression return $this->reflector = array($r, $callable); } } + +class_alias('Twig_Node_Expression_Call', 'Twig\Node\Expression\CallExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php b/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php index 67cca1fd2..c339d773c 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php @@ -29,3 +29,5 @@ class Twig_Node_Expression_Conditional extends Twig_Node_Expression ; } } + +class_alias('Twig_Node_Expression_Conditional', 'Twig\Node\Expression\ConditionalExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php b/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php index 1a2c5964f..bf4d031cf 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php @@ -21,3 +21,5 @@ class Twig_Node_Expression_Constant extends Twig_Node_Expression $compiler->repr($this->getAttribute('value')); } } + +class_alias('Twig_Node_Expression_Constant', 'Twig\Node\Expression\ConstantExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php b/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php index a8fa847a8..12da1d676 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php @@ -37,3 +37,5 @@ class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call $this->compileCallable($compiler); } } + +class_alias('Twig_Node_Expression_Filter', 'Twig\Node\Expression\FilterExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php b/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php index d32d86d34..d2e19d54e 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php @@ -41,3 +41,5 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter $compiler->subcompile($this->getNode('node')); } } + +class_alias('Twig_Node_Expression_Filter_Default', 'Twig\Node\Expression\Filter\DefaultFilter', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Function.php b/vendor/twig/twig/lib/Twig/Node/Expression/Function.php index eaad56ec0..cdee7c972 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Function.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Function.php @@ -41,3 +41,5 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call $this->compileCallable($compiler); } } + +class_alias('Twig_Node_Expression_Function', 'Twig\Node\Expression\FunctionExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php b/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php index 75814265c..b7823accb 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php @@ -70,3 +70,5 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression $compiler->raw(')'); } } + +class_alias('Twig_Node_Expression_GetAttr', 'Twig\Node\Expression\GetAttrExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php b/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php index 39481337b..709016eb2 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php @@ -39,3 +39,5 @@ class Twig_Node_Expression_MethodCall extends Twig_Node_Expression $compiler->raw(')'); } } + +class_alias('Twig_Node_Expression_MethodCall', 'Twig\Node\Expression\MethodCallExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Name.php b/vendor/twig/twig/lib/Twig/Node/Expression/Name.php index e03ca3578..9d5a21f87 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Name.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Name.php @@ -98,3 +98,5 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression return !$this->isSpecial() && !$this->getAttribute('is_defined_test'); } } + +class_alias('Twig_Node_Expression_Name', 'Twig\Node\Expression\NameExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php b/vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php index 14f6358fd..eaafa4c91 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php @@ -44,3 +44,5 @@ class Twig_Node_Expression_NullCoalesce extends Twig_Node_Expression_Conditional } } } + +class_alias('Twig_Node_Expression_NullCoalesce', 'Twig\Node\Expression\NullCoalesceExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php b/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php index e7d82d81c..78692db29 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php @@ -40,3 +40,5 @@ class Twig_Node_Expression_Parent extends Twig_Node_Expression } } } + +class_alias('Twig_Node_Expression_Parent', 'Twig\Node\Expression\ParentExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php b/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php index 09a04a319..0a86e003d 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php @@ -24,3 +24,5 @@ class Twig_Node_Expression_TempName extends Twig_Node_Expression ; } } + +class_alias('Twig_Node_Expression_TempName', 'Twig\Node\Expression\TempNameExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test.php index 3dfe4f195..ad102ba60 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test.php @@ -38,3 +38,5 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call $this->compileCallable($compiler); } } + +class_alias('Twig_Node_Expression_Test', 'Twig\Node\Expression\TestExpression', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php index ffde3488c..a51a4ba13 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php @@ -44,3 +44,5 @@ class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test ; } } + +class_alias('Twig_Node_Expression_Test_Constant', 'Twig\Node\Expression\Test\ConstantTest', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php index 31cd987cd..2136c3907 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php @@ -57,3 +57,5 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test $compiler->subcompile($this->getNode('node')); } } + +class_alias('Twig_Node_Expression_Test_Defined', 'Twig\Node\Expression\Test\DefinedTest', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php index 0d6bdb49e..a5d71961a 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php @@ -31,3 +31,5 @@ class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test ; } } + +class_alias('Twig_Node_Expression_Test_Divisibleby', 'Twig\Node\Expression\Test\DivisiblebyTest', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php index fe42e627d..7e198bea6 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php @@ -30,3 +30,5 @@ class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test ; } } + +class_alias('Twig_Node_Expression_Test_Even', 'Twig\Node\Expression\Test\EvenTest', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php index 934d83561..3746e4cbd 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php @@ -29,3 +29,5 @@ class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test ; } } + +class_alias('Twig_Node_Expression_Test_Null', 'Twig\Node\Expression\Test\NullTest', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php index 4f16029a2..0c6c099bb 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php @@ -30,3 +30,5 @@ class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test ; } } + +class_alias('Twig_Node_Expression_Test_Odd', 'Twig\Node\Expression\Test\OddTest', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php index abc2f5beb..e95ff1f20 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php @@ -27,3 +27,5 @@ class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test ; } } + +class_alias('Twig_Node_Expression_Test_Sameas', 'Twig\Node\Expression\Test\SameasTest', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php index 0ea2c2c32..5804485e3 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php @@ -25,3 +25,5 @@ abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression abstract public function operator(Twig_Compiler $compiler); } + +class_alias('Twig_Node_Expression_Unary', 'Twig\Node\Expression\Unary\AbstractUnary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php index ca3ef8f32..039d933d9 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Neg extends Twig_Node_Expression_Unary $compiler->raw('-'); } } + +class_alias('Twig_Node_Expression_Unary_Neg', 'Twig\Node\Expression\Unary\NegUnary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php index a5e4f198f..a0860b183 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Not extends Twig_Node_Expression_Unary $compiler->raw('!'); } } + +class_alias('Twig_Node_Expression_Unary_Not', 'Twig\Node\Expression\Unary\NotUnary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php index 5497532bc..eeff5452f 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php @@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Pos extends Twig_Node_Expression_Unary $compiler->raw('+'); } } + +class_alias('Twig_Node_Expression_Unary_Pos', 'Twig\Node\Expression\Unary\PosUnary', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Flush.php b/vendor/twig/twig/lib/Twig/Node/Flush.php index cd4be411e..fcc461ac0 100644 --- a/vendor/twig/twig/lib/Twig/Node/Flush.php +++ b/vendor/twig/twig/lib/Twig/Node/Flush.php @@ -29,3 +29,5 @@ class Twig_Node_Flush extends Twig_Node ; } } + +class_alias('Twig_Node_Flush', 'Twig\Node\FlushNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/For.php b/vendor/twig/twig/lib/Twig/Node/For.php index f93d9c812..914b70c98 100644 --- a/vendor/twig/twig/lib/Twig/Node/For.php +++ b/vendor/twig/twig/lib/Twig/Node/For.php @@ -109,3 +109,5 @@ class Twig_Node_For extends Twig_Node $compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n"); } } + +class_alias('Twig_Node_For', 'Twig\Node\ForNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/ForLoop.php b/vendor/twig/twig/lib/Twig/Node/ForLoop.php index ab0215e6b..06477cf1f 100644 --- a/vendor/twig/twig/lib/Twig/Node/ForLoop.php +++ b/vendor/twig/twig/lib/Twig/Node/ForLoop.php @@ -48,3 +48,5 @@ class Twig_Node_ForLoop extends Twig_Node } } } + +class_alias('Twig_Node_ForLoop', 'Twig\Node\ForLoopNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/If.php b/vendor/twig/twig/lib/Twig/Node/If.php index 9cd78f471..d82edec77 100644 --- a/vendor/twig/twig/lib/Twig/Node/If.php +++ b/vendor/twig/twig/lib/Twig/Node/If.php @@ -64,3 +64,5 @@ class Twig_Node_If extends Twig_Node ->write("}\n"); } } + +class_alias('Twig_Node_If', 'Twig\Node\IfNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Import.php b/vendor/twig/twig/lib/Twig/Node/Import.php index 759bb5c3e..c77e320b7 100644 --- a/vendor/twig/twig/lib/Twig/Node/Import.php +++ b/vendor/twig/twig/lib/Twig/Node/Import.php @@ -47,3 +47,5 @@ class Twig_Node_Import extends Twig_Node $compiler->raw(";\n"); } } + +class_alias('Twig_Node_Import', 'Twig\Node\ImportNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Include.php b/vendor/twig/twig/lib/Twig/Node/Include.php index 15a27ca60..2a5114cb8 100644 --- a/vendor/twig/twig/lib/Twig/Node/Include.php +++ b/vendor/twig/twig/lib/Twig/Node/Include.php @@ -86,3 +86,5 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface } } } + +class_alias('Twig_Node_Include', 'Twig\Node\IncludeNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Macro.php b/vendor/twig/twig/lib/Twig/Node/Macro.php index e9e1421aa..3cf549770 100644 --- a/vendor/twig/twig/lib/Twig/Node/Macro.php +++ b/vendor/twig/twig/lib/Twig/Node/Macro.php @@ -121,3 +121,5 @@ class Twig_Node_Macro extends Twig_Node ; } } + +class_alias('Twig_Node_Macro', 'Twig\Node\MacroNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Module.php b/vendor/twig/twig/lib/Twig/Node/Module.php index 5bfcc9230..5cd8d0502 100644 --- a/vendor/twig/twig/lib/Twig/Node/Module.php +++ b/vendor/twig/twig/lib/Twig/Node/Module.php @@ -457,3 +457,5 @@ class Twig_Node_Module extends Twig_Node } } } + +class_alias('Twig_Node_Module', 'Twig\Node\ModuleNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Print.php b/vendor/twig/twig/lib/Twig/Node/Print.php index 9e317c84e..374db89b7 100644 --- a/vendor/twig/twig/lib/Twig/Node/Print.php +++ b/vendor/twig/twig/lib/Twig/Node/Print.php @@ -32,3 +32,5 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface ; } } + +class_alias('Twig_Node_Print', 'Twig\Node\PrintNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Sandbox.php b/vendor/twig/twig/lib/Twig/Node/Sandbox.php index 658e068e1..44b30ab9c 100644 --- a/vendor/twig/twig/lib/Twig/Node/Sandbox.php +++ b/vendor/twig/twig/lib/Twig/Node/Sandbox.php @@ -40,3 +40,5 @@ class Twig_Node_Sandbox extends Twig_Node ; } } + +class_alias('Twig_Node_Sandbox', 'Twig\Node\SandboxNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php b/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php index fba0051ba..a08f21f56 100644 --- a/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php +++ b/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php @@ -47,3 +47,5 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print return $node; } } + +class_alias('Twig_Node_SandboxedPrint', 'Twig\Node\SandboxedPrintNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Set.php b/vendor/twig/twig/lib/Twig/Node/Set.php index 36e05ccad..6c6743eeb 100644 --- a/vendor/twig/twig/lib/Twig/Node/Set.php +++ b/vendor/twig/twig/lib/Twig/Node/Set.php @@ -94,3 +94,5 @@ class Twig_Node_Set extends Twig_Node implements Twig_NodeCaptureInterface $compiler->raw(";\n"); } } + +class_alias('Twig_Node_Set', 'Twig\Node\SetNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/SetTemp.php b/vendor/twig/twig/lib/Twig/Node/SetTemp.php index 0f43c7d31..996fdcde7 100644 --- a/vendor/twig/twig/lib/Twig/Node/SetTemp.php +++ b/vendor/twig/twig/lib/Twig/Node/SetTemp.php @@ -9,6 +9,9 @@ * file that was distributed with this source code. */ +/** + * @internal + */ class Twig_Node_SetTemp extends Twig_Node { public function __construct($name, $lineno) @@ -33,3 +36,5 @@ class Twig_Node_SetTemp extends Twig_Node ; } } + +class_alias('Twig_Node_SetTemp', 'Twig\Node\SetTempNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Spaceless.php b/vendor/twig/twig/lib/Twig/Node/Spaceless.php index 00419e260..76f90cde5 100644 --- a/vendor/twig/twig/lib/Twig/Node/Spaceless.php +++ b/vendor/twig/twig/lib/Twig/Node/Spaceless.php @@ -33,3 +33,5 @@ class Twig_Node_Spaceless extends Twig_Node ; } } + +class_alias('Twig_Node_Spaceless', 'Twig\Node\SpacelessNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/Text.php b/vendor/twig/twig/lib/Twig/Node/Text.php index 2c013cd76..f4577fee2 100644 --- a/vendor/twig/twig/lib/Twig/Node/Text.php +++ b/vendor/twig/twig/lib/Twig/Node/Text.php @@ -32,3 +32,5 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface ; } } + +class_alias('Twig_Node_Text', 'Twig\Node\TextNode', false); diff --git a/vendor/twig/twig/lib/Twig/Node/With.php b/vendor/twig/twig/lib/Twig/Node/With.php index 4978f375b..2ab0ea5d7 100644 --- a/vendor/twig/twig/lib/Twig/Node/With.php +++ b/vendor/twig/twig/lib/Twig/Node/With.php @@ -60,3 +60,5 @@ class Twig_Node_With extends Twig_Node ; } } + +class_alias('Twig_Node_With', 'Twig\Node\WithNode', false); diff --git a/vendor/twig/twig/lib/Twig/NodeCaptureInterface.php b/vendor/twig/twig/lib/Twig/NodeCaptureInterface.php index 97ffb6af2..6638834b1 100644 --- a/vendor/twig/twig/lib/Twig/NodeCaptureInterface.php +++ b/vendor/twig/twig/lib/Twig/NodeCaptureInterface.php @@ -17,3 +17,5 @@ interface Twig_NodeCaptureInterface { } + +class_alias('Twig_NodeCaptureInterface', 'Twig\Node\NodeCaptureInterface', false); diff --git a/vendor/twig/twig/lib/Twig/NodeOutputInterface.php b/vendor/twig/twig/lib/Twig/NodeOutputInterface.php index e6bbd9643..5a8eaa9c3 100644 --- a/vendor/twig/twig/lib/Twig/NodeOutputInterface.php +++ b/vendor/twig/twig/lib/Twig/NodeOutputInterface.php @@ -17,3 +17,5 @@ interface Twig_NodeOutputInterface { } + +class_alias('Twig_NodeOutputInterface', 'Twig\Node\NodeOutputInterface', false); diff --git a/vendor/twig/twig/lib/Twig/NodeTraverser.php b/vendor/twig/twig/lib/Twig/NodeTraverser.php index 353221747..787629ce3 100644 --- a/vendor/twig/twig/lib/Twig/NodeTraverser.php +++ b/vendor/twig/twig/lib/Twig/NodeTraverser.php @@ -80,3 +80,5 @@ class Twig_NodeTraverser return $visitor->leaveNode($node, $this->env); } } + +class_alias('Twig_NodeTraverser', 'Twig\NodeTraverser', false); diff --git a/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php b/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php index 7169f6f67..1a1ae66f7 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php @@ -150,3 +150,5 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor return 0; } } + +class_alias('Twig_NodeVisitor_Escaper', 'Twig\NodeVisitor\EscaperNodeVisitor', false); diff --git a/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php b/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php index 43453c4dc..2fa19f3d7 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php @@ -249,3 +249,5 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor return 255; } } + +class_alias('Twig_NodeVisitor_Optimizer', 'Twig\NodeVisitor\OptimizerNodeVisitor', false); diff --git a/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php b/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php index 6997f3573..ca31c8fc7 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php @@ -146,3 +146,5 @@ class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor return 0; } } + +class_alias('Twig_NodeVisitor_SafeAnalysis', 'Twig\NodeVisitor\SafeAnalysisNodeVisitor', false); diff --git a/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php b/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php index baf00a034..b631b29d4 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php @@ -73,3 +73,5 @@ class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor return 0; } } + +class_alias('Twig_NodeVisitor_Sandbox', 'Twig\NodeVisitor\SandboxNodeVisitor', false); diff --git a/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php b/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php index 092d36ae7..1270a3724 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php @@ -39,3 +39,7 @@ interface Twig_NodeVisitorInterface */ public function getPriority(); } + +class_alias('Twig_NodeVisitorInterface', 'Twig\NodeVisitor\NodeVisitorInterface', false); +class_exists('Twig_Environment'); +class_exists('Twig_Node'); diff --git a/vendor/twig/twig/lib/Twig/Parser.php b/vendor/twig/twig/lib/Twig/Parser.php index 070f301b1..e796f197a 100644 --- a/vendor/twig/twig/lib/Twig/Parser.php +++ b/vendor/twig/twig/lib/Twig/Parser.php @@ -404,3 +404,7 @@ class Twig_Parser implements Twig_ParserInterface return $node; } } + +class_alias('Twig_Parser', 'Twig\Parser', false); +class_exists('Twig_Node'); +class_exists('Twig_TokenStream'); diff --git a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php index 6be67edf9..7a33baf2d 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php @@ -22,7 +22,7 @@ class Twig_Profiler_Dumper_Blackfire $this->dumpProfile('main()', $profile, $data); $this->dumpChildren('main()', $profile, $data); - $start = microtime(true); + $start = sprintf('%f', microtime(true)); $str = <<%.2fms/%.0f%%', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent); } } + +class_alias('Twig_Profiler_Dumper_Html', 'Twig\Profiler\Dumper\HtmlDumper', false); diff --git a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php index c77e69184..1171e5c3e 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php @@ -68,3 +68,5 @@ class Twig_Profiler_Dumper_Text return $str; } } + +class_alias('Twig_Profiler_Dumper_Text', 'Twig\Profiler\Dumper\TextDumper', false); diff --git a/vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php b/vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php index e10d857e0..69c8f7970 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php @@ -35,3 +35,5 @@ class Twig_Profiler_Node_EnterProfile extends Twig_Node ; } } + +class_alias('Twig_Profiler_Node_EnterProfile', 'Twig\Profiler\Node\EnterProfileNode', false); diff --git a/vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php b/vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php index e4d0beb4e..d1d6a7cc1 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php @@ -29,3 +29,5 @@ class Twig_Profiler_Node_LeaveProfile extends Twig_Node ; } } + +class_alias('Twig_Profiler_Node_LeaveProfile', 'Twig\Profiler\Node\LeaveProfileNode', false); diff --git a/vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php b/vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php index a99047488..a395ae7fd 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php +++ b/vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php @@ -63,3 +63,5 @@ class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor return 0; } } + +class_alias('Twig_Profiler_NodeVisitor_Profiler', 'Twig\Profiler\NodeVisitor\ProfilerNodeVisitor', false); diff --git a/vendor/twig/twig/lib/Twig/Profiler/Profile.php b/vendor/twig/twig/lib/Twig/Profiler/Profile.php index 9274da28b..60b9103c8 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Profile.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Profile.php @@ -160,3 +160,5 @@ class Twig_Profiler_Profile implements IteratorAggregate, Serializable list($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles) = unserialize($data); } } + +class_alias('Twig_Profiler_Profile', 'Twig\Profiler\Profile', false); diff --git a/vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php b/vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php index c41f44af9..f5eb14e0d 100644 --- a/vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php +++ b/vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php @@ -25,3 +25,5 @@ interface Twig_RuntimeLoaderInterface */ public function load($class); } + +class_alias('Twig_RuntimeLoaderInterface', 'Twig\RuntimeLoader\RuntimeLoaderInterface', false); diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php index 5a4e021d5..b6707e386 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php @@ -17,3 +17,5 @@ class Twig_Sandbox_SecurityError extends Twig_Error { } + +class_alias('Twig_Sandbox_SecurityError', 'Twig\Sandbox\SecurityError', false); diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php index 1967cf766..0ba332762 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php @@ -29,3 +29,5 @@ class Twig_Sandbox_SecurityNotAllowedFilterError extends Twig_Sandbox_SecurityEr return $this->filterName; } } + +class_alias('Twig_Sandbox_SecurityNotAllowedFilterError', 'Twig\Sandbox\SecurityNotAllowedFilterError', false); diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php index 79a400f12..aa3914293 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php @@ -29,3 +29,5 @@ class Twig_Sandbox_SecurityNotAllowedFunctionError extends Twig_Sandbox_Security return $this->functionName; } } + +class_alias('Twig_Sandbox_SecurityNotAllowedFunctionError', 'Twig\Sandbox\SecurityNotAllowedFunctionError', false); diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php index 9e5d4df04..93012fe99 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php @@ -36,3 +36,5 @@ class Twig_Sandbox_SecurityNotAllowedMethodError extends Twig_Sandbox_SecurityEr return $this->methodName; } } + +class_alias('Twig_Sandbox_SecurityNotAllowedMethodError', 'Twig\Sandbox\SecurityNotAllowedMethodError', false); diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php index 9f7eab290..f27969c15 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php @@ -36,3 +36,5 @@ class Twig_Sandbox_SecurityNotAllowedPropertyError extends Twig_Sandbox_Security return $this->propertyName; } } + +class_alias('Twig_Sandbox_SecurityNotAllowedPropertyError', 'Twig\Sandbox\SecurityNotAllowedPropertyError', false); diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php index a177206cc..4bbd22387 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php @@ -29,3 +29,5 @@ class Twig_Sandbox_SecurityNotAllowedTagError extends Twig_Sandbox_SecurityError return $this->tagName; } } + +class_alias('Twig_Sandbox_SecurityNotAllowedTagError', 'Twig\Sandbox\SecurityNotAllowedTagError', false); diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php index 4470c39f4..dca0b82b5 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php @@ -121,3 +121,5 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac } } } + +class_alias('Twig_Sandbox_SecurityPolicy', 'Twig\Sandbox\SecurityPolicy', false); diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php index 2111a03c1..88f64447a 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php @@ -22,3 +22,5 @@ interface Twig_Sandbox_SecurityPolicyInterface public function checkPropertyAllowed($obj, $method); } + +class_alias('Twig_Sandbox_SecurityPolicyInterface', 'Twig\Sandbox\SecurityPolicyInterface', false); diff --git a/vendor/twig/twig/lib/Twig/SimpleFilter.php b/vendor/twig/twig/lib/Twig/SimpleFilter.php index a0b98af3a..ee4c0aebf 100644 --- a/vendor/twig/twig/lib/Twig/SimpleFilter.php +++ b/vendor/twig/twig/lib/Twig/SimpleFilter.php @@ -117,3 +117,5 @@ class Twig_SimpleFilter return $this->options['alternative']; } } + +class_alias('Twig_SimpleFilter', 'Twig\TwigFilter', false); diff --git a/vendor/twig/twig/lib/Twig/SimpleFunction.php b/vendor/twig/twig/lib/Twig/SimpleFunction.php index b7ef92a59..a6aa7ca74 100644 --- a/vendor/twig/twig/lib/Twig/SimpleFunction.php +++ b/vendor/twig/twig/lib/Twig/SimpleFunction.php @@ -107,3 +107,5 @@ class Twig_SimpleFunction return $this->options['alternative']; } } + +class_alias('Twig_SimpleFunction', 'Twig\TwigFunction', false); diff --git a/vendor/twig/twig/lib/Twig/SimpleTest.php b/vendor/twig/twig/lib/Twig/SimpleTest.php index b9ae8f146..fee5778b3 100644 --- a/vendor/twig/twig/lib/Twig/SimpleTest.php +++ b/vendor/twig/twig/lib/Twig/SimpleTest.php @@ -69,3 +69,5 @@ class Twig_SimpleTest return $this->options['alternative']; } } + +class_alias('Twig_SimpleTest', 'Twig\TwigTest', false); diff --git a/vendor/twig/twig/lib/Twig/Source.php b/vendor/twig/twig/lib/Twig/Source.php index 389317ec1..bd8d869f3 100644 --- a/vendor/twig/twig/lib/Twig/Source.php +++ b/vendor/twig/twig/lib/Twig/Source.php @@ -49,3 +49,5 @@ class Twig_Source return $this->path; } } + +class_alias('Twig_Source', 'Twig\Source', false); diff --git a/vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php b/vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php index acf21e378..a6e8c4255 100644 --- a/vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php +++ b/vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php @@ -29,3 +29,5 @@ interface Twig_SourceContextLoaderInterface */ public function getSourceContext($name); } + +class_alias('Twig_SourceContextLoaderInterface', 'Twig\Loader\SourceContextLoaderInterface', false); diff --git a/vendor/twig/twig/lib/Twig/Template.php b/vendor/twig/twig/lib/Twig/Template.php index f1855f117..64563419e 100644 --- a/vendor/twig/twig/lib/Twig/Template.php +++ b/vendor/twig/twig/lib/Twig/Template.php @@ -627,11 +627,14 @@ abstract class Twig_Template implements Twig_TemplateInterface continue; } - if (!isset($cache[$name])) { - $cache[$name] = $method; - } - if (!isset($cache[$lcName])) { - $cache[$lcName] = $method; + // skip get() and is() methods (in which case, $name is empty) + if ($name) { + if (!isset($cache[$name])) { + $cache[$name] = $method; + } + if (!isset($cache[$lcName])) { + $cache[$lcName] = $method; + } } } self::$cache[$class] = $cache; @@ -699,3 +702,5 @@ abstract class Twig_Template implements Twig_TemplateInterface return $ret; } } + +class_alias('Twig_Template', 'Twig\Template', false); diff --git a/vendor/twig/twig/lib/Twig/TemplateWrapper.php b/vendor/twig/twig/lib/Twig/TemplateWrapper.php index b72b92c20..497f6e980 100644 --- a/vendor/twig/twig/lib/Twig/TemplateWrapper.php +++ b/vendor/twig/twig/lib/Twig/TemplateWrapper.php @@ -129,3 +129,5 @@ final class Twig_TemplateWrapper return $this->template->getSourceContext(); } } + +class_alias('Twig_TemplateWrapper', 'Twig\TemplateWrapper', false); diff --git a/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php b/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php index 2253f7165..899c3aaf9 100644 --- a/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php +++ b/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php @@ -9,13 +9,15 @@ * file that was distributed with this source code. */ +use PHPUnit\Framework\TestCase; + /** * Integration test helper. * * @author Fabien Potencier * @author Karma Dordrak */ -abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase +abstract class Twig_Test_IntegrationTestCase extends TestCase { /** * @return string @@ -196,7 +198,8 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase if (false !== $exception) { list($class) = explode(':', $exception); - $this->assertThat(null, new PHPUnit_Framework_Constraint_Exception($class)); + $constraintClass = class_exists('PHPUnit\Framework\Constraint\Exception') ? 'PHPUnit\Framework\Constraint\Exception' : 'PHPUnit_Framework_Constraint_Exception'; + $this->assertThat(null, new $constraintClass($class)); } $expected = trim($match[3], "\n "); @@ -230,3 +233,5 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase return $templates; } } + +class_alias('Twig_Test_IntegrationTestCase', 'Twig\Test\IntegrationTestCase', false); diff --git a/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php b/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php index a6b550cf8..479426757 100644 --- a/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php +++ b/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php @@ -8,7 +8,10 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase + +use PHPUnit\Framework\TestCase; + +abstract class Twig_Test_NodeTestCase extends TestCase { abstract public function getTests(); @@ -66,3 +69,7 @@ abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase return '$this->getAttribute('; } } + +class_alias('Twig_Test_NodeTestCase', 'Twig\Test\NodeTestCase', false); +class_exists('Twig_Environment'); +class_exists('Twig_Node'); diff --git a/vendor/twig/twig/lib/Twig/Token.php b/vendor/twig/twig/lib/Twig/Token.php index 717ab0871..c7850eccc 100644 --- a/vendor/twig/twig/lib/Twig/Token.php +++ b/vendor/twig/twig/lib/Twig/Token.php @@ -203,3 +203,5 @@ class Twig_Token } } } + +class_alias('Twig_Token', 'Twig\Token', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser.php b/vendor/twig/twig/lib/Twig/TokenParser.php index 700a227f1..1b4de14da 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser.php +++ b/vendor/twig/twig/lib/Twig/TokenParser.php @@ -29,3 +29,5 @@ abstract class Twig_TokenParser implements Twig_TokenParserInterface $this->parser = $parser; } } + +class_alias('Twig_TokenParser', 'Twig\TokenParser\AbstractTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php b/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php index 176820ead..a20dedd18 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php @@ -79,3 +79,5 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser return 'autoescape'; } } + +class_alias('Twig_TokenParser_AutoEscape', 'Twig\TokenParser\AutoEscapeTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Block.php b/vendor/twig/twig/lib/Twig/TokenParser/Block.php index 9dae2b904..f30f86b58 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Block.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Block.php @@ -69,3 +69,5 @@ class Twig_TokenParser_Block extends Twig_TokenParser return 'block'; } } + +class_alias('Twig_TokenParser_Block', 'Twig\TokenParser\BlockTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Do.php b/vendor/twig/twig/lib/Twig/TokenParser/Do.php index fd03a2965..8ce088089 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Do.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Do.php @@ -30,3 +30,5 @@ class Twig_TokenParser_Do extends Twig_TokenParser return 'do'; } } + +class_alias('Twig_TokenParser_Do', 'Twig\TokenParser\DoTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Embed.php b/vendor/twig/twig/lib/Twig/TokenParser/Embed.php index 019d97810..44644cc6b 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Embed.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Embed.php @@ -63,3 +63,5 @@ class Twig_TokenParser_Embed extends Twig_TokenParser_Include return 'embed'; } } + +class_alias('Twig_TokenParser_Embed', 'Twig\TokenParser\EmbedTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Extends.php b/vendor/twig/twig/lib/Twig/TokenParser/Extends.php index b8454d2d6..31168ccec 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Extends.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Extends.php @@ -42,3 +42,5 @@ class Twig_TokenParser_Extends extends Twig_TokenParser return 'extends'; } } + +class_alias('Twig_TokenParser_Extends', 'Twig\TokenParser\ExtendsTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Filter.php b/vendor/twig/twig/lib/Twig/TokenParser/Filter.php index 1cdc0dd07..760178293 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Filter.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Filter.php @@ -49,3 +49,5 @@ class Twig_TokenParser_Filter extends Twig_TokenParser return 'filter'; } } + +class_alias('Twig_TokenParser_Filter', 'Twig\TokenParser\FilterTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Flush.php b/vendor/twig/twig/lib/Twig/TokenParser/Flush.php index b09ff9577..51832c77e 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Flush.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Flush.php @@ -30,3 +30,5 @@ class Twig_TokenParser_Flush extends Twig_TokenParser return 'flush'; } } + +class_alias('Twig_TokenParser_Flush', 'Twig\TokenParser\FlushTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/For.php b/vendor/twig/twig/lib/Twig/TokenParser/For.php index 6407afa81..63bf41d66 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/For.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/For.php @@ -123,3 +123,5 @@ class Twig_TokenParser_For extends Twig_TokenParser return 'for'; } } + +class_alias('Twig_TokenParser_For', 'Twig\TokenParser\ForTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/From.php b/vendor/twig/twig/lib/Twig/TokenParser/From.php index 69c09c2f2..f3053da4b 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/From.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/From.php @@ -62,3 +62,5 @@ class Twig_TokenParser_From extends Twig_TokenParser return 'from'; } } + +class_alias('Twig_TokenParser_From', 'Twig\TokenParser\FromTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/If.php b/vendor/twig/twig/lib/Twig/TokenParser/If.php index 05459408f..f081df3ab 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/If.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/If.php @@ -82,3 +82,5 @@ class Twig_TokenParser_If extends Twig_TokenParser return 'if'; } } + +class_alias('Twig_TokenParser_If', 'Twig\TokenParser\IfTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Import.php b/vendor/twig/twig/lib/Twig/TokenParser/Import.php index fa5ebae2c..47802f502 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Import.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Import.php @@ -37,3 +37,5 @@ class Twig_TokenParser_Import extends Twig_TokenParser return 'import'; } } + +class_alias('Twig_TokenParser_Import', 'Twig\TokenParser\ImportTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Include.php b/vendor/twig/twig/lib/Twig/TokenParser/Include.php index b3ac1bc7c..309f11db4 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Include.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Include.php @@ -18,8 +18,6 @@ * Body * {% include 'footer.html' %} * - * - * @final */ class Twig_TokenParser_Include extends Twig_TokenParser { @@ -63,3 +61,5 @@ class Twig_TokenParser_Include extends Twig_TokenParser return 'include'; } } + +class_alias('Twig_TokenParser_Include', 'Twig\TokenParser\IncludeTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Macro.php b/vendor/twig/twig/lib/Twig/TokenParser/Macro.php index b845c9095..4287934ba 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Macro.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Macro.php @@ -56,3 +56,5 @@ class Twig_TokenParser_Macro extends Twig_TokenParser return 'macro'; } } + +class_alias('Twig_TokenParser_Macro', 'Twig\TokenParser\MacroTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php b/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php index 0b08fe61a..b8f581cbc 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php @@ -57,3 +57,5 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser return 'sandbox'; } } + +class_alias('Twig_TokenParser_Sandbox', 'Twig\TokenParser\SandboxTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Set.php b/vendor/twig/twig/lib/Twig/TokenParser/Set.php index d03a36b01..48c6b3aeb 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Set.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Set.php @@ -71,3 +71,5 @@ class Twig_TokenParser_Set extends Twig_TokenParser return 'set'; } } + +class_alias('Twig_TokenParser_Set', 'Twig\TokenParser\SetTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php b/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php index e8b2638e2..cecf27c67 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php @@ -47,3 +47,5 @@ class Twig_TokenParser_Spaceless extends Twig_TokenParser return 'spaceless'; } } + +class_alias('Twig_TokenParser_Spaceless', 'Twig\TokenParser\SpacelessTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Use.php b/vendor/twig/twig/lib/Twig/TokenParser/Use.php index c3fb06974..154c0ad12 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Use.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Use.php @@ -64,3 +64,5 @@ class Twig_TokenParser_Use extends Twig_TokenParser return 'use'; } } + +class_alias('Twig_TokenParser_Use', 'Twig\TokenParser\UseTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/With.php b/vendor/twig/twig/lib/Twig/TokenParser/With.php index 8d078d972..7a692597c 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/With.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/With.php @@ -48,3 +48,5 @@ class Twig_TokenParser_With extends Twig_TokenParser return 'with'; } } + +class_alias('Twig_TokenParser_With', 'Twig\TokenParser\WithTokenParser', false); diff --git a/vendor/twig/twig/lib/Twig/TokenParserInterface.php b/vendor/twig/twig/lib/Twig/TokenParserInterface.php index aea969961..14acc8084 100644 --- a/vendor/twig/twig/lib/Twig/TokenParserInterface.php +++ b/vendor/twig/twig/lib/Twig/TokenParserInterface.php @@ -37,3 +37,7 @@ interface Twig_TokenParserInterface */ public function getTag(); } + +class_alias('Twig_TokenParserInterface', 'Twig\TokenParser\TokenParserInterface', false); +class_exists('Twig_Parser'); +class_exists('Twig_Token'); diff --git a/vendor/twig/twig/lib/Twig/TokenStream.php b/vendor/twig/twig/lib/Twig/TokenStream.php index 27ca1a74e..e1bd7ca1e 100644 --- a/vendor/twig/twig/lib/Twig/TokenStream.php +++ b/vendor/twig/twig/lib/Twig/TokenStream.php @@ -192,3 +192,5 @@ class Twig_TokenStream return $this->source; } } + +class_alias('Twig_TokenStream', 'Twig\TokenStream', false); diff --git a/vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php b/vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php index 884cf055f..c7bf53be2 100644 --- a/vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php +++ b/vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php @@ -82,3 +82,5 @@ class Twig_Util_DeprecationCollector } } } + +class_alias('Twig_Util_DeprecationCollector', 'Twig\Util\DeprecationCollector', false); diff --git a/vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php b/vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php index 3fb893278..c8682335d 100644 --- a/vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php +++ b/vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php @@ -24,3 +24,5 @@ class Twig_Util_TemplateDirIterator extends IteratorIterator return (string) parent::key(); } } + +class_alias('Twig_Util_TemplateDirIterator', 'Twig\Util\TemplateDirIterator', false); diff --git a/vendor/twig/twig/phpunit.xml.dist b/vendor/twig/twig/phpunit.xml.dist new file mode 100644 index 000000000..d800c5769 --- /dev/null +++ b/vendor/twig/twig/phpunit.xml.dist @@ -0,0 +1,33 @@ + + + + + + ./test/Twig/ + + + + + + + + + + + + + + ./lib/Twig/ + + + diff --git a/vendor/twig/twig/src/Cache/CacheInterface.php b/vendor/twig/twig/src/Cache/CacheInterface.php new file mode 100644 index 000000000..2e35e3ba0 --- /dev/null +++ b/vendor/twig/twig/src/Cache/CacheInterface.php @@ -0,0 +1,11 @@ +assertFalse(class_exists('FooBarFoo'), '->autoload() does not try to load classes that does not begin with Twig'); + + $autoloader = new Twig_Autoloader(); + $this->assertNull($autoloader->autoload('Foo'), '->autoload() returns false if it is not able to load a class'); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php b/vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php new file mode 100644 index 000000000..aca68ce0b --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Cache/FilesystemTest.php @@ -0,0 +1,193 @@ +classname = '__Twig_Tests_Cache_FilesystemTest_Template_'.$nonce; + $this->directory = sys_get_temp_dir().'/twig-test'; + $this->cache = new Twig_Cache_Filesystem($this->directory); + } + + protected function tearDown() + { + if (file_exists($this->directory)) { + Twig_Tests_FilesystemHelper::removeDir($this->directory); + } + } + + public function testLoad() + { + $key = $this->directory.'/cache/cachefile.php'; + + $dir = dirname($key); + @mkdir($dir, 0777, true); + $this->assertTrue(is_dir($dir)); + $this->assertFalse(class_exists($this->classname, false)); + + $content = $this->generateSource(); + file_put_contents($key, $content); + + $this->cache->load($key); + + $this->assertTrue(class_exists($this->classname, false)); + } + + public function testLoadMissing() + { + $key = $this->directory.'/cache/cachefile.php'; + + $this->assertFalse(class_exists($this->classname, false)); + + $this->cache->load($key); + + $this->assertFalse(class_exists($this->classname, false)); + } + + public function testWrite() + { + $key = $this->directory.'/cache/cachefile.php'; + $content = $this->generateSource(); + + $this->assertFileNotExists($key); + $this->assertFileNotExists($this->directory); + + $this->cache->write($key, $content); + + $this->assertFileExists($this->directory); + $this->assertFileExists($key); + $this->assertSame(file_get_contents($key), $content); + } + + /** + * @expectedException RuntimeException + * @expectedExceptionMessage Unable to create the cache directory + */ + public function testWriteFailMkdir() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Read-only directories not possible on Windows.'); + } + + $key = $this->directory.'/cache/cachefile.php'; + $content = $this->generateSource(); + + $this->assertFileNotExists($key); + + // Create read-only root directory. + @mkdir($this->directory, 0555, true); + $this->assertTrue(is_dir($this->directory)); + + $this->cache->write($key, $content); + } + + /** + * @expectedException RuntimeException + * @expectedExceptionMessage Unable to write in the cache directory + */ + public function testWriteFailDirWritable() + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->markTestSkipped('Read-only directories not possible on Windows.'); + } + + $key = $this->directory.'/cache/cachefile.php'; + $content = $this->generateSource(); + + $this->assertFileNotExists($key); + + // Create root directory. + @mkdir($this->directory, 0777, true); + // Create read-only subdirectory. + @mkdir($this->directory.'/cache', 0555); + $this->assertTrue(is_dir($this->directory.'/cache')); + + $this->cache->write($key, $content); + } + + /** + * @expectedException RuntimeException + * @expectedExceptionMessage Failed to write cache file + */ + public function testWriteFailWriteFile() + { + $key = $this->directory.'/cache/cachefile.php'; + $content = $this->generateSource(); + + $this->assertFileNotExists($key); + + // Create a directory in the place of the cache file. + @mkdir($key, 0777, true); + $this->assertTrue(is_dir($key)); + + $this->cache->write($key, $content); + } + + public function testGetTimestamp() + { + $key = $this->directory.'/cache/cachefile.php'; + + $dir = dirname($key); + @mkdir($dir, 0777, true); + $this->assertTrue(is_dir($dir)); + + // Create the file with a specific modification time. + touch($key, 1234567890); + + $this->assertSame(1234567890, $this->cache->getTimestamp($key)); + } + + public function testGetTimestampMissingFile() + { + $key = $this->directory.'/cache/cachefile.php'; + $this->assertSame(0, $this->cache->getTimestamp($key)); + } + + /** + * Test file cache is tolerant towards trailing (back)slashes on the configured cache directory. + * + * @dataProvider provideDirectories + */ + public function testGenerateKey($expected, $input) + { + $cache = new Twig_Cache_Filesystem($input); + $this->assertRegExp($expected, $cache->generateKey('_test_', get_class($this))); + } + + public function provideDirectories() + { + $pattern = '#a/b/[a-zA-Z0-9]+/[a-zA-Z0-9]+.php$#'; + + return array( + array($pattern, 'a/b'), + array($pattern, 'a/b/'), + array($pattern, 'a/b\\'), + array($pattern, 'a/b\\/'), + array($pattern, 'a/b\\//'), + array('#/'.substr($pattern, 1), '/a/b'), + ); + } + + private function generateSource() + { + return strtr(' $this->classname, + )); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/CompilerTest.php b/vendor/twig/twig/test/Twig/Tests/CompilerTest.php new file mode 100644 index 000000000..da7f53315 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/CompilerTest.php @@ -0,0 +1,33 @@ +getMockBuilder('Twig_LoaderInterface')->getMock())); + + $locale = setlocale(LC_NUMERIC, 0); + if (false === $locale) { + $this->markTestSkipped('Your platform does not support locales.'); + } + + $required_locales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252'); + if (false === setlocale(LC_NUMERIC, $required_locales)) { + $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $required_locales)); + } + + $this->assertEquals('1.2', $compiler->repr(1.2)->getSource()); + $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0))); + + setlocale(LC_NUMERIC, $locale); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/ContainerRuntimeLoaderTest.php b/vendor/twig/twig/test/Twig/Tests/ContainerRuntimeLoaderTest.php new file mode 100644 index 000000000..558edf227 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/ContainerRuntimeLoaderTest.php @@ -0,0 +1,40 @@ +getMockBuilder('Psr\Container\ContainerInterface')->getMock(); + $container->expects($this->once())->method('has')->with('stdClass')->willReturn(true); + $container->expects($this->once())->method('get')->with('stdClass')->willReturn(new stdClass()); + + $loader = new Twig_ContainerRuntimeLoader($container); + + $this->assertInstanceOf('stdClass', $loader->load('stdClass')); + } + + /** + * @requires PHP 5.3 + */ + public function testLoadUnknownRuntimeReturnsNull() + { + $container = $this->getMockBuilder('Psr\Container\ContainerInterface')->getMock(); + $container->expects($this->once())->method('has')->with('Foo'); + $container->expects($this->never())->method('get'); + + $loader = new Twig_ContainerRuntimeLoader($container); + $this->assertNull($loader->load('Foo')); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/CustomExtensionTest.php b/vendor/twig/twig/test/Twig/Tests/CustomExtensionTest.php new file mode 100644 index 000000000..c706df264 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/CustomExtensionTest.php @@ -0,0 +1,93 @@ +expectException('InvalidArgumentException'); + $this->expectExceptionMessage($expectedExceptionMessage); + } else { + $this->setExpectedException('InvalidArgumentException', $expectedExceptionMessage); + } + + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $env->addExtension($extension); + $env->getUnaryOperators(); + } + + public function provideInvalidExtensions() + { + return array( + array(new InvalidOperatorExtension(new stdClass()), '"InvalidOperatorExtension::getOperators()" must return an array with operators, got "stdClass".'), + array(new InvalidOperatorExtension(array(1, 2, 3)), '"InvalidOperatorExtension::getOperators()" must return an array of 2 elements, got 3.'), + ); + } +} + +class InvalidOperatorExtension implements Twig_ExtensionInterface +{ + private $operators; + + public function __construct($operators) + { + $this->operators = $operators; + } + + public function initRuntime(Twig_Environment $environment) + { + } + + public function getTokenParsers() + { + return array(); + } + + public function getNodeVisitors() + { + return array(); + } + + public function getFilters() + { + return array(); + } + + public function getTests() + { + return array(); + } + + public function getFunctions() + { + return array(); + } + + public function getGlobals() + { + return array(); + } + + public function getOperators() + { + return $this->operators; + } + + public function getName() + { + return __CLASS__; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php b/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php new file mode 100644 index 000000000..5b07c40e8 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php @@ -0,0 +1,659 @@ +tokenize('{{ foo }}', 'foo'); + $this->assertEquals('{{ foo }}', $stream->getSource()); + $this->assertEquals('foo', $stream->getFilename()); + } + + /** + * @group legacy + */ + public function testLegacyCompileSourceSignature() + { + $loader = new Twig_Loader_Array(array('foo' => '{{ foo }}')); + $env = new Twig_Environment($loader); + $this->assertContains('getTemplateName', $env->compileSource('{{ foo }}', 'foo')); + } + + /** + * @expectedException LogicException + * @expectedExceptionMessage You must set a loader first. + * @group legacy + */ + public function testRenderNoLoader() + { + $env = new Twig_Environment(); + $env->render('test'); + } + + public function testAutoescapeOption() + { + $loader = new Twig_Loader_Array(array( + 'html' => '{{ foo }} {{ foo }}', + 'js' => '{{ bar }} {{ bar }}', + )); + + $twig = new Twig_Environment($loader, array( + 'debug' => true, + 'cache' => false, + 'autoescape' => array($this, 'escapingStrategyCallback'), + )); + + $this->assertEquals('foo<br/ > foo<br/ >', $twig->render('html', array('foo' => 'foo
    '))); + $this->assertEquals('foo\x3Cbr\x2F\x20\x3E foo\x3Cbr\x2F\x20\x3E', $twig->render('js', array('bar' => 'foo
    '))); + } + + public function escapingStrategyCallback($name) + { + return $name; + } + + public function testGlobals() + { + // to be removed in 2.0 + $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock(); + //$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock(); + $loader->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('', ''))); + + // globals can be added after calling getGlobals + + $twig = new Twig_Environment($loader); + $twig->addGlobal('foo', 'foo'); + $twig->getGlobals(); + $twig->addGlobal('foo', 'bar'); + $globals = $twig->getGlobals(); + $this->assertEquals('bar', $globals['foo']); + + // globals can be modified after a template has been loaded + $twig = new Twig_Environment($loader); + $twig->addGlobal('foo', 'foo'); + $twig->getGlobals(); + $twig->loadTemplate('index'); + $twig->addGlobal('foo', 'bar'); + $globals = $twig->getGlobals(); + $this->assertEquals('bar', $globals['foo']); + + // globals can be modified after extensions init + $twig = new Twig_Environment($loader); + $twig->addGlobal('foo', 'foo'); + $twig->getGlobals(); + $twig->getFunctions(); + $twig->addGlobal('foo', 'bar'); + $globals = $twig->getGlobals(); + $this->assertEquals('bar', $globals['foo']); + + // globals can be modified after extensions and a template has been loaded + $arrayLoader = new Twig_Loader_Array(array('index' => '{{foo}}')); + $twig = new Twig_Environment($arrayLoader); + $twig->addGlobal('foo', 'foo'); + $twig->getGlobals(); + $twig->getFunctions(); + $twig->loadTemplate('index'); + $twig->addGlobal('foo', 'bar'); + $globals = $twig->getGlobals(); + $this->assertEquals('bar', $globals['foo']); + + $twig = new Twig_Environment($arrayLoader); + $twig->getGlobals(); + $twig->addGlobal('foo', 'bar'); + $template = $twig->loadTemplate('index'); + $this->assertEquals('bar', $template->render(array())); + + /* to be uncomment in Twig 2.0 + // globals cannot be added after a template has been loaded + $twig = new Twig_Environment($loader); + $twig->addGlobal('foo', 'foo'); + $twig->getGlobals(); + $twig->loadTemplate('index'); + try { + $twig->addGlobal('bar', 'bar'); + $this->fail(); + } catch (LogicException $e) { + $this->assertFalse(array_key_exists('bar', $twig->getGlobals())); + } + + // globals cannot be added after extensions init + $twig = new Twig_Environment($loader); + $twig->addGlobal('foo', 'foo'); + $twig->getGlobals(); + $twig->getFunctions(); + try { + $twig->addGlobal('bar', 'bar'); + $this->fail(); + } catch (LogicException $e) { + $this->assertFalse(array_key_exists('bar', $twig->getGlobals())); + } + + // globals cannot be added after extensions and a template has been loaded + $twig = new Twig_Environment($loader); + $twig->addGlobal('foo', 'foo'); + $twig->getGlobals(); + $twig->getFunctions(); + $twig->loadTemplate('index'); + try { + $twig->addGlobal('bar', 'bar'); + $this->fail(); + } catch (LogicException $e) { + $this->assertFalse(array_key_exists('bar', $twig->getGlobals())); + } + + // test adding globals after a template has been loaded without call to getGlobals + $twig = new Twig_Environment($loader); + $twig->loadTemplate('index'); + try { + $twig->addGlobal('bar', 'bar'); + $this->fail(); + } catch (LogicException $e) { + $this->assertFalse(array_key_exists('bar', $twig->getGlobals())); + } + */ + } + + public function testExtensionsAreNotInitializedWhenRenderingACompiledTemplate() + { + $cache = new Twig_Cache_Filesystem($dir = sys_get_temp_dir().'/twig'); + $options = array('cache' => $cache, 'auto_reload' => false, 'debug' => false); + + // force compilation + $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{ foo }}')), $options); + + $key = $cache->generateKey('index', $twig->getTemplateClass('index')); + $cache->write($key, $twig->compileSource(new Twig_Source('{{ foo }}', 'index'))); + + // check that extensions won't be initialized when rendering a template that is already in the cache + $twig = $this + ->getMockBuilder('Twig_Environment') + ->setConstructorArgs(array($loader, $options)) + ->setMethods(array('initExtensions')) + ->getMock() + ; + + $twig->expects($this->never())->method('initExtensions'); + + // render template + $output = $twig->render('index', array('foo' => 'bar')); + $this->assertEquals('bar', $output); + + Twig_Tests_FilesystemHelper::removeDir($dir); + } + + public function testAutoReloadCacheMiss() + { + $templateName = __FUNCTION__; + $templateContent = __FUNCTION__; + + $cache = $this->getMockBuilder('Twig_CacheInterface')->getMock(); + $loader = $this->getMockLoader($templateName, $templateContent); + $twig = new Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => true, 'debug' => false)); + + // Cache miss: getTimestamp returns 0 and as a result the load() is + // skipped. + $cache->expects($this->once()) + ->method('generateKey') + ->will($this->returnValue('key')); + $cache->expects($this->once()) + ->method('getTimestamp') + ->will($this->returnValue(0)); + $loader->expects($this->never()) + ->method('isFresh'); + $cache->expects($this->once()) + ->method('write'); + $cache->expects($this->once()) + ->method('load'); + + $twig->loadTemplate($templateName); + } + + public function testAutoReloadCacheHit() + { + $templateName = __FUNCTION__; + $templateContent = __FUNCTION__; + + $cache = $this->getMockBuilder('Twig_CacheInterface')->getMock(); + $loader = $this->getMockLoader($templateName, $templateContent); + $twig = new Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => true, 'debug' => false)); + + $now = time(); + + // Cache hit: getTimestamp returns something > extension timestamps and + // the loader returns true for isFresh(). + $cache->expects($this->once()) + ->method('generateKey') + ->will($this->returnValue('key')); + $cache->expects($this->once()) + ->method('getTimestamp') + ->will($this->returnValue($now)); + $loader->expects($this->once()) + ->method('isFresh') + ->will($this->returnValue(true)); + $cache->expects($this->atLeastOnce()) + ->method('load'); + + $twig->loadTemplate($templateName); + } + + public function testAutoReloadOutdatedCacheHit() + { + $templateName = __FUNCTION__; + $templateContent = __FUNCTION__; + + $cache = $this->getMockBuilder('Twig_CacheInterface')->getMock(); + $loader = $this->getMockLoader($templateName, $templateContent); + $twig = new Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => true, 'debug' => false)); + + $now = time(); + + $cache->expects($this->once()) + ->method('generateKey') + ->will($this->returnValue('key')); + $cache->expects($this->once()) + ->method('getTimestamp') + ->will($this->returnValue($now)); + $loader->expects($this->once()) + ->method('isFresh') + ->will($this->returnValue(false)); + $cache->expects($this->once()) + ->method('write'); + $cache->expects($this->once()) + ->method('load'); + + $twig->loadTemplate($templateName); + } + + /** + * @group legacy + */ + public function testHasGetExtensionWithDynamicName() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + + $ext1 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext1'); + $ext2 = new Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName('ext2'); + $twig->addExtension($ext1); + $twig->addExtension($ext2); + + $this->assertTrue($twig->hasExtension('ext1')); + $this->assertTrue($twig->hasExtension('ext2')); + + $this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName')); + + $this->assertSame($ext1, $twig->getExtension('ext1')); + $this->assertSame($ext2, $twig->getExtension('ext2')); + } + + public function testHasGetExtensionByClassName() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->addExtension($ext = new Twig_Tests_EnvironmentTest_Extension()); + $this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension')); + $this->assertTrue($twig->hasExtension('\Twig_Tests_EnvironmentTest_Extension')); + + $this->assertSame($ext, $twig->getExtension('Twig_Tests_EnvironmentTest_Extension')); + $this->assertSame($ext, $twig->getExtension('\Twig_Tests_EnvironmentTest_Extension')); + + $this->assertTrue($twig->hasExtension('Twig\Tests\EnvironmentTest\Extension')); + $this->assertSame($ext, $twig->getExtension('Twig\Tests\EnvironmentTest\Extension')); + } + + public function testAddExtension() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension()); + + $this->assertArrayHasKey('test', $twig->getTags()); + $this->assertArrayHasKey('foo_filter', $twig->getFilters()); + $this->assertArrayHasKey('foo_function', $twig->getFunctions()); + $this->assertArrayHasKey('foo_test', $twig->getTests()); + $this->assertArrayHasKey('foo_unary', $twig->getUnaryOperators()); + $this->assertArrayHasKey('foo_binary', $twig->getBinaryOperators()); + $this->assertArrayHasKey('foo_global', $twig->getGlobals()); + $visitors = $twig->getNodeVisitors(); + $found = false; + foreach ($visitors as $visitor) { + if ($visitor instanceof Twig_Tests_EnvironmentTest_NodeVisitor) { + $found = true; + } + } + $this->assertTrue($found); + } + + /** + * @requires PHP 5.3 + */ + public function testAddExtensionWithDeprecatedGetGlobals() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithGlobals()); + + $this->deprecations = array(); + set_error_handler(array($this, 'handleError')); + + $this->assertArrayHasKey('foo_global', $twig->getGlobals()); + + $this->assertCount(1, $this->deprecations); + $this->assertContains('Defining the getGlobals() method in the "Twig_Tests_EnvironmentTest_Extension_WithGlobals" extension ', $this->deprecations[0]); + + restore_error_handler(); + } + + /** + * @group legacy + */ + public function testRemoveExtension() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName()); + $twig->removeExtension('environment_test'); + + $this->assertArrayNotHasKey('test', $twig->getTags()); + $this->assertArrayNotHasKey('foo_filter', $twig->getFilters()); + $this->assertArrayNotHasKey('foo_function', $twig->getFunctions()); + $this->assertArrayNotHasKey('foo_test', $twig->getTests()); + $this->assertArrayNotHasKey('foo_unary', $twig->getUnaryOperators()); + $this->assertArrayNotHasKey('foo_binary', $twig->getBinaryOperators()); + $this->assertArrayNotHasKey('foo_global', $twig->getGlobals()); + $this->assertCount(2, $twig->getNodeVisitors()); + } + + public function testAddMockExtension() + { + // should be replaced by the following in 2.0 (this current code is just to avoid a dep notice) + // $extension = $this->getMockBuilder('Twig_Extension')->getMock(); + $extension = eval(<< 'hey')); + + $twig = new Twig_Environment($loader); + $twig->addExtension($extension); + + $this->assertInstanceOf('Twig_ExtensionInterface', $twig->getExtension(get_class($extension))); + $this->assertTrue($twig->isTemplateFresh('page', time())); + } + + public function testInitRuntimeWithAnExtensionUsingInitRuntimeNoDeprecation() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime()); + $twig->initRuntime(); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any deprecations + $this->addToAssertionCount(1); + } + + /** + * @requires PHP 5.3 + */ + public function testInitRuntimeWithAnExtensionUsingInitRuntimeDeprecation() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime()); + + $this->deprecations = array(); + set_error_handler(array($this, 'handleError')); + + $twig->initRuntime(); + + $this->assertCount(1, $this->deprecations); + $this->assertContains('Defining the initRuntime() method in the "Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime" extension is deprecated since version 1.23.', $this->deprecations[0]); + + restore_error_handler(); + } + + public function handleError($type, $msg) + { + if (E_USER_DEPRECATED === $type) { + $this->deprecations[] = $msg; + } + } + + /** + * @requires PHP 5.3 + */ + public function testOverrideExtension() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime()); + + $this->deprecations = array(); + set_error_handler(array($this, 'handleError')); + + $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName()); + $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName()); + + $this->assertCount(1, $this->deprecations); + $this->assertContains('The possibility to register the same extension twice', $this->deprecations[0]); + + restore_error_handler(); + } + + public function testAddRuntimeLoader() + { + $runtimeLoader = $this->getMockBuilder('Twig_RuntimeLoaderInterface')->getMock(); + $runtimeLoader->expects($this->any())->method('load')->will($this->returnValue(new Twig_Tests_EnvironmentTest_Runtime())); + + $loader = new Twig_Loader_Array(array( + 'func_array' => '{{ from_runtime_array("foo") }}', + 'func_array_default' => '{{ from_runtime_array() }}', + 'func_array_named_args' => '{{ from_runtime_array(name="foo") }}', + 'func_string' => '{{ from_runtime_string("foo") }}', + 'func_string_default' => '{{ from_runtime_string() }}', + 'func_string_named_args' => '{{ from_runtime_string(name="foo") }}', + )); + + $twig = new Twig_Environment($loader); + $twig->addExtension(new Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime()); + $twig->addRuntimeLoader($runtimeLoader); + + $this->assertEquals('foo', $twig->render('func_array')); + $this->assertEquals('bar', $twig->render('func_array_default')); + $this->assertEquals('foo', $twig->render('func_array_named_args')); + $this->assertEquals('foo', $twig->render('func_string')); + $this->assertEquals('bar', $twig->render('func_string_default')); + $this->assertEquals('foo', $twig->render('func_string_named_args')); + } + + protected function getMockLoader($templateName, $templateContent) + { + // to be removed in 2.0 + $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock(); + //$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock(); + $loader->expects($this->any()) + ->method('getSourceContext') + ->with($templateName) + ->will($this->returnValue(new Twig_Source($templateContent, $templateName))); + $loader->expects($this->any()) + ->method('getCacheKey') + ->with($templateName) + ->will($this->returnValue($templateName)); + + return $loader; + } +} + +class Twig_Tests_EnvironmentTest_Extension_WithGlobals extends Twig_Extension +{ + public function getGlobals() + { + return array( + 'foo_global' => 'foo_global', + ); + } +} + +class Twig_Tests_EnvironmentTest_Extension extends Twig_Extension implements Twig_Extension_GlobalsInterface +{ + public function getTokenParsers() + { + return array( + new Twig_Tests_EnvironmentTest_TokenParser(), + ); + } + + public function getNodeVisitors() + { + return array( + new Twig_Tests_EnvironmentTest_NodeVisitor(), + ); + } + + public function getFilters() + { + return array( + new Twig_SimpleFilter('foo_filter', 'foo_filter'), + ); + } + + public function getTests() + { + return array( + new Twig_SimpleTest('foo_test', 'foo_test'), + ); + } + + public function getFunctions() + { + return array( + new Twig_SimpleFunction('foo_function', 'foo_function'), + ); + } + + public function getOperators() + { + return array( + array('foo_unary' => array()), + array('foo_binary' => array()), + ); + } + + public function getGlobals() + { + return array( + 'foo_global' => 'foo_global', + ); + } +} +class_alias('Twig_Tests_EnvironmentTest_Extension', 'Twig\Tests\EnvironmentTest\Extension', false); + +class Twig_Tests_EnvironmentTest_Extension_WithDeprecatedName extends Twig_Extension +{ + public function getName() + { + return 'environment_test'; + } +} + +class Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName extends Twig_Extension +{ + private $name; + + public function __construct($name) + { + $this->name = $name; + } + + public function getName() + { + return $this->name; + } +} + +class Twig_Tests_EnvironmentTest_TokenParser extends Twig_TokenParser +{ + public function parse(Twig_Token $token) + { + } + + public function getTag() + { + return 'test'; + } +} + +class Twig_Tests_EnvironmentTest_NodeVisitor implements Twig_NodeVisitorInterface +{ + public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) + { + return $node; + } + + public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) + { + return $node; + } + + public function getPriority() + { + return 0; + } +} + +class Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime extends Twig_Extension +{ + public function initRuntime(Twig_Environment $env) + { + } +} + +class Twig_Tests_EnvironmentTest_ExtensionWithoutDeprecationInitRuntime extends Twig_Extension implements Twig_Extension_InitRuntimeInterface +{ + public function initRuntime(Twig_Environment $env) + { + } +} + +class Twig_Tests_EnvironmentTest_ExtensionWithoutRuntime extends Twig_Extension +{ + public function getFunctions() + { + return array( + new Twig_SimpleFunction('from_runtime_array', array('Twig_Tests_EnvironmentTest_Runtime', 'fromRuntime')), + new Twig_SimpleFunction('from_runtime_string', 'Twig_Tests_EnvironmentTest_Runtime::fromRuntime'), + ); + } + + public function getName() + { + return 'from_runtime'; + } +} + +class Twig_Tests_EnvironmentTest_Runtime +{ + public function fromRuntime($name = 'bar') + { + return $name; + } +} + +// to be removed in 2.0 +interface Twig_EnvironmentTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface +{ +} diff --git a/vendor/twig/twig/test/Twig/Tests/ErrorTest.php b/vendor/twig/twig/test/Twig/Tests/ErrorTest.php new file mode 100644 index 000000000..b0eeca2e6 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/ErrorTest.php @@ -0,0 +1,211 @@ +setSourceContext(new Twig_Source('', new SplFileInfo(__FILE__))); + + $this->assertContains('test'.DIRECTORY_SEPARATOR.'Twig'.DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage()); + } + + public function testErrorWithArrayFilename() + { + $error = new Twig_Error('foo'); + $error->setSourceContext(new Twig_Source('', array('foo' => 'bar'))); + + $this->assertEquals('foo in {"foo":"bar"}', $error->getMessage()); + } + + public function testTwigExceptionGuessWithMissingVarAndArrayLoader() + { + $loader = new Twig_Loader_Array(array( + 'base.html' => '{% block content %}{% endblock %}', + 'index.html' => << true, 'debug' => true, 'cache' => false)); + + $template = $twig->loadTemplate('index.html'); + try { + $template->render(array()); + + $this->fail(); + } catch (Twig_Error_Runtime $e) { + $this->assertEquals('Variable "foo" does not exist in "index.html" at line 3.', $e->getMessage()); + $this->assertEquals(3, $e->getTemplateLine()); + $this->assertEquals('index.html', $e->getSourceContext()->getName()); + } + } + + public function testTwigExceptionGuessWithExceptionAndArrayLoader() + { + $loader = new Twig_Loader_Array(array( + 'base.html' => '{% block content %}{% endblock %}', + 'index.html' => << true, 'debug' => true, 'cache' => false)); + + $template = $twig->loadTemplate('index.html'); + try { + $template->render(array('foo' => new Twig_Tests_ErrorTest_Foo())); + + $this->fail(); + } catch (Twig_Error_Runtime $e) { + $this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...") in "index.html" at line 3.', $e->getMessage()); + $this->assertEquals(3, $e->getTemplateLine()); + $this->assertEquals('index.html', $e->getSourceContext()->getName()); + } + } + + public function testTwigExceptionGuessWithMissingVarAndFilesystemLoader() + { + $loader = new Twig_Loader_Filesystem(dirname(__FILE__).'/Fixtures/errors'); + $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => false)); + + $template = $twig->loadTemplate('index.html'); + try { + $template->render(array()); + + $this->fail(); + } catch (Twig_Error_Runtime $e) { + $this->assertEquals('Variable "foo" does not exist.', $e->getMessage()); + $this->assertEquals(3, $e->getTemplateLine()); + $this->assertEquals('index.html', $e->getSourceContext()->getName()); + $this->assertEquals(3, $e->getLine()); + $this->assertEquals(strtr(dirname(__FILE__).'/Fixtures/errors/index.html', '/', DIRECTORY_SEPARATOR), $e->getFile()); + } + } + + public function testTwigExceptionGuessWithExceptionAndFilesystemLoader() + { + $loader = new Twig_Loader_Filesystem(dirname(__FILE__).'/Fixtures/errors'); + $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => false)); + + $template = $twig->loadTemplate('index.html'); + try { + $template->render(array('foo' => new Twig_Tests_ErrorTest_Foo())); + + $this->fail(); + } catch (Twig_Error_Runtime $e) { + $this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...").', $e->getMessage()); + $this->assertEquals(3, $e->getTemplateLine()); + $this->assertEquals('index.html', $e->getSourceContext()->getName()); + $this->assertEquals(3, $e->getLine()); + $this->assertEquals(strtr(dirname(__FILE__).'/Fixtures/errors/index.html', '/', DIRECTORY_SEPARATOR), $e->getFile()); + } + } + + /** + * @dataProvider getErroredTemplates + */ + public function testTwigExceptionAddsFileAndLine($templates, $name, $line) + { + $loader = new Twig_Loader_Array($templates); + $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => false)); + + $template = $twig->loadTemplate('index'); + + try { + $template->render(array()); + + $this->fail(); + } catch (Twig_Error_Runtime $e) { + $this->assertEquals(sprintf('Variable "foo" does not exist in "%s" at line %d.', $name, $line), $e->getMessage()); + $this->assertEquals($line, $e->getTemplateLine()); + $this->assertEquals($name, $e->getSourceContext()->getName()); + } + + try { + $template->render(array('foo' => new Twig_Tests_ErrorTest_Foo())); + + $this->fail(); + } catch (Twig_Error_Runtime $e) { + $this->assertEquals(sprintf('An exception has been thrown during the rendering of a template ("Runtime error...") in "%s" at line %d.', $name, $line), $e->getMessage()); + $this->assertEquals($line, $e->getTemplateLine()); + $this->assertEquals($name, $e->getSourceContext()->getName()); + } + } + + public function getErroredTemplates() + { + return array( + // error occurs in a template + array( + array( + 'index' => "\n\n{{ foo.bar }}\n\n\n{{ 'foo' }}", + ), + 'index', 3, + ), + + // error occurs in an included template + array( + array( + 'index' => "{% include 'partial' %}", + 'partial' => '{{ foo.bar }}', + ), + 'partial', 1, + ), + + // error occurs in a parent block when called via parent() + array( + array( + 'index' => "{% extends 'base' %} + {% block content %} + {{ parent() }} + {% endblock %}", + 'base' => '{% block content %}{{ foo.bar }}{% endblock %}', + ), + 'base', 1, + ), + + // error occurs in a block from the child + array( + array( + 'index' => "{% extends 'base' %} + {% block content %} + {{ foo.bar }} + {% endblock %} + {% block foo %} + {{ foo.bar }} + {% endblock %}", + 'base' => '{% block content %}{% endblock %}', + ), + 'index', 3, + ), + ); + } +} + +class Twig_Tests_ErrorTest_Foo +{ + public function bar() + { + throw new Exception('Runtime error...'); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php b/vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php new file mode 100644 index 000000000..54f2ecc96 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/ExpressionParserTest.php @@ -0,0 +1,377 @@ +getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source($template, 'index'))); + } + + public function getFailingTestsForAssignment() + { + return array( + array('{% set false = "foo" %}'), + array('{% set FALSE = "foo" %}'), + array('{% set true = "foo" %}'), + array('{% set TRUE = "foo" %}'), + array('{% set none = "foo" %}'), + array('{% set NONE = "foo" %}'), + array('{% set null = "foo" %}'), + array('{% set NULL = "foo" %}'), + array('{% set 3 = "foo" %}'), + array('{% set 1 + 2 = "foo" %}'), + array('{% set "bar" = "foo" %}'), + array('{% set %}{% endset %}'), + ); + } + + /** + * @dataProvider getTestsForArray + */ + public function testArrayExpression($template, $expected) + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $stream = $env->tokenize(new Twig_Source($template, '')); + $parser = new Twig_Parser($env); + + $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr')); + } + + /** + * @expectedException Twig_Error_Syntax + * @dataProvider getFailingTestsForArray + */ + public function testArraySyntaxError($template) + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source($template, 'index'))); + } + + public function getFailingTestsForArray() + { + return array( + array('{{ [1, "a": "b"] }}'), + array('{{ {"a": "b", 2} }}'), + ); + } + + public function getTestsForArray() + { + return array( + // simple array + array('{{ [1, 2] }}', new Twig_Node_Expression_Array(array( + new Twig_Node_Expression_Constant(0, 1), + new Twig_Node_Expression_Constant(1, 1), + + new Twig_Node_Expression_Constant(1, 1), + new Twig_Node_Expression_Constant(2, 1), + ), 1), + ), + + // array with trailing , + array('{{ [1, 2, ] }}', new Twig_Node_Expression_Array(array( + new Twig_Node_Expression_Constant(0, 1), + new Twig_Node_Expression_Constant(1, 1), + + new Twig_Node_Expression_Constant(1, 1), + new Twig_Node_Expression_Constant(2, 1), + ), 1), + ), + + // simple hash + array('{{ {"a": "b", "b": "c"} }}', new Twig_Node_Expression_Array(array( + new Twig_Node_Expression_Constant('a', 1), + new Twig_Node_Expression_Constant('b', 1), + + new Twig_Node_Expression_Constant('b', 1), + new Twig_Node_Expression_Constant('c', 1), + ), 1), + ), + + // hash with trailing , + array('{{ {"a": "b", "b": "c", } }}', new Twig_Node_Expression_Array(array( + new Twig_Node_Expression_Constant('a', 1), + new Twig_Node_Expression_Constant('b', 1), + + new Twig_Node_Expression_Constant('b', 1), + new Twig_Node_Expression_Constant('c', 1), + ), 1), + ), + + // hash in an array + array('{{ [1, {"a": "b", "b": "c"}] }}', new Twig_Node_Expression_Array(array( + new Twig_Node_Expression_Constant(0, 1), + new Twig_Node_Expression_Constant(1, 1), + + new Twig_Node_Expression_Constant(1, 1), + new Twig_Node_Expression_Array(array( + new Twig_Node_Expression_Constant('a', 1), + new Twig_Node_Expression_Constant('b', 1), + + new Twig_Node_Expression_Constant('b', 1), + new Twig_Node_Expression_Constant('c', 1), + ), 1), + ), 1), + ), + + // array in a hash + array('{{ {"a": [1, 2], "b": "c"} }}', new Twig_Node_Expression_Array(array( + new Twig_Node_Expression_Constant('a', 1), + new Twig_Node_Expression_Array(array( + new Twig_Node_Expression_Constant(0, 1), + new Twig_Node_Expression_Constant(1, 1), + + new Twig_Node_Expression_Constant(1, 1), + new Twig_Node_Expression_Constant(2, 1), + ), 1), + new Twig_Node_Expression_Constant('b', 1), + new Twig_Node_Expression_Constant('c', 1), + ), 1), + ), + ); + } + + /** + * @expectedException Twig_Error_Syntax + */ + public function testStringExpressionDoesNotConcatenateTwoConsecutiveStrings() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0)); + $stream = $env->tokenize(new Twig_Source('{{ "a" "b" }}', 'index')); + $parser = new Twig_Parser($env); + + $parser->parse($stream); + } + + /** + * @dataProvider getTestsForString + */ + public function testStringExpression($template, $expected) + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0)); + $stream = $env->tokenize(new Twig_Source($template, '')); + $parser = new Twig_Parser($env); + + $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr')); + } + + public function getTestsForString() + { + return array( + array( + '{{ "foo" }}', new Twig_Node_Expression_Constant('foo', 1), + ), + array( + '{{ "foo #{bar}" }}', new Twig_Node_Expression_Binary_Concat( + new Twig_Node_Expression_Constant('foo ', 1), + new Twig_Node_Expression_Name('bar', 1), + 1 + ), + ), + array( + '{{ "foo #{bar} baz" }}', new Twig_Node_Expression_Binary_Concat( + new Twig_Node_Expression_Binary_Concat( + new Twig_Node_Expression_Constant('foo ', 1), + new Twig_Node_Expression_Name('bar', 1), + 1 + ), + new Twig_Node_Expression_Constant(' baz', 1), + 1 + ), + ), + + array( + '{{ "foo #{"foo #{bar} baz"} baz" }}', new Twig_Node_Expression_Binary_Concat( + new Twig_Node_Expression_Binary_Concat( + new Twig_Node_Expression_Constant('foo ', 1), + new Twig_Node_Expression_Binary_Concat( + new Twig_Node_Expression_Binary_Concat( + new Twig_Node_Expression_Constant('foo ', 1), + new Twig_Node_Expression_Name('bar', 1), + 1 + ), + new Twig_Node_Expression_Constant(' baz', 1), + 1 + ), + 1 + ), + new Twig_Node_Expression_Constant(' baz', 1), + 1 + ), + ), + ); + } + + /** + * @expectedException Twig_Error_Syntax + */ + public function testAttributeCallDoesNotSupportNamedArguments() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source('{{ foo.bar(name="Foo") }}', 'index'))); + } + + /** + * @expectedException Twig_Error_Syntax + */ + public function testMacroCallDoesNotSupportNamedArguments() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source('{% from _self import foo %}{% macro foo() %}{% endmacro %}{{ foo(name="Foo") }}', 'index'))); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage An argument must be a name. Unexpected token "string" of value "a" ("name" expected) in "index" at line 1. + */ + public function testMacroDefinitionDoesNotSupportNonNameVariableName() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source('{% macro foo("a") %}{% endmacro %}', 'index'))); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage A default value for an argument must be a constant (a boolean, a string, a number, or an array) in "index" at line 1 + * @dataProvider getMacroDefinitionDoesNotSupportNonConstantDefaultValues + */ + public function testMacroDefinitionDoesNotSupportNonConstantDefaultValues($template) + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source($template, 'index'))); + } + + public function getMacroDefinitionDoesNotSupportNonConstantDefaultValues() + { + return array( + array('{% macro foo(name = "a #{foo} a") %}{% endmacro %}'), + array('{% macro foo(name = [["b", "a #{foo} a"]]) %}{% endmacro %}'), + ); + } + + /** + * @dataProvider getMacroDefinitionSupportsConstantDefaultValues + */ + public function testMacroDefinitionSupportsConstantDefaultValues($template) + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source($template, 'index'))); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + public function getMacroDefinitionSupportsConstantDefaultValues() + { + return array( + array('{% macro foo(name = "aa") %}{% endmacro %}'), + array('{% macro foo(name = 12) %}{% endmacro %}'), + array('{% macro foo(name = true) %}{% endmacro %}'), + array('{% macro foo(name = ["a"]) %}{% endmacro %}'), + array('{% macro foo(name = [["a"]]) %}{% endmacro %}'), + array('{% macro foo(name = {a: "a"}) %}{% endmacro %}'), + array('{% macro foo(name = {a: {b: "a"}}) %}{% endmacro %}'), + ); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown "cycl" function. Did you mean "cycle" in "index" at line 1? + */ + public function testUnknownFunction() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source('{{ cycl() }}', 'index'))); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown "foobar" function in "index" at line 1. + */ + public function testUnknownFunctionWithoutSuggestions() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source('{{ foobar() }}', 'index'))); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown "lowe" filter. Did you mean "lower" in "index" at line 1? + */ + public function testUnknownFilter() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source('{{ 1|lowe }}', 'index'))); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown "foobar" filter in "index" at line 1. + */ + public function testUnknownFilterWithoutSuggestions() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source('{{ 1|foobar }}', 'index'))); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown "nul" test. Did you mean "null" in "index" at line 1 + */ + public function testUnknownTest() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + $stream = $env->tokenize(new Twig_Source('{{ 1 is nul }}', 'index')); + $parser->parse($stream); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown "foobar" test in "index" at line 1. + */ + public function testUnknownTestWithoutSuggestions() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $parser = new Twig_Parser($env); + + $parser->parse($env->tokenize(new Twig_Source('{{ 1 is foobar }}', 'index'))); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php b/vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php new file mode 100644 index 000000000..c5429d487 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Extension/CoreTest.php @@ -0,0 +1,355 @@ +getMockBuilder('Twig_LoaderInterface')->getMock()); + + for ($i = 0; $i < 100; ++$i) { + $this->assertTrue(in_array(twig_random($env, $value), $expectedInArray, true)); // assertContains() would not consider the type + } + } + + public function getRandomFunctionTestData() + { + return array( + array(// array + array('apple', 'orange', 'citrus'), + array('apple', 'orange', 'citrus'), + ), + array(// Traversable + new ArrayObject(array('apple', 'orange', 'citrus')), + array('apple', 'orange', 'citrus'), + ), + array(// unicode string + 'Ä€é', + array('Ä', '€', 'é'), + ), + array(// numeric but string + '123', + array('1', '2', '3'), + ), + array(// integer + 5, + range(0, 5, 1), + ), + array(// float + 5.9, + range(0, 5, 1), + ), + array(// negative + -2, + array(0, -1, -2), + ), + ); + } + + public function testRandomFunctionWithoutParameter() + { + $max = mt_getrandmax(); + + for ($i = 0; $i < 100; ++$i) { + $val = twig_random(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $this->assertTrue(is_int($val) && $val >= 0 && $val <= $max); + } + } + + public function testRandomFunctionReturnsAsIs() + { + $this->assertSame('', twig_random(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()), '')); + $this->assertSame('', twig_random(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('charset' => null)), '')); + + $instance = new stdClass(); + $this->assertSame($instance, twig_random(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()), $instance)); + } + + /** + * @expectedException Twig_Error_Runtime + */ + public function testRandomFunctionOfEmptyArrayThrowsException() + { + twig_random(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()), array()); + } + + public function testRandomFunctionOnNonUTF8String() + { + if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) { + $this->markTestSkipped('needs iconv or mbstring'); + } + + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->setCharset('ISO-8859-1'); + + $text = twig_convert_encoding('Äé', 'ISO-8859-1', 'UTF-8'); + for ($i = 0; $i < 30; ++$i) { + $rand = twig_random($twig, $text); + $this->assertTrue(in_array(twig_convert_encoding($rand, 'UTF-8', 'ISO-8859-1'), array('Ä', 'é'), true)); + } + } + + public function testReverseFilterOnNonUTF8String() + { + if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) { + $this->markTestSkipped('needs iconv or mbstring'); + } + + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->setCharset('ISO-8859-1'); + + $input = twig_convert_encoding('Äé', 'ISO-8859-1', 'UTF-8'); + $output = twig_convert_encoding(twig_reverse_filter($twig, $input), 'UTF-8', 'ISO-8859-1'); + + $this->assertEquals($output, 'éÄ'); + } + + /** + * @dataProvider provideCustomEscaperCases + */ + public function testCustomEscaper($expected, $string, $strategy) + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->getExtension('Twig_Extension_Core')->setEscaper('foo', 'foo_escaper_for_test'); + + $this->assertSame($expected, twig_escape_filter($twig, $string, $strategy)); + } + + public function provideCustomEscaperCases() + { + return array( + array('fooUTF-8', 'foo', 'foo'), + array('UTF-8', null, 'foo'), + array('42UTF-8', 42, 'foo'), + ); + } + + /** + * @expectedException Twig_Error_Runtime + */ + public function testUnknownCustomEscaper() + { + twig_escape_filter(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()), 'foo', 'bar'); + } + + /** + * @dataProvider provideTwigFirstCases + */ + public function testTwigFirst($expected, $input) + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $this->assertSame($expected, twig_first($twig, $input)); + } + + public function provideTwigFirstCases() + { + $i = array(1 => 'a', 2 => 'b', 3 => 'c'); + + return array( + array('a', 'abc'), + array(1, array(1, 2, 3)), + array('', null), + array('', ''), + array('a', new CoreTestIterator($i, array_keys($i), true, 3)), + ); + } + + /** + * @dataProvider provideTwigLastCases + */ + public function testTwigLast($expected, $input) + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $this->assertSame($expected, twig_last($twig, $input)); + } + + public function provideTwigLastCases() + { + $i = array(1 => 'a', 2 => 'b', 3 => 'c'); + + return array( + array('c', 'abc'), + array(3, array(1, 2, 3)), + array('', null), + array('', ''), + array('c', new CoreTestIterator($i, array_keys($i), true)), + ); + } + + /** + * @dataProvider provideArrayKeyCases + */ + public function testArrayKeysFilter(array $expected, $input) + { + $this->assertSame($expected, twig_get_array_keys_filter($input)); + } + + public function provideArrayKeyCases() + { + $array = array('a' => 'a1', 'b' => 'b1', 'c' => 'c1'); + $keys = array_keys($array); + + return array( + array($keys, $array), + array($keys, new CoreTestIterator($array, $keys)), + array($keys, new CoreTestIteratorAggregate($array, $keys)), + array($keys, new CoreTestIteratorAggregateAggregate($array, $keys)), + array(array(), null), + array(array('a'), new SimpleXMLElement('')), + ); + } + + /** + * @dataProvider provideInFilterCases + */ + public function testInFilter($expected, $value, $compare) + { + $this->assertSame($expected, twig_in_filter($value, $compare)); + } + + public function provideInFilterCases() + { + $array = array(1, 2, 'a' => 3, 5, 6, 7); + $keys = array_keys($array); + + return array( + array(true, 1, $array), + array(true, '3', $array), + array(true, '3', 'abc3def'), + array(true, 1, new CoreTestIterator($array, $keys, true, 1)), + array(true, '3', new CoreTestIterator($array, $keys, true, 3)), + array(true, '3', new CoreTestIteratorAggregateAggregate($array, $keys, true, 3)), + array(false, 4, $array), + array(false, 4, new CoreTestIterator($array, $keys, true)), + array(false, 4, new CoreTestIteratorAggregateAggregate($array, $keys, true)), + array(false, 1, 1), + array(true, 'b', new SimpleXMLElement('b')), + ); + } + + /** + * @dataProvider provideSliceFilterCases + */ + public function testSliceFilter($expected, $input, $start, $length = null, $preserveKeys = false) + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $this->assertSame($expected, twig_slice($twig, $input, $start, $length, $preserveKeys)); + } + + public function provideSliceFilterCases() + { + $i = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4); + $keys = array_keys($i); + + return array( + array(array('a' => 1), $i, 0, 1, true), + array(array('a' => 1), $i, 0, 1, false), + array(array('b' => 2, 'c' => 3), $i, 1, 2), + array(array(1), array(1, 2, 3, 4), 0, 1), + array(array(2, 3), array(1, 2, 3, 4), 1, 2), + array(array(2, 3), new CoreTestIterator($i, $keys, true), 1, 2), + array(array('c' => 3, 'd' => 4), new CoreTestIteratorAggregate($i, $keys, true), 2, null, true), + array($i, new CoreTestIterator($i, $keys, true), 0, count($keys) + 10, true), + array(array(), new CoreTestIterator($i, $keys, true), count($keys) + 10), + array('de', 'abcdef', 3, 2), + array(array(), new SimpleXMLElement('12'), 3), + array(array(), new ArrayIterator(array(1, 2)), 3) + ); + } +} + +function foo_escaper_for_test(Twig_Environment $env, $string, $charset) +{ + return $string.$charset; +} + +final class CoreTestIteratorAggregate implements IteratorAggregate +{ + private $iterator; + + public function __construct(array $array, array $keys, $allowAccess = false, $maxPosition = false) + { + $this->iterator = new CoreTestIterator($array, $keys, $allowAccess, $maxPosition); + } + + public function getIterator() + { + return $this->iterator; + } +} + +final class CoreTestIteratorAggregateAggregate implements IteratorAggregate +{ + private $iterator; + + public function __construct(array $array, array $keys, $allowValueAccess = false, $maxPosition = false) + { + $this->iterator = new CoreTestIteratorAggregate($array, $keys, $allowValueAccess, $maxPosition); + } + + public function getIterator() + { + return $this->iterator; + } +} + +final class CoreTestIterator implements Iterator +{ + private $position; + private $array; + private $arrayKeys; + private $allowValueAccess; + private $maxPosition; + + public function __construct(array $values, array $keys, $allowValueAccess = false, $maxPosition = false) + { + $this->array = $values; + $this->arrayKeys = $keys; + $this->position = 0; + $this->allowValueAccess = $allowValueAccess; + $this->maxPosition = false === $maxPosition ? count($values) + 1 : $maxPosition; + } + + public function rewind() + { + $this->position = 0; + } + + public function current() + { + if ($this->allowValueAccess) { + return $this->array[$this->key()]; + } + + throw new LogicException('Code should only use the keys, not the values provided by iterator.'); + } + + public function key() + { + return $this->arrayKeys[$this->position]; + } + + public function next() + { + ++$this->position; + if ($this->position === $this->maxPosition) { + throw new LogicException(sprintf('Code should not iterate beyond %d.', $this->maxPosition)); + } + } + + public function valid() + { + return isset($this->arrayKeys[$this->position]); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php b/vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php new file mode 100644 index 000000000..0b2158269 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Extension/SandboxTest.php @@ -0,0 +1,304 @@ + 'Fabien', + 'obj' => new FooObject(), + 'arr' => array('obj' => new FooObject()), + ); + + self::$templates = array( + '1_basic1' => '{{ obj.foo }}', + '1_basic2' => '{{ name|upper }}', + '1_basic3' => '{% if name %}foo{% endif %}', + '1_basic4' => '{{ obj.bar }}', + '1_basic5' => '{{ obj }}', + '1_basic6' => '{{ arr.obj }}', + '1_basic7' => '{{ cycle(["foo","bar"], 1) }}', + '1_basic8' => '{{ obj.getfoobar }}{{ obj.getFooBar }}', + '1_basic9' => '{{ obj.foobar }}{{ obj.fooBar }}', + '1_basic' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', + '1_layout' => '{% block content %}{% endblock %}', + '1_child' => "{% extends \"1_layout\" %}\n{% block content %}\n{{ \"a\"|json_encode }}\n{% endblock %}", + '1_include' => '{{ include("1_basic1", sandboxed=true) }}', + ); + } + + /** + * @expectedException Twig_Sandbox_SecurityError + * @expectedExceptionMessage Filter "json_encode" is not allowed in "1_child" at line 3. + */ + public function testSandboxWithInheritance() + { + $twig = $this->getEnvironment(true, array(), self::$templates, array('block')); + $twig->loadTemplate('1_child')->render(array()); + } + + public function testSandboxGloballySet() + { + $twig = $this->getEnvironment(false, array(), self::$templates); + $this->assertEquals('FOO', $twig->loadTemplate('1_basic')->render(self::$params), 'Sandbox does nothing if it is disabled globally'); + } + + public function testSandboxUnallowedMethodAccessor() + { + $twig = $this->getEnvironment(true, array(), self::$templates); + try { + $twig->loadTemplate('1_basic1')->render(self::$params); + $this->fail('Sandbox throws a SecurityError exception if an unallowed method is called'); + } catch (Twig_Sandbox_SecurityError $e) { + $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedMethodError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedMethodError'); + $this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class'); + $this->assertEquals('foo', $e->getMethodName(), 'Exception should be raised on the "foo" method'); + } + } + + public function testSandboxUnallowedFilter() + { + $twig = $this->getEnvironment(true, array(), self::$templates); + try { + $twig->loadTemplate('1_basic2')->render(self::$params); + $this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called'); + } catch (Twig_Sandbox_SecurityError $e) { + $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedFilterError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedFilterError'); + $this->assertEquals('upper', $e->getFilterName(), 'Exception should be raised on the "upper" filter'); + } + } + + public function testSandboxUnallowedTag() + { + $twig = $this->getEnvironment(true, array(), self::$templates); + try { + $twig->loadTemplate('1_basic3')->render(self::$params); + $this->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template'); + } catch (Twig_Sandbox_SecurityError $e) { + $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedTagError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedTagError'); + $this->assertEquals('if', $e->getTagName(), 'Exception should be raised on the "if" tag'); + } + } + + public function testSandboxUnallowedProperty() + { + $twig = $this->getEnvironment(true, array(), self::$templates); + try { + $twig->loadTemplate('1_basic4')->render(self::$params); + $this->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template'); + } catch (Twig_Sandbox_SecurityError $e) { + $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedPropertyError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedPropertyError'); + $this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class'); + $this->assertEquals('bar', $e->getPropertyName(), 'Exception should be raised on the "bar" property'); + } + } + + public function testSandboxUnallowedToString() + { + $twig = $this->getEnvironment(true, array(), self::$templates); + try { + $twig->loadTemplate('1_basic5')->render(self::$params); + $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template'); + } catch (Twig_Sandbox_SecurityError $e) { + $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedMethodError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedMethodError'); + $this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class'); + $this->assertEquals('__tostring', $e->getMethodName(), 'Exception should be raised on the "__toString" method'); + } + } + + public function testSandboxUnallowedToStringArray() + { + $twig = $this->getEnvironment(true, array(), self::$templates); + try { + $twig->loadTemplate('1_basic6')->render(self::$params); + $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template'); + } catch (Twig_Sandbox_SecurityError $e) { + $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedMethodError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedMethodError'); + $this->assertEquals('FooObject', $e->getClassName(), 'Exception should be raised on the "FooObject" class'); + $this->assertEquals('__tostring', $e->getMethodName(), 'Exception should be raised on the "__toString" method'); + } + } + + public function testSandboxUnallowedFunction() + { + $twig = $this->getEnvironment(true, array(), self::$templates); + try { + $twig->loadTemplate('1_basic7')->render(self::$params); + $this->fail('Sandbox throws a SecurityError exception if an unallowed function is called in the template'); + } catch (Twig_Sandbox_SecurityError $e) { + $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedFunctionError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedFunctionError'); + $this->assertEquals('cycle', $e->getFunctionName(), 'Exception should be raised on the "cycle" function'); + } + } + + public function testSandboxAllowMethodFoo() + { + $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => 'foo')); + FooObject::reset(); + $this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods'); + $this->assertEquals(1, FooObject::$called['foo'], 'Sandbox only calls method once'); + } + + public function testSandboxAllowMethodToString() + { + $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => '__toString')); + FooObject::reset(); + $this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allow some methods'); + $this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once'); + } + + public function testSandboxAllowMethodToStringDisabled() + { + $twig = $this->getEnvironment(false, array(), self::$templates); + FooObject::reset(); + $this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allows __toString when sandbox disabled'); + $this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once'); + } + + public function testSandboxAllowFilter() + { + $twig = $this->getEnvironment(true, array(), self::$templates, array(), array('upper')); + $this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters'); + } + + public function testSandboxAllowTag() + { + $twig = $this->getEnvironment(true, array(), self::$templates, array('if')); + $this->assertEquals('foo', $twig->loadTemplate('1_basic3')->render(self::$params), 'Sandbox allow some tags'); + } + + public function testSandboxAllowProperty() + { + $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array('FooObject' => 'bar')); + $this->assertEquals('bar', $twig->loadTemplate('1_basic4')->render(self::$params), 'Sandbox allow some properties'); + } + + public function testSandboxAllowFunction() + { + $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array(), array('cycle')); + $this->assertEquals('bar', $twig->loadTemplate('1_basic7')->render(self::$params), 'Sandbox allow some functions'); + } + + public function testSandboxAllowFunctionsCaseInsensitive() + { + foreach (array('getfoobar', 'getFoobar', 'getFooBar') as $name) { + $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => $name)); + FooObject::reset(); + $this->assertEquals('foobarfoobar', $twig->loadTemplate('1_basic8')->render(self::$params), 'Sandbox allow methods in a case-insensitive way'); + $this->assertEquals(2, FooObject::$called['getFooBar'], 'Sandbox only calls method once'); + + $this->assertEquals('foobarfoobar', $twig->loadTemplate('1_basic9')->render(self::$params), 'Sandbox allow methods via shortcut names (ie. without get/set)'); + } + } + + public function testSandboxLocallySetForAnInclude() + { + self::$templates = array( + '2_basic' => '{{ obj.foo }}{% include "2_included" %}{{ obj.foo }}', + '2_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', + ); + + $twig = $this->getEnvironment(false, array(), self::$templates); + $this->assertEquals('fooFOOfoo', $twig->loadTemplate('2_basic')->render(self::$params), 'Sandbox does nothing if disabled globally and sandboxed not used for the include'); + + self::$templates = array( + '3_basic' => '{{ obj.foo }}{% sandbox %}{% include "3_included" %}{% endsandbox %}{{ obj.foo }}', + '3_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', + ); + + $twig = $this->getEnvironment(true, array(), self::$templates); + try { + $twig->loadTemplate('3_basic')->render(self::$params); + $this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed'); + } catch (Twig_Sandbox_SecurityError $e) { + $this->assertInstanceOf('Twig_Sandbox_SecurityNotAllowedTagError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedTagError'); + $this->assertEquals('sandbox', $e->getTagName()); + } + } + + public function testMacrosInASandbox() + { + $twig = $this->getEnvironment(true, array('autoescape' => 'html'), array('index' => <<{{ text }}

    {% endmacro %} + +{{- macros.test('username') }} +EOF + ), array('macro', 'import'), array('escape')); + + $this->assertEquals('

    username

    ', $twig->loadTemplate('index')->render(array())); + } + + public function testSandboxDisabledAfterIncludeFunctionError() + { + $twig = $this->getEnvironment(false, array(), self::$templates); + + $e = null; + try { + $twig->loadTemplate('1_include')->render(self::$params); + } catch (Throwable $e) { + } catch (Exception $e) { + } + if ($e === null) { + $this->fail('An exception should be thrown for this test to be valid.'); + } + + $this->assertFalse($twig->getExtension('Twig_Extension_Sandbox')->isSandboxed(), 'Sandboxed include() function call should not leave Sandbox enabled when an error occurs.'); + } + + protected function getEnvironment($sandboxed, $options, $templates, $tags = array(), $filters = array(), $methods = array(), $properties = array(), $functions = array()) + { + $loader = new Twig_Loader_Array($templates); + $twig = new Twig_Environment($loader, array_merge(array('debug' => true, 'cache' => false, 'autoescape' => false), $options)); + $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions); + $twig->addExtension(new Twig_Extension_Sandbox($policy, $sandboxed)); + + return $twig; + } +} + +class FooObject +{ + public static $called = array('__toString' => 0, 'foo' => 0, 'getFooBar' => 0); + + public $bar = 'bar'; + + public static function reset() + { + self::$called = array('__toString' => 0, 'foo' => 0, 'getFooBar' => 0); + } + + public function __toString() + { + ++self::$called['__toString']; + + return 'foo'; + } + + public function foo() + { + ++self::$called['foo']; + + return 'foo'; + } + + public function getFooBar() + { + ++self::$called['getFooBar']; + + return 'foobar'; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/FactoryRuntimeLoaderTest.php b/vendor/twig/twig/test/Twig/Tests/FactoryRuntimeLoaderTest.php new file mode 100644 index 000000000..f418edf78 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/FactoryRuntimeLoaderTest.php @@ -0,0 +1,32 @@ + 'getRuntime')); + + $this->assertInstanceOf('stdClass', $loader->load('stdClass')); + } + + public function testLoadReturnsNullForUnmappedRuntime() + { + $loader = new Twig_FactoryRuntimeLoader(); + + $this->assertNull($loader->load('stdClass')); + } +} + +function getRuntime() +{ + return new stdClass(); +} diff --git a/vendor/twig/twig/test/Twig/Tests/FileCachingTest.php b/vendor/twig/twig/test/Twig/Tests/FileCachingTest.php new file mode 100644 index 000000000..f7ff53c3f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/FileCachingTest.php @@ -0,0 +1,63 @@ +tmpDir = sys_get_temp_dir().'/TwigTests'; + if (!file_exists($this->tmpDir)) { + @mkdir($this->tmpDir, 0777, true); + } + + if (!is_writable($this->tmpDir)) { + $this->markTestSkipped(sprintf('Unable to run the tests as "%s" is not writable.', $this->tmpDir)); + } + + $this->env = new Twig_Environment(new Twig_Loader_Array(array('index' => 'index', 'index2' => 'index2')), array('cache' => $this->tmpDir)); + } + + protected function tearDown() + { + Twig_Tests_FilesystemHelper::removeDir($this->tmpDir); + } + + /** + * @group legacy + */ + public function testWritingCacheFiles() + { + $name = 'index'; + $this->env->loadTemplate($name); + $cacheFileName = $this->env->getCacheFilename($name); + + $this->assertFileExists($cacheFileName, 'Cache file does not exist.'); + } + + /** + * @group legacy + */ + public function testClearingCacheFiles() + { + $name = 'index2'; + $this->env->loadTemplate($name); + $cacheFileName = $this->env->getCacheFilename($name); + + $this->assertFileExists($cacheFileName, 'Cache file does not exist.'); + $this->env->clearCacheFiles(); + $this->assertFileNotExists($cacheFileName, 'Cache file was not cleared.'); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/FileExtensionEscapingStrategyTest.php b/vendor/twig/twig/test/Twig/Tests/FileExtensionEscapingStrategyTest.php new file mode 100644 index 000000000..b310a5be3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/FileExtensionEscapingStrategyTest.php @@ -0,0 +1,51 @@ +assertSame($strategy, Twig_FileExtensionEscapingStrategy::guess($filename)); + } + + public function getGuessData() + { + return array( + // default + array('html', 'foo.html'), + array('html', 'foo.html.twig'), + array('html', 'foo'), + array('html', 'foo.bar.twig'), + array('html', 'foo.txt/foo'), + array('html', 'foo.txt/foo.js/'), + + // css + array('css', 'foo.css'), + array('css', 'foo.css.twig'), + array('css', 'foo.twig.css'), + array('css', 'foo.js.css'), + array('css', 'foo.js.css.twig'), + + // js + array('js', 'foo.js'), + array('js', 'foo.js.twig'), + array('js', 'foo.txt/foo.js'), + array('js', 'foo.txt.twig/foo.js'), + + // txt + array(false, 'foo.txt'), + array(false, 'foo.txt.twig'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/FilesystemHelper.php b/vendor/twig/twig/test/Twig/Tests/FilesystemHelper.php new file mode 100644 index 000000000..0e315e8f7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/FilesystemHelper.php @@ -0,0 +1,30 @@ + $fileInfo) { + if ($iterator->isDot()) { + continue; + } + + if ($fileInfo->isDir()) { + rmdir($filename); + } else { + unlink($filename); + } + } + rmdir($dir); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/block.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/block.test new file mode 100644 index 000000000..1290973a5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/block.test @@ -0,0 +1,21 @@ +--TEST-- +blocks and autoescape +--TEMPLATE-- +{{ include('unrelated.txt.twig') -}} +{{ include('template.html.twig') -}} +--TEMPLATE(unrelated.txt.twig)-- +{% block content %}{% endblock %} +--TEMPLATE(template.html.twig)-- +{% extends 'parent.html.twig' %} +{% block content %} +{{ br -}} +{% endblock %} +--TEMPLATE(parent.html.twig)-- +{% set _content = block('content')|raw %} +{{ _content|raw }} +--DATA-- +return array('br' => '
    ') +--CONFIG-- +return array('autoescape' => 'name') +--EXPECT-- +<br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/name.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/name.test new file mode 100644 index 000000000..04299bed3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/autoescape/name.test @@ -0,0 +1,22 @@ +--TEST-- +"name" autoescape strategy +--TEMPLATE-- +{{ br -}} +{{ include('index.js.twig') -}} +{{ include('index.html.twig') -}} +{{ include('index.txt.twig') -}} +--TEMPLATE(index.js.twig)-- +{{ br -}} +--TEMPLATE(index.html.twig)-- +{{ br -}} +--TEMPLATE(index.txt.twig)-- +{{ br -}} +--DATA-- +return array('br' => '
    ') +--CONFIG-- +return array('autoescape' => 'name') +--EXPECT-- +<br /> +\x3Cbr\x20\x2F\x3E +<br /> +
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/base.html b/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/base.html new file mode 100644 index 000000000..cb0dbe444 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/base.html @@ -0,0 +1 @@ +{% block content %}{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/index.html b/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/index.html new file mode 100644 index 000000000..df57c822f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/index.html @@ -0,0 +1,7 @@ +{% extends 'base.html' %} +{% block content %} + {{ foo.bar }} +{% endblock %} +{% block foo %} + {{ foo.bar }} +{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/child_contents_outside_blocks.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/child_contents_outside_blocks.test new file mode 100644 index 000000000..a3f0b50ff --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/child_contents_outside_blocks.test @@ -0,0 +1,15 @@ +--TEST-- +Exception for child templates defining contents outside blocks defined by parent +--TEMPLATE-- +{% extends 'base.twig' %} + +Content outside a block. + +{% block sidebar %} + Content inside a block. +{% endblock %} +--TEMPLATE(base.twig)-- +{% block sidebar %} +{% endblock %} +--EXCEPTION-- +Twig_Error_Syntax: A template that extends another one cannot include contents outside Twig blocks. Did you forget to put the contents inside a {% block %} tag in "index.twig" at line 3? diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable.test new file mode 100644 index 000000000..7ff2eedb7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable.test @@ -0,0 +1,18 @@ +--TEST-- +Exception for multiline array with undefined variable +--TEMPLATE-- +{% set foo = { + foo: 'foo', + bar: 'bar', + + + foobar: foobar, + + + + foo2: foo2, +} %} +--DATA-- +return array('foobar' => 'foobar') +--EXCEPTION-- +Twig_Error_Runtime: Variable "foo2" does not exist in "index.twig" at line 11. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable_again.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable_again.test new file mode 100644 index 000000000..c425069bf --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_array_with_undefined_variable_again.test @@ -0,0 +1,18 @@ +--TEST-- +Exception for multiline array with undefined variable +--TEMPLATE-- +{% set foo = { + foo: 'foo', + bar: 'bar', + + + foobar: foobar, + + + + foo2: foo2, +} %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Runtime: Variable "foobar" does not exist in "index.twig" at line 7. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_undefined_variable.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_undefined_variable.test new file mode 100644 index 000000000..2f94a5ee9 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_undefined_variable.test @@ -0,0 +1,12 @@ +--TEST-- +Exception for multile function with undefined variable +--TEMPLATE-- +{{ include('foo', + with_context=with_context +) }} +--TEMPLATE(foo)-- +Foo +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Runtime: Variable "with_context" does not exist in "index.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_unknown_argument.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_unknown_argument.test new file mode 100644 index 000000000..64761fcf1 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_function_with_unknown_argument.test @@ -0,0 +1,9 @@ +--TEST-- +Exception for multiline function with unknown argument +--TEMPLATE-- +{{ include('foo', + with_context=True, + invalid=False +) }} +--EXCEPTION-- +Twig_Error_Syntax: Unknown argument "invalid" for function "include(template, variables, with_context, ignore_missing, sandboxed)" in "index.twig" at line 4. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_tag_with_undefined_variable.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_tag_with_undefined_variable.test new file mode 100644 index 000000000..7b3b1daf9 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/multiline_tag_with_undefined_variable.test @@ -0,0 +1,12 @@ +--TEST-- +Exception for multiline tag with undefined variable +--TEMPLATE-- +{% include 'foo' + with vars +%} +--TEMPLATE(foo)-- +Foo +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Runtime: Variable "vars" does not exist in "index.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/syntax_error_in_reused_template.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/syntax_error_in_reused_template.test new file mode 100644 index 000000000..9ca418b22 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/syntax_error_in_reused_template.test @@ -0,0 +1,10 @@ +--TEST-- +Exception for syntax error in reused template +--TEMPLATE-- +{% use 'foo.twig' %} +--TEMPLATE(foo.twig)-- +{% block bar %} + {% do node.data = 5 %} +{% endblock %} +--EXCEPTION-- +Twig_Error_Syntax: Unexpected token "operator" of value "=" ("end of statement block" expected) in "foo.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/unclosed_tag.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/unclosed_tag.test new file mode 100644 index 000000000..2c35ad564 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/unclosed_tag.test @@ -0,0 +1,20 @@ +--TEST-- +Exception for an unclosed tag +--TEMPLATE-- +{% block foo %} + {% if foo %} + + + + + {% for i in fo %} + + + + {% endfor %} + + + +{% endblock %} +--EXCEPTION-- +Twig_Error_Syntax: Unexpected "endblock" tag (expecting closing tag for the "if" tag defined near line 4) in "index.twig" at line 16. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_parent.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_parent.test new file mode 100644 index 000000000..c8e7a0973 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_parent.test @@ -0,0 +1,8 @@ +--TEST-- +Exception for an undefined parent +--TEMPLATE-- +{% extends 'foo.html' %} + +{% set foo = "foo" %} +--EXCEPTION-- +Twig_Error_Loader: Template "foo.html" is not defined in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_template_in_child_template.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_template_in_child_template.test new file mode 100644 index 000000000..1992510b2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_template_in_child_template.test @@ -0,0 +1,15 @@ +--TEST-- +Exception for an undefined template in a child template +--TEMPLATE-- +{% extends 'base.twig' %} + +{% block sidebar %} + {{ include('include.twig') }} +{% endblock %} +--TEMPLATE(base.twig)-- +{% block sidebar %} +{% endblock %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Loader: Template "include.twig" is not defined in "index.twig" at line 5. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_trait.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_trait.test new file mode 100644 index 000000000..6679fbe13 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/exceptions/undefined_trait.test @@ -0,0 +1,9 @@ +--TEST-- +Exception for an undefined trait +--TEMPLATE-- +{% use 'foo' with foobar as bar %} +--TEMPLATE(foo)-- +{% block bar %} +{% endblock %} +--EXCEPTION-- +Twig_Error_Runtime: Block "foobar" is not defined in trait "foo" in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/_self.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/_self.test new file mode 100644 index 000000000..32fed8fd0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/_self.test @@ -0,0 +1,8 @@ +--TEST-- +_self returns the template name +--TEMPLATE-- +{{ _self }} +--DATA-- +return array() +--EXPECT-- +index.twig diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/array.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/array.test new file mode 100644 index 000000000..c69b1192f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/array.test @@ -0,0 +1,61 @@ +--TEST-- +Twig supports array notation +--TEMPLATE-- +{# empty array #} +{{ []|join(',') }} + +{{ [1, 2]|join(',') }} +{{ ['foo', "bar"]|join(',') }} +{{ {0: 1, 'foo': 'bar'}|join(',') }} +{{ {0: 1, 'foo': 'bar'}|keys|join(',') }} + +{{ {0: 1, foo: 'bar'}|join(',') }} +{{ {0: 1, foo: 'bar'}|keys|join(',') }} + +{# nested arrays #} +{% set a = [1, 2, [1, 2], {'foo': {'foo': 'bar'}}] %} +{{ a[2]|join(',') }} +{{ a[3]["foo"]|join(',') }} + +{# works even if [] is used inside the array #} +{{ [foo[bar]]|join(',') }} + +{# elements can be any expression #} +{{ ['foo'|upper, bar|upper, bar == foo]|join(',') }} + +{# arrays can have a trailing , like in PHP #} +{{ + [ + 1, + 2, + ]|join(',') +}} + +{# keys can be any expression #} +{% set a = 1 %} +{% set b = "foo" %} +{% set ary = { (a): 'a', (b): 'b', 'c': 'c', (a ~ b): 'd' } %} +{{ ary|keys|join(',') }} +{{ ary|join(',') }} +--DATA-- +return array('bar' => 'bar', 'foo' => array('bar' => 'bar')) +--EXPECT-- +1,2 +foo,bar +1,bar +0,foo + +1,bar +0,foo + +1,2 +bar + +bar + +FOO,BAR, + +1,2 + +1,foo,c,1foo +a,b,c,d diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/array_call.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/array_call.test new file mode 100644 index 000000000..f3df328fe --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/array_call.test @@ -0,0 +1,14 @@ +--TEST-- +Twig supports method calls +--TEMPLATE-- +{{ items.foo }} +{{ items['foo'] }} +{{ items[foo] }} +{{ items[items[foo]] }} +--DATA-- +return array('foo' => 'bar', 'items' => array('foo' => 'bar', 'bar' => 'foo')) +--EXPECT-- +bar +bar +foo +bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/binary.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/binary.test new file mode 100644 index 000000000..f5e68456d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/binary.test @@ -0,0 +1,46 @@ +--TEST-- +Twig supports binary operations (+, -, *, /, ~, %, and, or) +--TEMPLATE-- +{{ 1 + 1 }} +{{ 2 - 1 }} +{{ 2 * 2 }} +{{ 2 / 2 }} +{{ 3 % 2 }} +{{ 1 and 1 }} +{{ 1 and 0 }} +{{ 0 and 1 }} +{{ 0 and 0 }} +{{ 1 or 1 }} +{{ 1 or 0 }} +{{ 0 or 1 }} +{{ 0 or 0 }} +{{ 0 or 1 and 0 }} +{{ 1 or 0 and 1 }} +{{ "foo" ~ "bar" }} +{{ foo ~ "bar" }} +{{ "foo" ~ bar }} +{{ foo ~ bar }} +{{ 20 // 7 }} +--DATA-- +return array('foo' => 'bar', 'bar' => 'foo') +--EXPECT-- +2 +1 +4 +1 +1 +1 + + + +1 +1 +1 + + +1 +foobar +barbar +foofoo +barfoo +2 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/bitwise.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/bitwise.test new file mode 100644 index 000000000..74fe6cabb --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/bitwise.test @@ -0,0 +1,14 @@ +--TEST-- +Twig supports bitwise operations +--TEMPLATE-- +{{ 1 b-and 5 }} +{{ 1 b-or 5 }} +{{ 1 b-xor 5 }} +{{ (1 and 0 b-or 0) is same as(1 and (0 b-or 0)) ? 'ok' : 'ko' }} +--DATA-- +return array() +--EXPECT-- +1 +5 +4 +ok diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/comparison.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/comparison.test new file mode 100644 index 000000000..726b85075 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/comparison.test @@ -0,0 +1,14 @@ +--TEST-- +Twig supports comparison operators (==, !=, <, >, >=, <=) +--TEMPLATE-- +{{ 1 > 2 }}/{{ 1 > 1 }}/{{ 1 >= 2 }}/{{ 1 >= 1 }} +{{ 1 < 2 }}/{{ 1 < 1 }}/{{ 1 <= 2 }}/{{ 1 <= 1 }} +{{ 1 == 1 }}/{{ 1 == 2 }} +{{ 1 != 1 }}/{{ 1 != 2 }} +--DATA-- +return array() +--EXPECT-- +///1 +1//1/1 +1/ +/1 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/divisibleby.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/divisibleby.test new file mode 100644 index 000000000..238dd2790 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/divisibleby.test @@ -0,0 +1,17 @@ +--TEST-- +Twig supports the "divisible by" operator +--TEMPLATE-- +{{ 8 is divisible by(2) ? 'OK' }} +{{ 8 is not divisible by(3) ? 'OK' }} +{{ 8 is divisible by (2) ? 'OK' }} +{{ 8 is not + divisible + by + (3) ? 'OK' }} +--DATA-- +return array() +--EXPECT-- +OK +OK +OK +OK diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/dotdot.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/dotdot.test new file mode 100644 index 000000000..9cd0676ce --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/dotdot.test @@ -0,0 +1,20 @@ +--TEST-- +Twig supports the .. operator +--TEMPLATE-- +{% for i in 0..10 %}{{ i }} {% endfor %} + +{% for letter in 'a'..'z' %}{{ letter }} {% endfor %} + +{% for letter in 'a'|upper..'z'|upper %}{{ letter }} {% endfor %} + +{% for i in foo[0]..foo[1] %}{{ i }} {% endfor %} + +{% for i in 0 + 1 .. 10 - 1 %}{{ i }} {% endfor %} +--DATA-- +return array('foo' => array(1, 10)) +--EXPECT-- +0 1 2 3 4 5 6 7 8 9 10 +a b c d e f g h i j k l m n o p q r s t u v w x y z +A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +1 2 3 4 5 6 7 8 9 10 +1 2 3 4 5 6 7 8 9 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ends_with.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ends_with.test new file mode 100644 index 000000000..9ad5e5e8e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ends_with.test @@ -0,0 +1,26 @@ +--TEST-- +Twig supports the "ends with" operator +--TEMPLATE-- +{{ 'foo' ends with 'o' ? 'OK' : 'KO' }} +{{ not ('foo' ends with 'f') ? 'OK' : 'KO' }} +{{ not ('foo' ends with 'foowaytoolong') ? 'OK' : 'KO' }} +{{ 'foo' ends with '' ? 'OK' : 'KO' }} +{{ '1' ends with true ? 'OK' : 'KO' }} +{{ 1 ends with true ? 'OK' : 'KO' }} +{{ 0 ends with false ? 'OK' : 'KO' }} +{{ '' ends with false ? 'OK' : 'KO' }} +{{ false ends with false ? 'OK' : 'KO' }} +{{ false ends with '' ? 'OK' : 'KO' }} +--DATA-- +return array() +--EXPECT-- +OK +OK +OK +OK +KO +KO +KO +KO +KO +KO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/grouping.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/grouping.test new file mode 100644 index 000000000..79f8e0b0d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/grouping.test @@ -0,0 +1,8 @@ +--TEST-- +Twig supports grouping of expressions +--TEMPLATE-- +{{ (2 + 2) / 2 }} +--DATA-- +return array() +--EXPECT-- +2 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/literals.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/literals.test new file mode 100644 index 000000000..7ae3bae95 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/literals.test @@ -0,0 +1,22 @@ +--TEST-- +Twig supports literals +--TEMPLATE-- +1 {{ true }} +2 {{ TRUE }} +3 {{ false }} +4 {{ FALSE }} +5 {{ none }} +6 {{ NONE }} +7 {{ null }} +8 {{ NULL }} +--DATA-- +return array() +--EXPECT-- +1 1 +2 1 +3 +4 +5 +6 +7 +8 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test new file mode 100644 index 000000000..1a27a2d6f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test @@ -0,0 +1,27 @@ +--TEST-- +Twig supports __call() for attributes +--TEMPLATE-- +{{ foo.foo }} +{{ foo.bar }} +--DATA-- +class TestClassForMagicCallAttributes +{ + public function getBar() + { + return 'bar_from_getbar'; + } + + public function __call($method, $arguments) + { + if ('foo' === $method) { + return 'foo_from_call'; + } + + return false; + } +} + +return array('foo' => new TestClassForMagicCallAttributes()) +--EXPECT-- +foo_from_call +bar_from_getbar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/matches.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/matches.test new file mode 100644 index 000000000..b6c771657 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/matches.test @@ -0,0 +1,12 @@ +--TEST-- +Twig supports the "matches" operator +--TEMPLATE-- +{{ 'foo' matches '/o/' ? 'OK' : 'KO' }} +{{ 'foo' matches '/^fo/' ? 'OK' : 'KO' }} +{{ 'foo' matches '/O/i' ? 'OK' : 'KO' }} +--DATA-- +return array() +--EXPECT-- +OK +OK +OK diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/method_call.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/method_call.test new file mode 100644 index 000000000..5f801e635 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/method_call.test @@ -0,0 +1,28 @@ +--TEST-- +Twig supports method calls +--TEMPLATE-- +{{ items.foo.foo }} +{{ items.foo.getFoo() }} +{{ items.foo.bar }} +{{ items.foo['bar'] }} +{{ items.foo.bar('a', 43) }} +{{ items.foo.bar(foo) }} +{{ items.foo.self.foo() }} +{{ items.foo.is }} +{{ items.foo.in }} +{{ items.foo.not }} +--DATA-- +return array('foo' => 'bar', 'items' => array('foo' => new TwigTestFoo(), 'bar' => 'foo')) +--CONFIG-- +return array('strict_variables' => false) +--EXPECT-- +foo +foo +bar + +bar_a-43 +bar_bar +foo +is +in +not diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/negative_numbers.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/negative_numbers.test new file mode 100644 index 000000000..1853b1b06 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/negative_numbers.test @@ -0,0 +1,18 @@ +--TEST-- +Twig manages negative numbers correctly +--TEMPLATE-- +{{ -1 }} +{{ - 1 }} +{{ 5 - 1 }} +{{ 5-1 }} +{{ 5 + -1 }} +{{ 5 + - 1 }} +--DATA-- +return array() +--EXPECT-- +-1 +-1 +4 +4 +4 +4 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/operators_as_variables.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/operators_as_variables.test new file mode 100644 index 000000000..fe29d08bb --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/operators_as_variables.test @@ -0,0 +1,16 @@ +--TEST-- +Twig allows to use named operators as variable names +--TEMPLATE-- +{% for match in matches %} + {{- match }} +{% endfor %} +{{ in }} +{{ is }} +--DATA-- +return array('matches' => array(1, 2, 3), 'in' => 'in', 'is' => 'is') +--EXPECT-- +1 +2 +3 +in +is diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/postfix.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/postfix.test new file mode 100644 index 000000000..542c35046 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/postfix.test @@ -0,0 +1,22 @@ +--TEST-- +Twig parses postfix expressions +--TEMPLATE-- +{% import _self as macros %} + +{% macro foo() %}foo{% endmacro %} + +{{ 'a' }} +{{ 'a'|upper }} +{{ ('a')|upper }} +{{ -1|upper }} +{{ macros.foo() }} +{{ (macros).foo() }} +--DATA-- +return array(); +--EXPECT-- +a +A +A +-1 +foo +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/power.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/power.test new file mode 100644 index 000000000..eacc98f86 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/power.test @@ -0,0 +1,20 @@ +--TEST-- +Twig parses power expressions +--TEMPLATE-- +{{ 2**3 }} +{{ (-2)**3 }} +{{ (-2)**(-3) }} +{{ a ** a }} +{{ a ** b }} +{{ b ** a }} +{{ b ** b }} +--DATA-- +return array('a' => 4, 'b' => -2); +--EXPECT-- +8 +-8 +-0.125 +256 +0.0625 +16 +0.25 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/sameas.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/sameas.test new file mode 100644 index 000000000..601201deb --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/sameas.test @@ -0,0 +1,21 @@ +--TEST-- +Twig supports the "same as" operator +--TEMPLATE-- +{{ 1 is same as(1) ? 'OK' }} +{{ 1 is not same as(true) ? 'OK' }} +{{ 1 is same as(1) ? 'OK' }} +{{ 1 is not same as(true) ? 'OK' }} +{{ 1 is same as (1) ? 'OK' }} +{{ 1 is not + same + as + (true) ? 'OK' }} +--DATA-- +return array() +--EXPECT-- +OK +OK +OK +OK +OK +OK diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/starts_with.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/starts_with.test new file mode 100644 index 000000000..75d331e90 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/starts_with.test @@ -0,0 +1,27 @@ +--TEST-- +Twig supports the "starts with" operator +--TEMPLATE-- +{{ 'foo' starts with 'f' ? 'OK' : 'KO' }} +{{ not ('foo' starts with 'oo') ? 'OK' : 'KO' }} +{{ not ('foo' starts with 'foowaytoolong') ? 'OK' : 'KO' }} +{{ 'foo' starts with 'f' ? 'OK' : 'KO' }} +{{ 'foo' starts +with 'f' ? 'OK' : 'KO' }} +{{ 'foo' starts with '' ? 'OK' : 'KO' }} +{{ '1' starts with true ? 'OK' : 'KO' }} +{{ '' starts with false ? 'OK' : 'KO' }} +{{ 'a' starts with false ? 'OK' : 'KO' }} +{{ false starts with '' ? 'OK' : 'KO' }} +--DATA-- +return array() +--EXPECT-- +OK +OK +OK +OK +OK +OK +KO +KO +KO +KO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/strings.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/strings.test new file mode 100644 index 000000000..a9116613e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/strings.test @@ -0,0 +1,10 @@ +--TEST-- +Twig supports string interpolation +--TEMPLATE-- +{{ "foo #{"foo #{bar} baz"} baz" }} +{{ "foo #{bar}#{bar} baz" }} +--DATA-- +return array('bar' => 'BAR'); +--EXPECT-- +foo foo BAR baz baz +foo BARBAR baz diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator.test new file mode 100644 index 000000000..0e6fa96e2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator.test @@ -0,0 +1,18 @@ +--TEST-- +Twig supports the ternary operator +--TEMPLATE-- +{{ 1 ? 'YES' : 'NO' }} +{{ 0 ? 'YES' : 'NO' }} +{{ 0 ? 'YES' : (1 ? 'YES1' : 'NO1') }} +{{ 0 ? 'YES' : (0 ? 'YES1' : 'NO1') }} +{{ 1 == 1 ? 'foo
    ':'' }} +{{ foo ~ (bar ? ('-' ~ bar) : '') }} +--DATA-- +return array('foo' => 'foo', 'bar' => 'bar') +--EXPECT-- +YES +NO +YES1 +NO1 +foo
    +foo-bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_noelse.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_noelse.test new file mode 100644 index 000000000..fdc660fc5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_noelse.test @@ -0,0 +1,10 @@ +--TEST-- +Twig supports the ternary operator +--TEMPLATE-- +{{ 1 ? 'YES' }} +{{ 0 ? 'YES' }} +--DATA-- +return array() +--EXPECT-- +YES + diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_nothen.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_nothen.test new file mode 100644 index 000000000..9057e8370 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator_nothen.test @@ -0,0 +1,10 @@ +--TEST-- +Twig supports the ternary operator +--TEMPLATE-- +{{ 'YES' ?: 'NO' }} +{{ 0 ?: 'NO' }} +--DATA-- +return array() +--EXPECT-- +YES +NO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/two_word_operators_as_variables.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/two_word_operators_as_variables.test new file mode 100644 index 000000000..0eaabb446 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/two_word_operators_as_variables.test @@ -0,0 +1,8 @@ +--TEST-- +Twig does not allow to use two-word named operators as variable names +--TEMPLATE-- +{{ starts with }} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: Unexpected token "operator" of value "starts with" in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary.test new file mode 100644 index 000000000..b79219a2a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary.test @@ -0,0 +1,12 @@ +--TEST-- +Twig supports unary operators (not, -, +) +--TEMPLATE-- +{{ not 1 }}/{{ not 0 }} +{{ +1 + 1 }}/{{ -1 - 1 }} +{{ not (false or true) }} +--DATA-- +return array() +--EXPECT-- +/1 +2/-2 + diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary_macro_arguments.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary_macro_arguments.test new file mode 100644 index 000000000..ad84a9c26 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary_macro_arguments.test @@ -0,0 +1,22 @@ +--TEST-- +Twig manages negative numbers as default parameters +--TEMPLATE-- +{% import _self as macros %} +{{ macros.negative_number1() }} +{{ macros.negative_number2() }} +{{ macros.negative_number3() }} +{{ macros.positive_number1() }} +{{ macros.positive_number2() }} +{% macro negative_number1(nb=-1) %}{{ nb }}{% endmacro %} +{% macro negative_number2(nb = --1) %}{{ nb }}{% endmacro %} +{% macro negative_number3(nb = - 1) %}{{ nb }}{% endmacro %} +{% macro positive_number1(nb = +1) %}{{ nb }}{% endmacro %} +{% macro positive_number2(nb = ++1) %}{{ nb }}{% endmacro %} +--DATA-- +return array() +--EXPECT-- +-1 +1 +-1 +1 +1 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary_precedence.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary_precedence.test new file mode 100644 index 000000000..cc6eef8d2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/expressions/unary_precedence.test @@ -0,0 +1,14 @@ +--TEST-- +Twig unary operators precedence +--TEMPLATE-- +{{ -1 - 1 }} +{{ -1 - -1 }} +{{ -1 * -1 }} +{{ 4 / -1 * 5 }} +--DATA-- +return array() +--EXPECT-- +-2 +0 +1 +-20 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/abs.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/abs.test new file mode 100644 index 000000000..27e93fd63 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/abs.test @@ -0,0 +1,30 @@ +--TEST-- +"abs" filter +--TEMPLATE-- +{{ (-5.5)|abs }} +{{ (-5)|abs }} +{{ (-0)|abs }} +{{ 0|abs }} +{{ 5|abs }} +{{ 5.5|abs }} +{{ number1|abs }} +{{ number2|abs }} +{{ number3|abs }} +{{ number4|abs }} +{{ number5|abs }} +{{ number6|abs }} +--DATA-- +return array('number1' => -5.5, 'number2' => -5, 'number3' => -0, 'number4' => 0, 'number5' => 5, 'number6' => 5.5) +--EXPECT-- +5.5 +5 +0 +0 +5 +5.5 +5.5 +5 +0 +0 +5 +5.5 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch.test new file mode 100644 index 000000000..cb6de7f97 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch.test @@ -0,0 +1,31 @@ +--TEST-- +"batch" filter +--TEMPLATE-- +{% for row in items|batch(3) %} +
    + {% for column in row %} +
    {{ column }}
    + {% endfor %} +
    +{% endfor %} +--DATA-- +return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')) +--EXPECT-- +
    +
    a
    +
    b
    +
    c
    +
    +
    +
    d
    +
    e
    +
    f
    +
    +
    +
    g
    +
    h
    +
    i
    +
    +
    +
    j
    +
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_float.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_float.test new file mode 100644 index 000000000..e2ec4beb2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_float.test @@ -0,0 +1,29 @@ +--TEST-- +"batch" filter +--TEMPLATE-- +{% for row in items|batch(3.1) %} +
    + {% for column in row %} +
    {{ column }}
    + {% endfor %} +
    +{% endfor %} +--DATA-- +return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')) +--EXPECT-- +
    +
    a
    +
    b
    +
    c
    +
    d
    +
    +
    +
    e
    +
    f
    +
    g
    +
    h
    +
    +
    +
    i
    +
    j
    +
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_empty_fill.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_empty_fill.test new file mode 100644 index 000000000..af996f246 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_empty_fill.test @@ -0,0 +1,37 @@ +--TEST-- +"batch" filter +--TEMPLATE-- + +{% for row in items|batch(3, '') %} + + {% for column in row %} + + {% endfor %} + +{% endfor %} +
    {{ column }}
    +--DATA-- +return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')) +--EXPECT-- + + + + + + + + + + + + + + + + + + + + + +
    abc
    def
    ghi
    j
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_exact_elements.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_exact_elements.test new file mode 100644 index 000000000..72483f4b5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_exact_elements.test @@ -0,0 +1,33 @@ +--TEST-- +"batch" filter +--TEMPLATE-- +{% for row in items|batch(3, 'fill') %} +
    + {% for column in row %} +
    {{ column }}
    + {% endfor %} +
    +{% endfor %} +--DATA-- +return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l')) +--EXPECT-- +
    +
    a
    +
    b
    +
    c
    +
    +
    +
    d
    +
    e
    +
    f
    +
    +
    +
    g
    +
    h
    +
    i
    +
    +
    +
    j
    +
    k
    +
    l
    +
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_fill.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_fill.test new file mode 100644 index 000000000..746295f1b --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_fill.test @@ -0,0 +1,37 @@ +--TEST-- +"batch" filter +--TEMPLATE-- + +{% for row in items|batch(3, 'fill') %} + + {% for column in row %} + + {% endfor %} + +{% endfor %} +
    {{ column }}
    +--DATA-- +return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')) +--EXPECT-- + + + + + + + + + + + + + + + + + + + + + +
    abc
    def
    ghi
    jfillfill
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_keys.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_keys.test new file mode 100644 index 000000000..6015380e2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_keys.test @@ -0,0 +1,10 @@ +--TEST-- +"batch" filter preserves array keys +--TEMPLATE-- +{{ {'foo': 'bar', 'key': 'value'}|batch(4)|first|keys|join(',') }} +{{ {'foo': 'bar', 'key': 'value'}|batch(4, 'fill')|first|keys|join(',') }} +--DATA-- +return array() +--EXPECT-- +foo,key +foo,key,0,1 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_zero_elements.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_zero_elements.test new file mode 100644 index 000000000..b9c058d6b --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/batch_with_zero_elements.test @@ -0,0 +1,10 @@ +--TEST-- +"batch" filter with zero elements +--TEMPLATE-- +{{ []|batch(3)|length }} +{{ []|batch(3, 'fill')|length }} +--DATA-- +return array() +--EXPECT-- +0 +0 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/convert_encoding.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/convert_encoding.test new file mode 100644 index 000000000..380b04bb8 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/convert_encoding.test @@ -0,0 +1,10 @@ +--TEST-- +"convert_encoding" filter +--CONDITION-- +function_exists('iconv') || function_exists('mb_convert_encoding') +--TEMPLATE-- +{{ "愛していますか?"|convert_encoding('ISO-2022-JP', 'UTF-8')|convert_encoding('UTF-8', 'ISO-2022-JP') }} +--DATA-- +return array() +--EXPECT-- +愛していますか? diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date.test new file mode 100644 index 000000000..d17e5e2f0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date.test @@ -0,0 +1,90 @@ +--TEST-- +"date" filter +--TEMPLATE-- +{{ date1|date }} +{{ date1|date('d/m/Y') }} +{{ date1|date('d/m/Y H:i:s', 'Asia/Hong_Kong') }} +{{ date1|date('d/m/Y H:i:s P', 'Asia/Hong_Kong') }} +{{ date1|date('d/m/Y H:i:s P', 'America/Chicago') }} +{{ date1|date('e') }} +{{ date1|date('d/m/Y H:i:s') }} + +{{ date2|date }} +{{ date2|date('d/m/Y') }} +{{ date2|date('d/m/Y H:i:s', 'Asia/Hong_Kong') }} +{{ date2|date('d/m/Y H:i:s', timezone1) }} +{{ date2|date('d/m/Y H:i:s') }} + +{{ date3|date }} +{{ date3|date('d/m/Y') }} + +{{ date4|date }} +{{ date4|date('d/m/Y') }} + +{{ date5|date }} +{{ date5|date('d/m/Y') }} + +{{ date6|date('d/m/Y H:i:s P', 'Europe/Paris') }} +{{ date6|date('d/m/Y H:i:s P', 'Asia/Hong_Kong') }} +{{ date6|date('d/m/Y H:i:s P', false) }} +{{ date6|date('e', 'Europe/Paris') }} +{{ date6|date('e', false) }} + +{{ date7|date }} +{{ date7|date(timezone='Europe/Paris') }} +{{ date7|date(timezone='Asia/Hong_Kong') }} +{{ date7|date(timezone=false) }} +{{ date7|date(timezone='Indian/Mauritius') }} + +{{ '2010-01-28 15:00:00'|date(timezone="Europe/Paris") }} +{{ '2010-01-28 15:00:00'|date(timezone="Asia/Hong_Kong") }} +--DATA-- +date_default_timezone_set('Europe/Paris'); +return array( + 'date1' => mktime(13, 45, 0, 10, 4, 2010), + 'date2' => new DateTime('2010-10-04 13:45'), + 'date3' => '2010-10-04 13:45', + 'date4' => 1286199900, // DateTime::createFromFormat('Y-m-d H:i', '2010-10-04 13:45', new DateTimeZone('UTC'))->getTimestamp() -- A unixtimestamp is always GMT + 'date5' => -189291360, // DateTime::createFromFormat('Y-m-d H:i', '1964-01-02 03:04', new DateTimeZone('UTC'))->getTimestamp(), + 'date6' => new DateTime('2010-10-04 13:45', new DateTimeZone('America/New_York')), + 'date7' => '2010-01-28T15:00:00+04:00', + 'timezone1' => new DateTimeZone('America/New_York'), +) +--EXPECT-- +October 4, 2010 13:45 +04/10/2010 +04/10/2010 19:45:00 +04/10/2010 19:45:00 +08:00 +04/10/2010 06:45:00 -05:00 +Europe/Paris +04/10/2010 13:45:00 + +October 4, 2010 13:45 +04/10/2010 +04/10/2010 19:45:00 +04/10/2010 07:45:00 +04/10/2010 13:45:00 + +October 4, 2010 13:45 +04/10/2010 + +October 4, 2010 15:45 +04/10/2010 + +January 2, 1964 04:04 +02/01/1964 + +04/10/2010 19:45:00 +02:00 +05/10/2010 01:45:00 +08:00 +04/10/2010 13:45:00 -04:00 +Europe/Paris +America/New_York + +January 28, 2010 12:00 +January 28, 2010 12:00 +January 28, 2010 19:00 +January 28, 2010 15:00 +January 28, 2010 15:00 + +January 28, 2010 15:00 +January 28, 2010 22:00 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test new file mode 100644 index 000000000..6ad504cdf --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test @@ -0,0 +1,14 @@ +--TEST-- +"date" filter +--TEMPLATE-- +{{ date1|date }} +{{ date1|date('d/m/Y') }} +--DATA-- +date_default_timezone_set('UTC'); +$twig->getExtension('Twig_Extension_Core')->setDateFormat('Y-m-d', '%d days %h hours'); +return array( + 'date1' => mktime(13, 45, 0, 10, 4, 2010), +) +--EXPECT-- +2010-10-04 +04/10/2010 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test new file mode 100644 index 000000000..be4a642e7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test @@ -0,0 +1,16 @@ +--TEST-- +"date" filter (interval support as of PHP 5.3) +--CONDITION-- +version_compare(phpversion(), '5.3.0', '>=') +--TEMPLATE-- +{{ date2|date }} +{{ date2|date('%d days') }} +--DATA-- +date_default_timezone_set('UTC'); +$twig->getExtension('Twig_Extension_Core')->setDateFormat('Y-m-d', '%d days %h hours'); +return array( + 'date2' => new DateInterval('P2D'), +) +--EXPECT-- +2 days 0 hours +2 days diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_immutable.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_immutable.test new file mode 100644 index 000000000..4e1832562 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_immutable.test @@ -0,0 +1,37 @@ +--TEST-- +"date" filter +--CONDITION-- +version_compare(phpversion(), '5.5.0', '>=') +--TEMPLATE-- +{{ date1|date }} +{{ date1|date('d/m/Y') }} +{{ date1|date('d/m/Y H:i:s', 'Asia/Hong_Kong') }} +{{ date1|date('d/m/Y H:i:s', timezone1) }} +{{ date1|date('d/m/Y H:i:s') }} +{{ date1|date_modify('+1 hour')|date('d/m/Y H:i:s') }} + +{{ date2|date('d/m/Y H:i:s P', 'Europe/Paris') }} +{{ date2|date('d/m/Y H:i:s P', 'Asia/Hong_Kong') }} +{{ date2|date('d/m/Y H:i:s P', false) }} +{{ date2|date('e', 'Europe/Paris') }} +{{ date2|date('e', false) }} +--DATA-- +date_default_timezone_set('Europe/Paris'); +return array( + 'date1' => new DateTimeImmutable('2010-10-04 13:45'), + 'date2' => new DateTimeImmutable('2010-10-04 13:45', new DateTimeZone('America/New_York')), + 'timezone1' => new DateTimeZone('America/New_York'), +) +--EXPECT-- +October 4, 2010 13:45 +04/10/2010 +04/10/2010 19:45:00 +04/10/2010 07:45:00 +04/10/2010 13:45:00 +04/10/2010 14:45:00 + +04/10/2010 19:45:00 +02:00 +05/10/2010 01:45:00 +08:00 +04/10/2010 13:45:00 -04:00 +Europe/Paris +America/New_York diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_interval.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_interval.test new file mode 100644 index 000000000..0c8c6f1a2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_interval.test @@ -0,0 +1,19 @@ +--TEST-- +"date" filter (interval support as of PHP 5.3) +--CONDITION-- +version_compare(phpversion(), '5.3.0', '>=') +--TEMPLATE-- +{{ date1|date }} +{{ date1|date('%d days %h hours') }} +{{ date1|date('%d days %h hours', timezone1) }} +--DATA-- +date_default_timezone_set('UTC'); +return array( + 'date1' => new DateInterval('P2D'), + // This should have no effect on DateInterval formatting + 'timezone1' => new DateTimeZone('America/New_York'), +) +--EXPECT-- +2 days +2 days 0 hours +2 days 0 hours diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_modify.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_modify.test new file mode 100644 index 000000000..53d3a69cd --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_modify.test @@ -0,0 +1,14 @@ +--TEST-- +"date_modify" filter +--TEMPLATE-- +{{ date1|date_modify('-1day')|date('Y-m-d H:i:s') }} +{{ date2|date_modify('-1day')|date('Y-m-d H:i:s') }} +--DATA-- +date_default_timezone_set('UTC'); +return array( + 'date1' => '2010-10-04 13:45', + 'date2' => new DateTime('2010-10-04 13:45'), +) +--EXPECT-- +2010-10-03 13:45:00 +2010-10-03 13:45:00 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_namedargs.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_namedargs.test new file mode 100644 index 000000000..4ecde8a18 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_namedargs.test @@ -0,0 +1,13 @@ +--TEST-- +"date" filter +--TEMPLATE-- +{{ date|date(format='d/m/Y H:i:s P', timezone='America/Chicago') }} +{{ date|date(timezone='America/Chicago', format='d/m/Y H:i:s P') }} +{{ date|date('d/m/Y H:i:s P', timezone='America/Chicago') }} +--DATA-- +date_default_timezone_set('UTC'); +return array('date' => mktime(13, 45, 0, 10, 4, 2010)) +--EXPECT-- +04/10/2010 08:45:00 -05:00 +04/10/2010 08:45:00 -05:00 +04/10/2010 08:45:00 -05:00 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/default.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/default.test new file mode 100644 index 000000000..b8d1d66f5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/default.test @@ -0,0 +1,150 @@ +--TEST-- +"default" filter +--TEMPLATE-- +Variable: +{{ definedVar |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ zeroVar |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ emptyVar |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ nullVar |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ undefinedVar |default('default') is same as('default') ? 'ok' : 'ko' }} +Array access: +{{ nested.definedVar |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ nested['definedVar'] |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ nested.zeroVar |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ nested.emptyVar |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ nested.nullVar |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ nested.undefinedVar |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ nested['undefinedVar'] |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ undefinedVar.foo |default('default') is same as('default') ? 'ok' : 'ko' }} +Plain values: +{{ 'defined' |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ 0 |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ '' |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ null |default('default') is same as('default') ? 'ok' : 'ko' }} +Precedence: +{{ 'o' ~ nullVar |default('k') }} +{{ 'o' ~ nested.nullVar |default('k') }} +Object methods: +{{ object.foo |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ object.undefinedMethod |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ object.getFoo() |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ object.getFoo('a') |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ object.undefinedMethod() |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ object.undefinedMethod('a') |default('default') is same as('default') ? 'ok' : 'ko' }} +Deep nested: +{{ nested.undefinedVar.foo.bar |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ nested.definedArray.0 |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ nested['definedArray'][0] |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ object.self.foo |default('default') is same as('default') ? 'ko' : 'ok' }} +{{ object.self.undefinedMethod |default('default') is same as('default') ? 'ok' : 'ko' }} +{{ object.undefinedMethod.self |default('default') is same as('default') ? 'ok' : 'ko' }} +--DATA-- +return array( + 'definedVar' => 'defined', + 'zeroVar' => 0, + 'emptyVar' => '', + 'nullVar' => null, + 'nested' => array( + 'definedVar' => 'defined', + 'zeroVar' => 0, + 'emptyVar' => '', + 'nullVar' => null, + 'definedArray' => array(0), + ), + 'object' => new TwigTestFoo(), +) +--CONFIG-- +return array('strict_variables' => false) +--EXPECT-- +Variable: +ok +ok +ok +ok +ok +Array access: +ok +ok +ok +ok +ok +ok +ok +ok +Plain values: +ok +ok +ok +ok +Precedence: +ok +ok +Object methods: +ok +ok +ok +ok +ok +ok +Deep nested: +ok +ok +ok +ok +ok +ok +--DATA-- +return array( + 'definedVar' => 'defined', + 'zeroVar' => 0, + 'emptyVar' => '', + 'nullVar' => null, + 'nested' => array( + 'definedVar' => 'defined', + 'zeroVar' => 0, + 'emptyVar' => '', + 'nullVar' => null, + 'definedArray' => array(0), + ), + 'object' => new TwigTestFoo(), +) +--CONFIG-- +return array('strict_variables' => true) +--EXPECT-- +Variable: +ok +ok +ok +ok +ok +Array access: +ok +ok +ok +ok +ok +ok +ok +ok +Plain values: +ok +ok +ok +ok +Precedence: +ok +ok +Object methods: +ok +ok +ok +ok +ok +ok +Deep nested: +ok +ok +ok +ok +ok +ok diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/dynamic_filter.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/dynamic_filter.test new file mode 100644 index 000000000..93c5913f2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/dynamic_filter.test @@ -0,0 +1,10 @@ +--TEST-- +dynamic filter +--TEMPLATE-- +{{ 'bar'|foo_path }} +{{ 'bar'|a_foo_b_bar }} +--DATA-- +return array() +--EXPECT-- +foo/bar +a/b/bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape.test new file mode 100644 index 000000000..a606c1065 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape.test @@ -0,0 +1,8 @@ +--TEST-- +"escape" filter +--TEMPLATE-- +{{ "foo
    "|e }} +--DATA-- +return array() +--EXPECT-- +foo <br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_html_attr.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_html_attr.test new file mode 100644 index 000000000..009a24532 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_html_attr.test @@ -0,0 +1,8 @@ +--TEST-- +"escape" filter does not escape with the html strategy when using the html_attr strategy +--TEMPLATE-- +{{ '
    '|escape('html_attr') }} +--DATA-- +return array() +--EXPECT-- +<br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_javascript.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_javascript.test new file mode 100644 index 000000000..647147a43 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_javascript.test @@ -0,0 +1,8 @@ +--TEST-- +"escape" filter +--TEMPLATE-- +{{ "é ♜ 𝌆"|e('js') }} +--DATA-- +return array() +--EXPECT-- +\u00E9\x20\u265C\x20\uD834\uDF06 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_non_supported_charset.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_non_supported_charset.test new file mode 100644 index 000000000..bba26a0df --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/escape_non_supported_charset.test @@ -0,0 +1,8 @@ +--TEST-- +"escape" filter +--TEMPLATE-- +{{ "愛していますか?
    "|e }} +--DATA-- +return array() +--EXPECT-- +愛していますか? <br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/first.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/first.test new file mode 100644 index 000000000..aa54645c3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/first.test @@ -0,0 +1,17 @@ +--TEST-- +"first" filter +--TEMPLATE-- +{{ [1, 2, 3, 4]|first }} +{{ {a: 1, b: 2, c: 3, d: 4}|first }} +{{ '1234'|first }} +{{ arr|first }} +{{ 'Ä€é'|first }} +{{ ''|first }} +--DATA-- +return array('arr' => new ArrayObject(array(1, 2, 3, 4))) +--EXPECT-- +1 +1 +1 +1 +Ä diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/force_escape.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/force_escape.test new file mode 100644 index 000000000..85a9b7172 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/force_escape.test @@ -0,0 +1,18 @@ +--TEST-- +"escape" filter +--TEMPLATE-- +{% set foo %} + foo
    +{% endset %} + +{{ foo|e('html') -}} +{{ foo|e('js') }} +{% autoescape true %} + {{ foo }} +{% endautoescape %} +--DATA-- +return array() +--EXPECT-- + foo<br /> +\x20\x20\x20\x20foo\x3Cbr\x20\x2F\x3E\x0A + foo
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/format.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/format.test new file mode 100644 index 000000000..97221ff80 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/format.test @@ -0,0 +1,8 @@ +--TEST-- +"format" filter +--TEMPLATE-- +{{ string|format(foo, 3) }} +--DATA-- +return array('string' => '%s/%d', 'foo' => 'bar') +--EXPECT-- +bar/3 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/join.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/join.test new file mode 100644 index 000000000..b342c174c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/join.test @@ -0,0 +1,12 @@ +--TEST-- +"join" filter +--TEMPLATE-- +{{ ["foo", "bar"]|join(', ') }} +{{ foo|join(', ') }} +{{ bar|join(', ') }} +--DATA-- +return array('foo' => new TwigTestFoo(), 'bar' => new ArrayObject(array(3, 4))) +--EXPECT-- +foo, bar +1, 2 +3, 4 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/json_encode.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/json_encode.test new file mode 100644 index 000000000..1738d40cd --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/json_encode.test @@ -0,0 +1,12 @@ +--TEST-- +"json_encode" filter +--TEMPLATE-- +{{ "foo"|json_encode|raw }} +{{ foo|json_encode|raw }} +{{ [foo, "foo"]|json_encode|raw }} +--DATA-- +return array('foo' => new Twig_Markup('foo', 'UTF-8')) +--EXPECT-- +"foo" +"foo" +["foo","foo"] diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/last.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/last.test new file mode 100644 index 000000000..1b8031ee8 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/last.test @@ -0,0 +1,17 @@ +--TEST-- +"last" filter +--TEMPLATE-- +{{ [1, 2, 3, 4]|last }} +{{ {a: 1, b: 2, c: 3, d: 4}|last }} +{{ '1234'|last }} +{{ arr|last }} +{{ 'Ä€é'|last }} +{{ ''|last }} +--DATA-- +return array('arr' => new ArrayObject(array(1, 2, 3, 4))) +--EXPECT-- +4 +4 +4 +4 +é diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/length.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/length.test new file mode 100644 index 000000000..a7f1e5031 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/length.test @@ -0,0 +1,31 @@ +--TEST-- +"length" filter +--TEMPLATE-- +{{ array|length }} +{{ string|length }} +{{ number|length }} +{{ to_string_able|length }} +{{ countable|length }} +{{ null|length }} +{{ magic|length }} +{{ non_countable|length }} +--DATA-- +return array( + 'array' => array(1, 4), + 'string' => 'foo', + 'number' => 1000, + 'to_string_able' => new ToStringStub('foobar'), + 'countable' => new CountableStub(42), /* also asserts we do *not* call __toString() */ + 'null' => null, + 'magic' => new MagicCallStub(), /* used to assert we do *not* call __call */ + 'non_countable' => new \StdClass(), +); +--EXPECT-- +2 +3 +4 +6 +42 +0 +1 +1 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/length_utf8.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/length_utf8.test new file mode 100644 index 000000000..5d5e24361 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/length_utf8.test @@ -0,0 +1,12 @@ +--TEST-- +"length" filter +--CONDITION-- +function_exists('mb_get_info') +--TEMPLATE-- +{{ string|length }} +{{ markup|length }} +--DATA-- +return array('string' => 'été', 'markup' => new Twig_Markup('foo', 'UTF-8')) +--EXPECT-- +3 +3 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/merge.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/merge.test new file mode 100644 index 000000000..81371a41b --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/merge.test @@ -0,0 +1,18 @@ +--TEST-- +"merge" filter +--TEMPLATE-- +{{ items|merge({'bar': 'foo'})|join }} +{{ items|merge({'bar': 'foo'})|keys|join }} +{{ {'bar': 'foo'}|merge(items)|join }} +{{ {'bar': 'foo'}|merge(items)|keys|join }} +{{ numerics|merge([4, 5, 6])|join }} +{{ traversable.a|merge(traversable.b)|join }} +--DATA-- +return array('items' => array('foo' => 'bar'), 'numerics' => array(1, 2, 3), 'traversable' => array('a' => new ArrayObject(array(0 => 1, 1 => 2, 2 => 3)), 'b' => new ArrayObject(array('a' => 'b')))) +--EXPECT-- +barfoo +foobar +foobar +barfoo +123456 +123b diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/nl2br.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/nl2br.test new file mode 100644 index 000000000..6545a9bb0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/nl2br.test @@ -0,0 +1,14 @@ +--TEST-- +"nl2br" filter +--TEMPLATE-- +{{ "I like Twig.\nYou will like it too.\n\nEverybody like it!"|nl2br }} +{{ text|nl2br }} +--DATA-- +return array('text' => "If you have some HTML\nit will be escaped.") +--EXPECT-- +I like Twig.
    +You will like it too.
    +
    +Everybody like it! +If you have some <strong>HTML</strong>
    +it will be escaped. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format.test new file mode 100644 index 000000000..639a8659f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format.test @@ -0,0 +1,18 @@ +--TEST-- +"number_format" filter +--TEMPLATE-- +{{ 20|number_format }} +{{ 20.25|number_format }} +{{ 20.25|number_format(2) }} +{{ 20.25|number_format(2, ',') }} +{{ 1020.25|number_format(2, ',') }} +{{ 1020.25|number_format(2, ',', '.') }} +--DATA-- +return array(); +--EXPECT-- +20 +20 +20.25 +20,25 +1,020,25 +1.020,25 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test new file mode 100644 index 000000000..65c1cdb48 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test @@ -0,0 +1,21 @@ +--TEST-- +"number_format" filter with defaults. +--TEMPLATE-- +{{ 20|number_format }} +{{ 20.25|number_format }} +{{ 20.25|number_format(1) }} +{{ 20.25|number_format(2, ',') }} +{{ 1020.25|number_format }} +{{ 1020.25|number_format(2, ',') }} +{{ 1020.25|number_format(2, ',', '.') }} +--DATA-- +$twig->getExtension('Twig_Extension_Core')->setNumberFormat(2, '!', '='); +return array(); +--EXPECT-- +20!00 +20!25 +20!3 +20,25 +1=020!25 +1=020,25 +1.020,25 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace.test new file mode 100644 index 000000000..06be7e270 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace.test @@ -0,0 +1,12 @@ +--TEST-- +"replace" filter +--TEMPLATE-- +{{ "I liké %this% and %that%."|replace({'%this%': "foo", '%that%': "bar"}) }} +{{ 'I like single replace operation only %that%'|replace({'%that%' : '%that%1'}) }} +{{ 'I like %this% and %that%.'|replace(traversable) }} +--DATA-- +return array('traversable' => new ArrayObject(array('%this%' => 'foo', '%that%' => 'bar'))) +--EXPECT-- +I liké foo and bar. +I like single replace operation only %that%1 +I like foo and bar. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace_invalid_arg.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace_invalid_arg.test new file mode 100644 index 000000000..2143a8690 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/replace_invalid_arg.test @@ -0,0 +1,8 @@ +--TEST-- +Exception for invalid argument type in replace call +--TEMPLATE-- +{{ 'test %foo%'|replace(stdClass) }} +--DATA-- +return array('stdClass' => new stdClass()) +--EXCEPTION-- +Twig_Error_Runtime: The "replace" filter expects an array or "Traversable" as replace values, got "stdClass" in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/reverse.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/reverse.test new file mode 100644 index 000000000..7948ac45f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/reverse.test @@ -0,0 +1,18 @@ +--TEST-- +"reverse" filter +--TEMPLATE-- +{{ [1, 2, 3, 4]|reverse|join('') }} +{{ '1234évènement'|reverse }} +{{ arr|reverse|join('') }} +{{ {'a': 'c', 'b': 'a'}|reverse()|join(',') }} +{{ {'a': 'c', 'b': 'a'}|reverse(preserveKeys=true)|join(glue=',') }} +{{ {'a': 'c', 'b': 'a'}|reverse(preserve_keys=true)|join(glue=',') }} +--DATA-- +return array('arr' => new ArrayObject(array(1, 2, 3, 4))) +--EXPECT-- +4321 +tnemenèvé4321 +4321 +a,c +a,c +a,c diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/round.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/round.test new file mode 100644 index 000000000..57806b619 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/round.test @@ -0,0 +1,22 @@ +--TEST-- +"round" filter +--TEMPLATE-- +{{ 2.7|round }} +{{ 2.1|round }} +{{ 2.1234|round(3, 'floor') }} +{{ 2.1|round(0, 'ceil') }} + +{{ 21.3|round(-1)}} +{{ 21.3|round(-1, 'ceil')}} +{{ 21.3|round(-1, 'floor')}} +--DATA-- +return array() +--EXPECT-- +3 +2 +2.123 +3 + +20 +30 +20 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/slice.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/slice.test new file mode 100644 index 000000000..b49b89fe5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/slice.test @@ -0,0 +1,54 @@ +--TEST-- +"slice" filter +--TEMPLATE-- +{{ [1, 2, 3, 4][1:2]|join('') }} +{{ {a: 1, b: 2, c: 3, d: 4}[1:2]|join('') }} +{{ [1, 2, 3, 4][start:length]|join('') }} +{{ [1, 2, 3, 4]|slice(1, 2)|join('') }} +{{ [1, 2, 3, 4]|slice(1, 2)|keys|join('') }} +{{ [1, 2, 3, 4]|slice(1, 2, true)|keys|join('') }} +{{ {a: 1, b: 2, c: 3, d: 4}|slice(1, 2)|join('') }} +{{ {a: 1, b: 2, c: 3, d: 4}|slice(1, 2)|keys|join('') }} +{{ '1234'|slice(1, 2) }} +{{ '1234'[1:2] }} +{{ arr|slice(1, 2)|join('') }} +{{ arr[1:2]|join('') }} +{{ arr[4:1]|join('') }} +{{ arr[3:2]|join('') }} + +{{ [1, 2, 3, 4]|slice(1)|join('') }} +{{ [1, 2, 3, 4][1:]|join('') }} +{{ '1234'|slice(1) }} +{{ '1234'[1:] }} +{{ '1234'[:1] }} + +{{ arr|slice(3)|join('') }} +{{ arr[2:]|join('') }} +{{ xml|slice(1)|join('')}} +--DATA-- +return array('start' => 1, 'length' => 2, 'arr' => new ArrayObject(array(1, 2, 3, 4)), 'xml' => new SimpleXMLElement('12')) +--EXPECT-- +23 +23 +23 +23 +01 +12 +23 +bc +23 +23 +23 +23 + +4 + +234 +234 +234 +234 +1 + +4 +34 +2 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/sort.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/sort.test new file mode 100644 index 000000000..c67c18ea9 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/sort.test @@ -0,0 +1,12 @@ +--TEST-- +"sort" filter +--TEMPLATE-- +{{ array1|sort|join }} +{{ array2|sort|join }} +{{ traversable|sort|join }} +--DATA-- +return array('array1' => array(4, 1), 'array2' => array('foo', 'bar'), 'traversable' => new ArrayObject(array(0 => 3, 1 => 2, 2 => 1))) +--EXPECT-- +14 +barfoo +123 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/special_chars.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/special_chars.test new file mode 100644 index 000000000..dbaf7dc97 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/special_chars.test @@ -0,0 +1,8 @@ +--TEST-- +"§" custom filter +--TEMPLATE-- +{{ 'foo'|§ }} +--DATA-- +return array() +--EXPECT-- +§foo§ diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/split.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/split.test new file mode 100644 index 000000000..a093ed79b --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/split.test @@ -0,0 +1,20 @@ +--TEST-- +"split" filter +--TEMPLATE-- +{{ "one,two,three,four,five"|split(',')|join('-') }} +{{ foo|split(',')|join('-') }} +{{ foo|split(',', 3)|join('-') }} +{{ baz|split('')|join('-') }} +{{ baz|split('', 1)|join('-') }} +{{ baz|split('', 2)|join('-') }} +{{ foo|split(',', -2)|join('-') }} +--DATA-- +return array('foo' => "one,two,three,four,five", 'baz' => '12345',) +--EXPECT-- +one-two-three-four-five +one-two-three-four-five +one-two-three,four,five +1-2-3-4-5 +1-2-3-4-5 +12-34-5 +one-two-three \ No newline at end of file diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/split_utf8.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/split_utf8.test new file mode 100644 index 000000000..305e162fe --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/split_utf8.test @@ -0,0 +1,24 @@ +--TEST-- +"split" filter +--CONDITION-- +function_exists('mb_get_info') +--TEMPLATE-- +{{ "é"|split('', 10)|join('-') }} +{{ foo|split(',')|join('-') }} +{{ foo|split(',', 1)|join('-') }} +{{ foo|split(',', 2)|join('-') }} +{{ foo|split(',', 3)|join('-') }} +{{ baz|split('')|join('-') }} +{{ baz|split('', 1)|join('-') }} +{{ baz|split('', 2)|join('-') }} +--DATA-- +return array('foo' => 'Ä,é,Äほ', 'baz' => 'éÄßごa',) +--EXPECT-- +é +Ä-é-Äほ +Ä,é,Äほ +Ä-é,Äほ +Ä-é-Äほ +é-Ä-ß-ご-a +é-Ä-ß-ご-a +éÄ-ßご-a \ No newline at end of file diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/static_calls.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/static_calls.test new file mode 100644 index 000000000..4e17b7726 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/static_calls.test @@ -0,0 +1,10 @@ +--TEST-- +Filters as static method calls +--TEMPLATE-- +{{ 'foo'|static_call_string }} +{{ 'foo'|static_call_array }} +--DATA-- +return array('foo' => 'foo') +--EXPECT-- +*foo* +*foo* diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/trim.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/trim.test new file mode 100644 index 000000000..b1ef7b473 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/trim.test @@ -0,0 +1,24 @@ +--TEST-- +"trim" filter +--TEMPLATE-- +{{ " I like Twig. "|trim }} +{{ text|trim }} +{{ " foo/"|trim("/") }} +{{ "xxxI like Twig.xxx"|trim(character_mask="x", side="left") }} +{{ "xxxI like Twig.xxx"|trim(side="right", character_mask="x") }} +{{ "xxxI like Twig.xxx"|trim("x", "right") }} +{{ "/ foo/"|trim("/", "left") }} +{{ "/ foo/"|trim(character_mask="/", side="left") }} +{{ " do nothing. "|trim("", "right") }} +--DATA-- +return array('text' => " If you have some HTML it will be escaped. ") +--EXPECT-- +I like Twig. +If you have some <strong>HTML</strong> it will be escaped. + foo +I like Twig.xxx +xxxI like Twig. +xxxI like Twig. + foo/ + foo/ + do nothing. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/urlencode.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/urlencode.test new file mode 100644 index 000000000..8726159db --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/urlencode.test @@ -0,0 +1,16 @@ +--TEST-- +"url_encode" filter +--CONDITION-- +defined('PHP_QUERY_RFC3986') +--TEMPLATE-- +{{ {foo: "bar", number: 3, "spéßi%l": "e%c0d@d", "spa ce": ""}|url_encode }} +{{ {foo: "bar", number: 3, "spéßi%l": "e%c0d@d", "spa ce": ""}|url_encode|raw }} +{{ {}|url_encode|default("default") }} +{{ 'spéßi%le%c0d@dspa ce'|url_encode }} +--DATA-- +return array() +--EXPECT-- +foo=bar&number=3&sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&spa%20ce= +foo=bar&number=3&sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&spa%20ce= +default +sp%C3%A9%C3%9Fi%25le%25c0d%40dspa%20ce diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/urlencode_deprecated.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/urlencode_deprecated.test new file mode 100644 index 000000000..35e50390d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/urlencode_deprecated.test @@ -0,0 +1,16 @@ +--TEST-- +"url_encode" filter for PHP < 5.4 +--CONDITION-- +defined('PHP_QUERY_RFC3986') +--TEMPLATE-- +{{ {foo: "bar", number: 3, "spéßi%l": "e%c0d@d", "spa ce": ""}|url_encode }} +{{ {foo: "bar", number: 3, "spéßi%l": "e%c0d@d", "spa ce": ""}|url_encode|raw }} +{{ {}|url_encode|default("default") }} +{{ 'spéßi%le%c0d@dspa ce'|url_encode }} +--DATA-- +return array() +--EXPECT-- +foo=bar&number=3&sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&spa%20ce= +foo=bar&number=3&sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&spa%20ce= +default +sp%C3%A9%C3%9Fi%25le%25c0d%40dspa%20ce diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/attribute.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/attribute.test new file mode 100644 index 000000000..71b2038aa --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/attribute.test @@ -0,0 +1,18 @@ +--TEST-- +"attribute" function +--TEMPLATE-- +{{ attribute(obj, method) }} +{{ attribute(array, item) }} +{{ attribute(obj, "bar", ["a", "b"]) }} +{{ attribute(obj, "bar", arguments) }} +{{ attribute(obj, method) is defined ? 'ok' : 'ko' }} +{{ attribute(obj, nonmethod) is defined ? 'ok' : 'ko' }} +--DATA-- +return array('obj' => new TwigTestFoo(), 'method' => 'foo', 'array' => array('foo' => 'bar'), 'item' => 'foo', 'nonmethod' => 'xxx', 'arguments' => array('a', 'b')) +--EXPECT-- +foo +bar +bar_a-b +bar_a-b +ok +ko diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block.test new file mode 100644 index 000000000..8e54059ae --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block.test @@ -0,0 +1,12 @@ +--TEST-- +"block" function +--TEMPLATE-- +{% extends 'base.twig' %} +{% block bar %}BAR{% endblock %} +--TEMPLATE(base.twig)-- +{% block foo %}{{ block('bar') }}{% endblock %} +{% block bar %}BAR_BASE{% endblock %} +--DATA-- +return array() +--EXPECT-- +BARBAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block_with_template.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block_with_template.test new file mode 100644 index 000000000..8305eb67f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block_with_template.test @@ -0,0 +1,22 @@ +--TEST-- +"block" function with a template argument +--TEMPLATE-- +{{ block('foo', 'included.twig') }} +{{ block('foo', included_loaded) }} +{{ block('foo', included_loaded_internal) }} +{% set output = block('foo', 'included.twig') %} +{{ output }} +{% block foo %}NOT FOO{% endblock %} +--TEMPLATE(included.twig)-- +{% block foo %}FOO{% endblock %} +--DATA-- +return array( + 'included_loaded' => $twig->load('included.twig'), + 'included_loaded_internal' => $twig->loadTemplate('included.twig'), +) +--EXPECT-- +FOO +FOO +FOO +FOO +NOT FOO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block_without_name.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block_without_name.test new file mode 100644 index 000000000..665cc87e5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/block_without_name.test @@ -0,0 +1,12 @@ +--TEST-- +"block" function without arguments +--TEMPLATE-- +{% extends 'base.twig' %} +{% block bar %}BAR{% endblock %} +--TEMPLATE(base.twig)-- +{% block foo %}{{ block() }}{% endblock %} +{% block bar %}BAR_BASE{% endblock %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: The "block" function takes one argument (the block name) in "base.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/constant.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/constant.test new file mode 100644 index 000000000..63128791f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/constant.test @@ -0,0 +1,10 @@ +--TEST-- +"constant" function +--TEMPLATE-- +{{ constant('DATE_W3C') == expect ? 'true' : 'false' }} +{{ constant('ARRAY_AS_PROPS', object) }} +--DATA-- +return array('expect' => DATE_W3C, 'object' => new ArrayObject(array('hi'))); +--EXPECT-- +true +2 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/cycle.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/cycle.test new file mode 100644 index 000000000..522a63b85 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/cycle.test @@ -0,0 +1,16 @@ +--TEST-- +"cycle" function +--TEMPLATE-- +{% for i in 0..6 %} +{{ cycle(array1, i) }}-{{ cycle(array2, i) }} +{% endfor %} +--DATA-- +return array('array1' => array('odd', 'even'), 'array2' => array('apple', 'orange', 'citrus')) +--EXPECT-- +odd-apple +even-orange +odd-citrus +even-apple +odd-orange +even-citrus +odd-apple diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date.test new file mode 100644 index 000000000..c9f464468 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date.test @@ -0,0 +1,27 @@ +--TEST-- +"date" function +--TEMPLATE-- +{{ date().format('r') == date('now').format('r') ? 'OK' : 'KO' }} +{{ date(date1) == date('2010-10-04 13:45') ? 'OK' : 'KO' }} +{{ date(date2) == date('2010-10-04 13:45') ? 'OK' : 'KO' }} +{{ date(date3) == date('2010-10-04 13:45') ? 'OK' : 'KO' }} +{{ date(date4) == date('2010-10-04 13:45') ? 'OK' : 'KO' }} +{{ date(date5) == date('1964-01-02 03:04') ? 'OK' : 'KO' }} +{{ date() > date('-1day') ? 'OK' : 'KO' }} +--DATA-- +date_default_timezone_set('UTC'); +return array( + 'date1' => mktime(13, 45, 0, 10, 4, 2010), + 'date2' => new DateTime('2010-10-04 13:45'), + 'date3' => '2010-10-04 13:45', + 'date4' => 1286199900, // DateTime::createFromFormat('Y-m-d H:i', '2010-10-04 13:45', new DateTimeZone('UTC'))->getTimestamp() -- A unixtimestamp is always GMT + 'date5' => -189291360, // DateTime::createFromFormat('Y-m-d H:i', '1964-01-02 03:04', new DateTimeZone('UTC'))->getTimestamp(), +) +--EXPECT-- +OK +OK +OK +OK +OK +OK +OK diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date_namedargs.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date_namedargs.test new file mode 100644 index 000000000..b9dd9e383 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/date_namedargs.test @@ -0,0 +1,11 @@ +--TEST-- +"date" function +--TEMPLATE-- +{{ date(date, "America/New_York")|date('d/m/Y H:i:s P', false) }} +{{ date(timezone="America/New_York", date=date)|date('d/m/Y H:i:s P', false) }} +--DATA-- +date_default_timezone_set('UTC'); +return array('date' => mktime(13, 45, 0, 10, 4, 2010)) +--EXPECT-- +04/10/2010 09:45:00 -04:00 +04/10/2010 09:45:00 -04:00 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dump.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dump.test new file mode 100644 index 000000000..f4072375a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dump.test @@ -0,0 +1,16 @@ +--TEST-- +"dump" function +--CONDITION-- +!extension_loaded('xdebug') +--TEMPLATE-- +{{ dump('foo') }} +{{ dump('foo', 'bar') }} +--DATA-- +return array('foo' => 'foo', 'bar' => 'bar') +--CONFIG-- +return array('debug' => true, 'autoescape' => false); +--EXPECT-- +string(3) "foo" + +string(3) "foo" +string(3) "bar" diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dump_array.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dump_array.test new file mode 100644 index 000000000..889b7a922 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dump_array.test @@ -0,0 +1,19 @@ +--TEST-- +"dump" function, xdebug is not loaded or xdebug <2.2-dev is loaded +--CONDITION-- +!extension_loaded('xdebug') || (($r = new ReflectionExtension('xdebug')) && version_compare($r->getVersion(), '2.2-dev', '<')) +--TEMPLATE-- +{{ dump() }} +--DATA-- +return array('foo' => 'foo', 'bar' => 'bar') +--CONFIG-- +return array('debug' => true, 'autoescape' => false); +--EXPECT-- +array(3) { + ["foo"]=> + string(3) "foo" + ["bar"]=> + string(3) "bar" + ["global"]=> + string(6) "global" +} diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dynamic_function.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dynamic_function.test new file mode 100644 index 000000000..913fbc995 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/dynamic_function.test @@ -0,0 +1,10 @@ +--TEST-- +dynamic function +--TEMPLATE-- +{{ foo_path('bar') }} +{{ a_foo_b_bar('bar') }} +--DATA-- +return array() +--EXPECT-- +foo/bar +a/b/bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/assignment.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/assignment.test new file mode 100644 index 000000000..b7653b4ef --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/assignment.test @@ -0,0 +1,13 @@ +--TEST-- +"include" function +--TEMPLATE-- +{% set tmp = include("foo.twig") %} + +FOO{{ tmp }}BAR +--TEMPLATE(foo.twig)-- +FOOBAR +--DATA-- +return array() +--EXPECT-- +FOO +FOOBARBAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/autoescaping.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/autoescaping.test new file mode 100644 index 000000000..56f8f3b5a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/autoescaping.test @@ -0,0 +1,10 @@ +--TEST-- +"include" function is safe for auto-escaping +--TEMPLATE-- +{{ include("foo.twig") }} +--TEMPLATE(foo.twig)-- +

    Test

    +--DATA-- +return array() +--EXPECT-- +

    Test

    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/basic.test new file mode 100644 index 000000000..a434182a2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/basic.test @@ -0,0 +1,17 @@ +--TEST-- +"include" function +--TEMPLATE-- +FOO +{{ include("foo.twig") }} + +BAR +--TEMPLATE(foo.twig)-- +FOOBAR +--DATA-- +return array() +--EXPECT-- +FOO + +FOOBAR + +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/expression.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/expression.test new file mode 100644 index 000000000..aba30ce3f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/expression.test @@ -0,0 +1,17 @@ +--TEST-- +"include" function allows expressions for the template to include +--TEMPLATE-- +FOO +{{ include(foo) }} + +BAR +--TEMPLATE(foo.twig)-- +FOOBAR +--DATA-- +return array('foo' => 'foo.twig') +--EXPECT-- +FOO + +FOOBAR + +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/ignore_missing.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/ignore_missing.test new file mode 100644 index 000000000..43a2ccc2c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/ignore_missing.test @@ -0,0 +1,10 @@ +--TEST-- +"include" function +--TEMPLATE-- +{{ include(["foo.twig", "bar.twig"], ignore_missing = true) }} +{{ include("foo.twig", ignore_missing = true) }} +{{ include("foo.twig", ignore_missing = true, variables = {}) }} +{{ include("foo.twig", ignore_missing = true, variables = {}, with_context = true) }} +--DATA-- +return array() +--EXPECT-- diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing.test new file mode 100644 index 000000000..4d2f6cf13 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing.test @@ -0,0 +1,8 @@ +--TEST-- +"include" function +--TEMPLATE-- +{{ include("foo.twig") }} +--DATA-- +return array(); +--EXCEPTION-- +Twig_Error_Loader: Template "foo.twig" is not defined in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing_nested.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing_nested.test new file mode 100644 index 000000000..78fddc7a6 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/missing_nested.test @@ -0,0 +1,16 @@ +--TEST-- +"include" function +--TEMPLATE-- +{% extends "base.twig" %} + +{% block content %} + {{ parent() }} +{% endblock %} +--TEMPLATE(base.twig)-- +{% block content %} + {{ include("foo.twig") }} +{% endblock %} +--DATA-- +return array(); +--EXCEPTION-- +Twig_Error_Loader: Template "foo.twig" is not defined in "base.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox.test new file mode 100644 index 000000000..7b9ccaca8 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox.test @@ -0,0 +1,13 @@ +--TEST-- +"include" tag sandboxed +--TEMPLATE-- +{{ include("foo.twig", sandboxed = true) }} +--TEMPLATE(foo.twig)-- + + +{{ foo|e }} +{{ foo|e }} +--DATA-- +return array() +--EXCEPTION-- +Twig_Sandbox_SecurityNotAllowedFilterError: Filter "e" is not allowed in "foo.twig" at line 4. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling.test new file mode 100644 index 000000000..8ffc49225 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling.test @@ -0,0 +1,16 @@ +--TEST-- +"include" tag sandboxed +--TEMPLATE-- +{{ include("foo.twig", sandboxed = true) }} +{{ include("bar.twig") }} +--TEMPLATE(foo.twig)-- +foo +--TEMPLATE(bar.twig)-- +{{ foo|e }} +--DATA-- +return array('foo' => 'bar
    ') +--EXPECT-- +foo + + +bar<br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling_ignore_missing.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling_ignore_missing.test new file mode 100644 index 000000000..8bf6e102d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/sandbox_disabling_ignore_missing.test @@ -0,0 +1,13 @@ +--TEST-- +"include" tag sandboxed +--TEMPLATE-- +{{ include("unknown.twig", sandboxed = true, ignore_missing = true) }} +{{ include("bar.twig") }} +--TEMPLATE(bar.twig)-- +{{ foo|e }} +--DATA-- +return array('foo' => 'bar
    ') +--EXPECT-- + + +bar<br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/template_instance.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/template_instance.test new file mode 100644 index 000000000..18d405a02 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/template_instance.test @@ -0,0 +1,10 @@ +--TEST-- +"include" function accepts Twig_Template instance +--TEMPLATE-- +{{ include(foo) }} FOO +--TEMPLATE(foo.twig)-- +BAR +--DATA-- +return array('foo' => $twig->loadTemplate('foo.twig')) +--EXPECT-- +BAR FOO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/templates_as_array.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/templates_as_array.test new file mode 100644 index 000000000..1a8100687 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/templates_as_array.test @@ -0,0 +1,12 @@ +--TEST-- +"include" function +--TEMPLATE-- +{{ include(["foo.twig", "bar.twig"]) }} +{{- include(["bar.twig", "foo.twig"]) }} +--TEMPLATE(foo.twig)-- +foo +--DATA-- +return array() +--EXPECT-- +foo +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_context.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_context.test new file mode 100644 index 000000000..35611fbb9 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_context.test @@ -0,0 +1,16 @@ +--TEST-- +"include" function accept variables and with_context +--TEMPLATE-- +{{ include("foo.twig") }} +{{- include("foo.twig", with_context = false) }} +{{- include("foo.twig", {'foo1': 'bar'}) }} +{{- include("foo.twig", {'foo1': 'bar'}, with_context = false) }} +--TEMPLATE(foo.twig)-- +{% for k, v in _context %}{{ k }},{% endfor %} +--DATA-- +return array('foo' => 'bar') +--EXPECT-- +foo,global,_parent, +global,_parent, +foo,global,foo1,_parent, +foo1,global,_parent, diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_variables.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_variables.test new file mode 100644 index 000000000..b2ace940e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/include/with_variables.test @@ -0,0 +1,12 @@ +--TEST-- +"include" function accept variables +--TEMPLATE-- +{{ include("foo.twig", {'foo': 'bar'}) }} +{{- include("foo.twig", vars) }} +--TEMPLATE(foo.twig)-- +{{ foo }} +--DATA-- +return array('vars' => array('foo' => 'bar')) +--EXPECT-- +bar +bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call.test new file mode 100644 index 000000000..933544312 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call.test @@ -0,0 +1,8 @@ +--TEST-- +__call calls +--TEMPLATE-- +{{ 'foo'|magic_call }} +--DATA-- +return array() +--EXPECT-- +magic_foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call53.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call53.test new file mode 100644 index 000000000..a0f55e116 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/magic_call53.test @@ -0,0 +1,12 @@ +--TEST-- +__staticCall calls +--CONDITION-- +version_compare(phpversion(), '5.3.0', '>=') +--TEMPLATE-- +{{ 'foo'|magic_call_string }} +{{ 'foo'|magic_call_array }} +--DATA-- +return array() +--EXPECT-- +static_magic_foo +static_magic_foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/max.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/max.test new file mode 100644 index 000000000..e6c94af63 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/max.test @@ -0,0 +1,12 @@ +--TEST-- +"max" function +--TEMPLATE-- +{{ max([2, 1, 3, 5, 4]) }} +{{ max(2, 1, 3, 5, 4) }} +{{ max({2:"two", 1:"one", 3:"three", 5:"five", 4:"for"}) }} +--DATA-- +return array() +--EXPECT-- +5 +5 +two diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/min.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/min.test new file mode 100644 index 000000000..660471c00 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/min.test @@ -0,0 +1,12 @@ +--TEST-- +"min" function +--TEMPLATE-- +{{ min(2, 1, 3, 5, 4) }} +{{ min([2, 1, 3, 5, 4]) }} +{{ min({2:"two", 1:"one", 3:"three", 5:"five", 4:"for"}) }} +--DATA-- +return array() +--EXPECT-- +1 +1 +five diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/range.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/range.test new file mode 100644 index 000000000..e0377c8d4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/range.test @@ -0,0 +1,8 @@ +--TEST-- +"range" function +--TEMPLATE-- +{{ range(low=0+1, high=10+0, step=2)|join(',') }} +--DATA-- +return array() +--EXPECT-- +1,3,5,7,9 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test new file mode 100644 index 000000000..bf0556d24 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/recursive_block_with_inheritance.test @@ -0,0 +1,21 @@ +--TEST-- +"block" function recursively called in a parent template +--TEMPLATE-- +{% extends "ordered_menu.twig" %} +{% block label %}"{{ parent() }}"{% endblock %} +{% block list %}{% set class = 'b' %}{{ parent() }}{% endblock %} +--TEMPLATE(ordered_menu.twig)-- +{% extends "menu.twig" %} +{% block list %}{% set class = class|default('a') %}
      {{ block('children') }}
    {% endblock %} +--TEMPLATE(menu.twig)-- +{% extends "base.twig" %} +{% block list %}
      {{ block('children') }}
    {% endblock %} +{% block children %}{% set currentItem = item %}{% for item in currentItem %}{{ block('item') }}{% endfor %}{% set item = currentItem %}{% endblock %} +{% block item %}
  • {% if item is not iterable %}{{ block('label') }}{% else %}{{ block('list') }}{% endif %}
  • {% endblock %} +{% block label %}{{ item }}{% endblock %} +--TEMPLATE(base.twig)-- +{{ block('list') }} +--DATA-- +return array('item' => array('1', '2', array('3.1', array('3.2.1', '3.2.2'), '3.4'))) +--EXPECT-- +
    1. "1"
    2. "2"
      1. "3.1"
        1. "3.2.1"
        2. "3.2.2"
      2. "3.4"
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/source.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/source.test new file mode 100644 index 000000000..0e094c3b2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/source.test @@ -0,0 +1,17 @@ +--TEST-- +"source" function +--TEMPLATE-- +FOO +{{ source("foo.twig") }} + +BAR +--TEMPLATE(foo.twig)-- +{{ foo }}
    +--DATA-- +return array() +--EXPECT-- +FOO + +{{ foo }}
    + +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/special_chars.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/special_chars.test new file mode 100644 index 000000000..30c3df516 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/special_chars.test @@ -0,0 +1,8 @@ +--TEST-- +"§" custom function +--TEMPLATE-- +{{ §('foo') }} +--DATA-- +return array() +--EXPECT-- +§foo§ diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/static_calls.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/static_calls.test new file mode 100644 index 000000000..57e5be392 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/static_calls.test @@ -0,0 +1,10 @@ +--TEST-- +Functions as static method calls +--TEMPLATE-- +{{ static_call_string('foo') }} +{{ static_call_array('foo') }} +--DATA-- +return array('foo' => 'foo') +--EXPECT-- +*foo* +*foo* diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/template_from_string.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/template_from_string.test new file mode 100644 index 000000000..3d3b95874 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/functions/template_from_string.test @@ -0,0 +1,15 @@ +--TEST-- +"template_from_string" function +--TEMPLATE-- +{% include template_from_string(template) %} + +{% include template_from_string("Hello {{ name }}") %} +{% include template_from_string('{% extends "parent.twig" %}{% block content %}Hello {{ name }}{% endblock %}') %} +--TEMPLATE(parent.twig)-- +{% block content %}{% endblock %} +--DATA-- +return array('name' => 'Fabien', 'template' => "Hello {{ name }}") +--EXPECT-- +Hello Fabien +Hello Fabien +Hello Fabien diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/default_values.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/default_values.test new file mode 100644 index 000000000..4ccff7b67 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/default_values.test @@ -0,0 +1,16 @@ +--TEST-- +macro +--TEMPLATE-- +{% from _self import test %} + +{% macro test(a, b = 'bar') -%} +{{ a }}{{ b }} +{%- endmacro %} + +{{ test('foo') }} +{{ test('bar', 'foo') }} +--DATA-- +return array(); +--EXPECT-- +foobar +barfoo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/nested_calls.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/nested_calls.test new file mode 100644 index 000000000..cd2542810 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/nested_calls.test @@ -0,0 +1,18 @@ +--TEST-- +macro +--TEMPLATE-- +{% import _self as macros %} + +{% macro foo(data) %} + {{ data }} +{% endmacro %} + +{% macro bar() %} +
    +{% endmacro %} + +{{ macros.foo(macros.bar()) }} +--DATA-- +return array(); +--EXPECT-- +
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/reserved_variables.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/reserved_variables.test new file mode 100644 index 000000000..cbfb921b2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/reserved_variables.test @@ -0,0 +1,14 @@ +--TEST-- +macro +--TEMPLATE-- +{% from _self import test %} + +{% macro test(this) -%} + {{ this }} +{%- endmacro %} + +{{ test(this) }} +--DATA-- +return array('this' => 'foo'); +--EXPECT-- +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/simple.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/simple.test new file mode 100644 index 000000000..6a366cdf1 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/simple.test @@ -0,0 +1,22 @@ +--TEST-- +macro +--TEMPLATE-- +{% import _self as test %} +{% from _self import test %} + +{% macro test(a, b) -%} + {{ a|default('a') }}
    + {{- b|default('b') }}
    +{%- endmacro %} + +{{ test.test() }} +{{ test() }} +{{ test.test(1, "c") }} +{{ test(1, "c") }} +--DATA-- +return array(); +--EXPECT-- +a
    b
    +a
    b
    +1
    c
    +1
    c
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs.test new file mode 100644 index 000000000..412c90fae --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs.test @@ -0,0 +1,21 @@ +--TEST-- +macro with arbitrary arguments +--TEMPLATE-- +{% from _self import test1, test2 %} + +{% macro test1(var) %} + {{- var }}: {{ varargs|join(", ") }} +{% endmacro %} + +{% macro test2() %} + {{- varargs|join(", ") }} +{% endmacro %} + +{{ test1("foo", "bar", "foobar") }} +{{ test2("foo", "bar", "foobar") }} +--DATA-- +return array(); +--EXPECT-- +foo: bar, foobar + +foo, bar, foobar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test new file mode 100644 index 000000000..800c262e7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test @@ -0,0 +1,7 @@ +--TEST-- +macro with varargs argument +--TEMPLATE-- +{% macro test(varargs) %} +{% endmacro %} +--EXCEPTION-- +Twig_Error_Syntax: The argument "varargs" in macro "test" cannot be defined because the variable "varargs" is reserved for arbitrary arguments in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/with_filters.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/with_filters.test new file mode 100644 index 000000000..685626f2a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/with_filters.test @@ -0,0 +1,14 @@ +--TEST-- +macro with a filter +--TEMPLATE-- +{% import _self as test %} + +{% macro test() %} + {% filter escape %}foo
    {% endfilter %} +{% endmacro %} + +{{ test.test() }} +--DATA-- +return array(); +--EXPECT-- +foo<br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/combined_debug_info.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/combined_debug_info.test new file mode 100644 index 000000000..ff977ad62 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/combined_debug_info.test @@ -0,0 +1,15 @@ +--TEST-- +Exception with bad line number +--TEMPLATE-- +{% block content %} + {{ foo }} + {{ include("foo") }} +{% endblock %} +index +--TEMPLATE(foo)-- +foo +{{ foo.bar }} +--DATA-- +return array('foo' => 'foo'); +--EXCEPTION-- +Twig_Error_Runtime: Impossible to access an attribute ("bar") on a string variable ("foo") in "foo" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/empty_token.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/empty_token.test new file mode 100644 index 000000000..65f6cd2b8 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/empty_token.test @@ -0,0 +1,8 @@ +--TEST-- +Twig outputs 0 nodes correctly +--TEMPLATE-- +{{ foo }}0{{ foo }} +--DATA-- +return array('foo' => 'foo') +--EXPECT-- +foo0foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/issue_1143.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/issue_1143.test new file mode 100644 index 000000000..ff7c8bb70 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/issue_1143.test @@ -0,0 +1,23 @@ +--TEST-- +error in twig extension +--TEMPLATE-- +{{ object.region is not null ? object.regionChoices[object.region] }} +--DATA-- +class House +{ + const REGION_S = 1; + const REGION_P = 2; + + public static $regionChoices = array(self::REGION_S => 'house.region.s', self::REGION_P => 'house.region.p'); + + public function getRegionChoices() + { + return self::$regionChoices; + } +} + +$object = new House(); +$object->region = 1; +return array('object' => $object) +--EXPECT-- +house.region.s diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/multi_word_tests.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/multi_word_tests.test new file mode 100644 index 000000000..269a30571 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/multi_word_tests.test @@ -0,0 +1,10 @@ +--TEST-- +Twig allows multi-word tests without a custom node class +--TEMPLATE-- +{{ 'foo' is multi word ? 'yes' : 'no' }} +{{ 'foo bar' is multi word ? 'yes' : 'no' }} +--DATA-- +return array() +--EXPECT-- +no +yes diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/simple_xml_element.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/simple_xml_element.test new file mode 100644 index 000000000..60c3c51d7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/simple_xml_element.test @@ -0,0 +1,19 @@ +--TEST-- +Twig is able to deal with SimpleXMLElement instances as variables +--CONDITION-- +version_compare(phpversion(), '5.3.0', '>=') +--TEMPLATE-- +Hello '{{ images.image.0.group }}'! +{{ images.image.0.group.attributes.myattr }} +{{ images.children().image.count() }} +{% for image in images %} + - {{ image.group }} +{% endfor %} +--DATA-- +return array('images' => new SimpleXMLElement('foobar')) +--EXPECT-- +Hello 'foo'! +example +2 + - foo + - bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/strings_like_numbers.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/strings_like_numbers.test new file mode 100644 index 000000000..e18e11079 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/strings_like_numbers.test @@ -0,0 +1,8 @@ +--TEST-- +Twig does not confuse strings with integers in getAttribute() +--TEMPLATE-- +{{ hash['2e2'] }} +--DATA-- +return array('hash' => array('2e2' => 'works')) +--EXPECT-- +works diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/basic.test new file mode 100644 index 000000000..2f6a3e1a0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/basic.test @@ -0,0 +1,26 @@ +--TEST-- +"autoescape" tag applies escaping on its children +--TEMPLATE-- +{% autoescape %} +{{ var }}
    +{% endautoescape %} +{% autoescape 'html' %} +{{ var }}
    +{% endautoescape %} +{% autoescape false %} +{{ var }}
    +{% endautoescape %} +{% autoescape true %} +{{ var }}
    +{% endautoescape %} +{% autoescape false %} +{{ var }}
    +{% endautoescape %} +--DATA-- +return array('var' => '
    ') +--EXPECT-- +<br />
    +<br />
    +

    +<br />
    +

    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/blocks.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/blocks.test new file mode 100644 index 000000000..05ab83ce3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/blocks.test @@ -0,0 +1,12 @@ +--TEST-- +"autoescape" tag applies escaping on embedded blocks +--TEMPLATE-- +{% autoescape 'html' %} + {% block foo %} + {{ var }} + {% endblock %} +{% endautoescape %} +--DATA-- +return array('var' => '
    ') +--EXPECT-- +<br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/double_escaping.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/double_escaping.test new file mode 100644 index 000000000..9c0972462 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/double_escaping.test @@ -0,0 +1,10 @@ +--TEST-- +"autoescape" tag does not double-escape +--TEMPLATE-- +{% autoescape 'html' %} +{{ var|escape }} +{% endautoescape %} +--DATA-- +return array('var' => '
    ') +--EXPECT-- +<br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test new file mode 100644 index 000000000..ce7ea789e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test @@ -0,0 +1,83 @@ +--TEST-- +"autoescape" tag applies escaping after calling functions +--TEMPLATE-- + +autoescape false +{% autoescape false %} + +safe_br +{{ safe_br() }} + +unsafe_br +{{ unsafe_br() }} + +{% endautoescape %} + +autoescape 'html' +{% autoescape 'html' %} + +safe_br +{{ safe_br() }} + +unsafe_br +{{ unsafe_br() }} + +unsafe_br()|raw +{{ (unsafe_br())|raw }} + +safe_br()|escape +{{ (safe_br())|escape }} + +safe_br()|raw +{{ (safe_br())|raw }} + +unsafe_br()|escape +{{ (unsafe_br())|escape }} + +{% endautoescape %} + +autoescape js +{% autoescape 'js' %} + +safe_br +{{ safe_br() }} + +{% endautoescape %} +--DATA-- +return array() +--EXPECT-- + +autoescape false + +safe_br +
    + +unsafe_br +
    + + +autoescape 'html' + +safe_br +
    + +unsafe_br +<br /> + +unsafe_br()|raw +
    + +safe_br()|escape +<br /> + +safe_br()|raw +
    + +unsafe_br()|escape +<br /> + + +autoescape js + +safe_br +\x3Cbr\x20\x2F\x3E diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/literal.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/literal.test new file mode 100644 index 000000000..e389d4dd5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/literal.test @@ -0,0 +1,45 @@ +--TEST-- +"autoescape" tag does not apply escaping on literals +--TEMPLATE-- +{% autoescape 'html' %} + +1. Simple literal +{{ "
    " }} + +2. Conditional expression with only literals +{{ true ? "
    " : "
    " }} + +3. Conditional expression with a variable +{{ true ? "
    " : someVar }} + +4. Nested conditionals with only literals +{{ true ? (true ? "
    " : "
    ") : "\n" }} + +5. Nested conditionals with a variable +{{ true ? (true ? "
    " : someVar) : "\n" }} + +6. Nested conditionals with a variable marked safe +{{ true ? (true ? "
    " : someVar|raw) : "\n" }} + +{% endautoescape %} +--DATA-- +return array() +--EXPECT-- + +1. Simple literal +
    + +2. Conditional expression with only literals +
    + +3. Conditional expression with a variable +<br /> + +4. Nested conditionals with only literals +
    + +5. Nested conditionals with a variable +<br /> + +6. Nested conditionals with a variable marked safe +
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/nested.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/nested.test new file mode 100644 index 000000000..798e6feaf --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/nested.test @@ -0,0 +1,26 @@ +--TEST-- +"autoescape" tags can be nested at will +--TEMPLATE-- +{{ var }} +{% autoescape 'html' %} + {{ var }} + {% autoescape false %} + {{ var }} + {% autoescape 'html' %} + {{ var }} + {% endautoescape %} + {{ var }} + {% endautoescape %} + {{ var }} +{% endautoescape %} +{{ var }} +--DATA-- +return array('var' => '
    ') +--EXPECT-- +<br /> + <br /> +
    + <br /> +
    + <br /> +<br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/objects.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/objects.test new file mode 100644 index 000000000..e896aa41c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/objects.test @@ -0,0 +1,26 @@ +--TEST-- +"autoescape" tag applies escaping to object method calls +--TEMPLATE-- +{% autoescape 'html' %} +{{ user.name }} +{{ user.name|lower }} +{{ user }} +{% endautoescape %} +--DATA-- +class UserForAutoEscapeTest +{ + public function getName() + { + return 'Fabien
    '; + } + + public function __toString() + { + return 'Fabien
    '; + } +} +return array('user' => new UserForAutoEscapeTest()) +--EXPECT-- +Fabien<br /> +fabien<br /> +Fabien<br /> diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/raw.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/raw.test new file mode 100644 index 000000000..9f1cedd3a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/raw.test @@ -0,0 +1,10 @@ +--TEST-- +"autoescape" tag does not escape when raw is used as a filter +--TEMPLATE-- +{% autoescape 'html' %} +{{ var|raw }} +{% endautoescape %} +--DATA-- +return array('var' => '
    ') +--EXPECT-- +
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.legacy.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.legacy.test new file mode 100644 index 000000000..bbf1356e7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.legacy.test @@ -0,0 +1,11 @@ +--TEST-- +"autoescape" tag accepts an escaping strategy +--TEMPLATE-- +{% autoescape true js %}{{ var }}{% endautoescape %} + +{% autoescape true html %}{{ var }}{% endautoescape %} +--DATA-- +return array('var' => '
    "') +--EXPECT-- +\x3Cbr\x20\x2F\x3E\x22 +<br />" diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test new file mode 100644 index 000000000..e496f6081 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test @@ -0,0 +1,11 @@ +--TEST-- +"autoescape" tag accepts an escaping strategy +--TEMPLATE-- +{% autoescape 'js' %}{{ var }}{% endautoescape %} + +{% autoescape 'html' %}{{ var }}{% endautoescape %} +--DATA-- +return array('var' => '
    "') +--EXPECT-- +\x3Cbr\x20\x2F\x3E\x22 +<br />" diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test new file mode 100644 index 000000000..4f415201d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test @@ -0,0 +1,69 @@ +--TEST-- +escape types +--TEMPLATE-- + +1. autoescape 'html' |escape('js') + +{% autoescape 'html' %} + +{% endautoescape %} + +2. autoescape 'html' |escape('js') + +{% autoescape 'html' %} + +{% endautoescape %} + +3. autoescape 'js' |escape('js') + +{% autoescape 'js' %} + +{% endautoescape %} + +4. no escape + +{% autoescape false %} + +{% endautoescape %} + +5. |escape('js')|escape('html') + +{% autoescape false %} + +{% endautoescape %} + +6. autoescape 'html' |escape('js')|escape('html') + +{% autoescape 'html' %} + +{% endautoescape %} + +--DATA-- +return array('msg' => "<>\n'\"") +--EXPECT-- + +1. autoescape 'html' |escape('js') + + + +2. autoescape 'html' |escape('js') + + + +3. autoescape 'js' |escape('js') + + + +4. no escape + + + +5. |escape('js')|escape('html') + + + +6. autoescape 'html' |escape('js')|escape('html') + + + diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters.test new file mode 100644 index 000000000..7821a9aaf --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters.test @@ -0,0 +1,131 @@ +--TEST-- +"autoescape" tag applies escaping after calling filters +--TEMPLATE-- +{% autoescape 'html' %} + +(escape_and_nl2br is an escaper filter) + +1. Don't escape escaper filter output +( var is escaped by |escape_and_nl2br, line-breaks are added, + the output is not escaped ) +{{ var|escape_and_nl2br }} + +2. Don't escape escaper filter output +( var is escaped by |escape_and_nl2br, line-breaks are added, + the output is not escaped, |raw is redundant ) +{{ var|escape_and_nl2br|raw }} + +3. Explicit escape +( var is escaped by |escape_and_nl2br, line-breaks are added, + the output is explicitly escaped by |escape ) +{{ var|escape_and_nl2br|escape }} + +4. Escape non-escaper filter output +( var is upper-cased by |upper, + the output is auto-escaped ) +{{ var|upper }} + +5. Escape if last filter is not an escaper +( var is escaped by |escape_and_nl2br, line-breaks are added, + the output is upper-cased by |upper, + the output is auto-escaped as |upper is not an escaper ) +{{ var|escape_and_nl2br|upper }} + +6. Don't escape escaper filter output +( var is upper cased by upper, + the output is escaped by |escape_and_nl2br, line-breaks are added, + the output is not escaped as |escape_and_nl2br is an escaper ) +{{ var|upper|escape_and_nl2br }} + +7. Escape if last filter is not an escaper +( the output of |format is "" ~ var ~ "", + the output is auto-escaped ) +{{ "%s"|format(var) }} + +8. Escape if last filter is not an escaper +( the output of |format is "" ~ var ~ "", + |raw is redundant, + the output is auto-escaped ) +{{ "%s"|raw|format(var) }} + +9. Don't escape escaper filter output +( the output of |format is "" ~ var ~ "", + the output is not escaped due to |raw filter at the end ) +{{ "%s"|format(var)|raw }} + +10. Don't escape escaper filter output +( the output of |format is "" ~ var ~ "", + the output is not escaped due to |raw filter at the end, + the |raw filter on var is redundant ) +{{ "%s"|format(var|raw)|raw }} + +{% endautoescape %} +--DATA-- +return array('var' => "\nTwig") +--EXPECT-- + +(escape_and_nl2br is an escaper filter) + +1. Don't escape escaper filter output +( var is escaped by |escape_and_nl2br, line-breaks are added, + the output is not escaped ) +<Fabien>
    +Twig + +2. Don't escape escaper filter output +( var is escaped by |escape_and_nl2br, line-breaks are added, + the output is not escaped, |raw is redundant ) +<Fabien>
    +Twig + +3. Explicit escape +( var is escaped by |escape_and_nl2br, line-breaks are added, + the output is explicitly escaped by |escape ) +&lt;Fabien&gt;<br /> +Twig + +4. Escape non-escaper filter output +( var is upper-cased by |upper, + the output is auto-escaped ) +<FABIEN> +TWIG + +5. Escape if last filter is not an escaper +( var is escaped by |escape_and_nl2br, line-breaks are added, + the output is upper-cased by |upper, + the output is auto-escaped as |upper is not an escaper ) +&LT;FABIEN&GT;<BR /> +TWIG + +6. Don't escape escaper filter output +( var is upper cased by upper, + the output is escaped by |escape_and_nl2br, line-breaks are added, + the output is not escaped as |escape_and_nl2br is an escaper ) +<FABIEN>
    +TWIG + +7. Escape if last filter is not an escaper +( the output of |format is "" ~ var ~ "", + the output is auto-escaped ) +<b><Fabien> +Twig</b> + +8. Escape if last filter is not an escaper +( the output of |format is "" ~ var ~ "", + |raw is redundant, + the output is auto-escaped ) +<b><Fabien> +Twig</b> + +9. Don't escape escaper filter output +( the output of |format is "" ~ var ~ "", + the output is not escaped due to |raw filter at the end ) + +Twig + +10. Don't escape escaper filter output +( the output of |format is "" ~ var ~ "", + the output is not escaped due to |raw filter at the end, + the |raw filter on var is redundant ) + +Twig diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters_arguments.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters_arguments.test new file mode 100644 index 000000000..f58a1e09c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters_arguments.test @@ -0,0 +1,23 @@ +--TEST-- +"autoescape" tag do not applies escaping on filter arguments +--TEMPLATE-- +{% autoescape 'html' %} +{{ var|nl2br("
    ") }} +{{ var|nl2br("
    "|escape) }} +{{ var|nl2br(sep) }} +{{ var|nl2br(sep|raw) }} +{{ var|nl2br(sep|escape) }} +{% endautoescape %} +--DATA-- +return array('var' => "\nTwig", 'sep' => '
    ') +--EXPECT-- +<Fabien>
    +Twig +<Fabien><br /> +Twig +<Fabien>
    +Twig +<Fabien>
    +Twig +<Fabien><br /> +Twig diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_pre_escape_filters.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_pre_escape_filters.test new file mode 100644 index 000000000..134c77ea8 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_pre_escape_filters.test @@ -0,0 +1,68 @@ +--TEST-- +"autoescape" tag applies escaping after calling filters, and before calling pre_escape filters +--TEMPLATE-- +{% autoescape 'html' %} + +(nl2br is pre_escaped for "html" and declared safe for "html") + +1. Pre-escape and don't post-escape +( var|escape|nl2br ) +{{ var|nl2br }} + +2. Don't double-pre-escape +( var|escape|nl2br ) +{{ var|escape|nl2br }} + +3. Don't escape safe values +( var|raw|nl2br ) +{{ var|raw|nl2br }} + +4. Don't escape safe values +( var|escape|nl2br|nl2br ) +{{ var|nl2br|nl2br }} + +5. Re-escape values that are escaped for an other contexts +( var|escape_something|escape|nl2br ) +{{ var|escape_something|nl2br }} + +6. Still escape when using filters not declared safe +( var|escape|nl2br|upper|escape ) +{{ var|nl2br|upper }} + +{% endautoescape %} +--DATA-- +return array('var' => "\nTwig") +--EXPECT-- + +(nl2br is pre_escaped for "html" and declared safe for "html") + +1. Pre-escape and don't post-escape +( var|escape|nl2br ) +<Fabien>
    +Twig + +2. Don't double-pre-escape +( var|escape|nl2br ) +<Fabien>
    +Twig + +3. Don't escape safe values +( var|raw|nl2br ) +
    +Twig + +4. Don't escape safe values +( var|escape|nl2br|nl2br ) +<Fabien>

    +Twig + +5. Re-escape values that are escaped for an other contexts +( var|escape_something|escape|nl2br ) +<FABIEN>
    +TWIG + +6. Still escape when using filters not declared safe +( var|escape|nl2br|upper|escape ) +&LT;FABIEN&GT;<BR /> +TWIG + diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_preserves_safety_filters.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_preserves_safety_filters.test new file mode 100644 index 000000000..32d3943b5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_preserves_safety_filters.test @@ -0,0 +1,50 @@ +--TEST-- +"autoescape" tag handles filters preserving the safety +--TEMPLATE-- +{% autoescape 'html' %} + +(preserves_safety is preserving safety for "html") + +1. Unsafe values are still unsafe +( var|preserves_safety|escape ) +{{ var|preserves_safety }} + +2. Safe values are still safe +( var|escape|preserves_safety ) +{{ var|escape|preserves_safety }} + +3. Re-escape values that are escaped for an other contexts +( var|escape_something|preserves_safety|escape ) +{{ var|escape_something|preserves_safety }} + +4. Still escape when using filters not declared safe +( var|escape|preserves_safety|replace({'FABIEN': 'FABPOT'})|escape ) +{{ var|escape|preserves_safety|replace({'FABIEN': 'FABPOT'}) }} + +{% endautoescape %} +--DATA-- +return array('var' => "\nTwig") +--EXPECT-- + +(preserves_safety is preserving safety for "html") + +1. Unsafe values are still unsafe +( var|preserves_safety|escape ) +<FABIEN> +TWIG + +2. Safe values are still safe +( var|escape|preserves_safety ) +<FABIEN> +TWIG + +3. Re-escape values that are escaped for an other contexts +( var|escape_something|preserves_safety|escape ) +<FABIEN> +TWIG + +4. Still escape when using filters not declared safe +( var|escape|preserves_safety|replace({'FABIEN': 'FABPOT'})|escape ) +&LT;FABPOT&GT; +TWIG + diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/basic.test new file mode 100644 index 000000000..360dcf030 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/basic.test @@ -0,0 +1,11 @@ +--TEST-- +"block" tag +--TEMPLATE-- +{% block title1 %}FOO{% endblock %} +{% block title2 foo|lower %} +--TEMPLATE(foo.twig)-- +{% block content %}{% endblock %} +--DATA-- +return array('foo' => 'bar') +--EXPECT-- +FOObar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/block_unique_name.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/block_unique_name.test new file mode 100644 index 000000000..bc89ec820 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/block_unique_name.test @@ -0,0 +1,11 @@ +--TEST-- +"block" tag +--TEMPLATE-- +{% block content %} + {% block content %} + {% endblock %} +{% endblock %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: The block 'content' has already been defined line 2 in "index.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/special_chars.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/special_chars.test new file mode 100644 index 000000000..be17fedf3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/block/special_chars.test @@ -0,0 +1,10 @@ +--TEST-- +"§" special chars in a block name +--TEMPLATE-- +{% block § %} +§ +{% endblock § %} +--DATA-- +return array() +--EXPECT-- +§ diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/basic.test new file mode 100644 index 000000000..f44296ea0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/basic.test @@ -0,0 +1,35 @@ +--TEST-- +"embed" tag +--TEMPLATE-- +FOO +{% embed "foo.twig" %} + {% block c1 %} + {{ parent() }} + block1extended + {% endblock %} +{% endembed %} + +BAR +--TEMPLATE(foo.twig)-- +A +{% block c1 %} + block1 +{% endblock %} +B +{% block c2 %} + block2 +{% endblock %} +C +--DATA-- +return array() +--EXPECT-- +FOO + +A + block1 + + block1extended + B + block2 +C +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/complex_dynamic_parent.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/complex_dynamic_parent.test new file mode 100644 index 000000000..de5ea7eea --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/complex_dynamic_parent.test @@ -0,0 +1,35 @@ +--TEST-- +"embed" tag +--TEMPLATE-- +FOO +{% embed foo ~ ".twig" %} + {% block c1 %} + {{ parent() }} + block1extended + {% endblock %} +{% endembed %} + +BAR +--TEMPLATE(foo.twig)-- +A +{% block c1 %} + block1 +{% endblock %} +B +{% block c2 %} + block2 +{% endblock %} +C +--DATA-- +return array('foo' => 'foo') +--EXPECT-- +FOO + +A + block1 + + block1extended + B + block2 +C +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/dynamic_parent.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/dynamic_parent.test new file mode 100644 index 000000000..2a125e6b5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/dynamic_parent.test @@ -0,0 +1,35 @@ +--TEST-- +"embed" tag +--TEMPLATE-- +FOO +{% embed foo %} + {% block c1 %} + {{ parent() }} + block1extended + {% endblock %} +{% endembed %} + +BAR +--TEMPLATE(foo.twig)-- +A +{% block c1 %} + block1 +{% endblock %} +B +{% block c2 %} + block2 +{% endblock %} +C +--DATA-- +return array('foo' => 'foo.twig') +--EXPECT-- +FOO + +A + block1 + + block1extended + B + block2 +C +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/error_line.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/error_line.test new file mode 100644 index 000000000..431473707 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/error_line.test @@ -0,0 +1,16 @@ +--TEST-- +"embed" tag +--TEMPLATE(index.twig)-- +FOO +{% embed "foo.twig" %} + {% block c1 %} + {{ nothing }} + {% endblock %} +{% endembed %} +BAR +--TEMPLATE(foo.twig)-- +{% block c1 %}{% endblock %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Runtime: Variable "nothing" does not exist in "index.twig" at line 5. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/multiple.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/multiple.test new file mode 100644 index 000000000..da161e6d4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/multiple.test @@ -0,0 +1,50 @@ +--TEST-- +"embed" tag +--TEMPLATE-- +FOO +{% embed "foo.twig" %} + {% block c1 %} + {{ parent() }} + block1extended + {% endblock %} +{% endembed %} + +{% embed "foo.twig" %} + {% block c1 %} + {{ parent() }} + block1extended + {% endblock %} +{% endembed %} + +BAR +--TEMPLATE(foo.twig)-- +A +{% block c1 %} + block1 +{% endblock %} +B +{% block c2 %} + block2 +{% endblock %} +C +--DATA-- +return array() +--EXPECT-- +FOO + +A + block1 + + block1extended + B + block2 +C + +A + block1 + + block1extended + B + block2 +C +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/nested.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/nested.test new file mode 100644 index 000000000..81563dcef --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/nested.test @@ -0,0 +1,42 @@ +--TEST-- +"embed" tag +--TEMPLATE-- +{% embed "foo.twig" %} + {% block c1 %} + {{ parent() }} + {% embed "foo.twig" %} + {% block c1 %} + {{ parent() }} + block1extended + {% endblock %} + {% endembed %} + + {% endblock %} +{% endembed %} +--TEMPLATE(foo.twig)-- +A +{% block c1 %} + block1 +{% endblock %} +B +{% block c2 %} + block2 +{% endblock %} +C +--DATA-- +return array() +--EXPECT-- +A + block1 + + +A + block1 + + block1extended + B + block2 +C + B + block2 +C diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/with_extends.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/with_extends.test new file mode 100644 index 000000000..2c1dd584c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/with_extends.test @@ -0,0 +1,60 @@ +--TEST-- +"embed" tag +--TEMPLATE-- +{% extends "base.twig" %} + +{% block c1 %} + {{ parent() }} + blockc1baseextended +{% endblock %} + +{% block c2 %} + {{ parent() }} + + {% embed "foo.twig" %} + {% block c1 %} + {{ parent() }} + block1extended + {% endblock %} + {% endembed %} + {{ parent() }} +{% endblock %} +--TEMPLATE(base.twig)-- +A +{% block c1 %} + blockc1base +{% endblock %} +{% block c2 %} + blockc2base +{% endblock %} +B +--TEMPLATE(foo.twig)-- +A +{% block c1 %} + block1 +{% endblock %} +B +{% block c2 %} + block2 +{% endblock %} +C +--DATA-- +return array() +--EXPECT-- +A + blockc1base + + blockc1baseextended + blockc2base + + + +A + block1 + + block1extended + B + block2 +C blockc2base + +B \ No newline at end of file diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/basic.test new file mode 100644 index 000000000..82094f2f0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/basic.test @@ -0,0 +1,10 @@ +--TEST-- +"filter" tag applies a filter on its children +--TEMPLATE-- +{% filter upper %} +Some text with a {{ var }} +{% endfilter %} +--DATA-- +return array('var' => 'var') +--EXPECT-- +SOME TEXT WITH A VAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/json_encode.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/json_encode.test new file mode 100644 index 000000000..3e7148bf4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/json_encode.test @@ -0,0 +1,8 @@ +--TEST-- +"filter" tag applies a filter on its children +--TEMPLATE-- +{% filter json_encode|raw %}test{% endfilter %} +--DATA-- +return array() +--EXPECT-- +"test" diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/multiple.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/multiple.test new file mode 100644 index 000000000..75512ef96 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/multiple.test @@ -0,0 +1,10 @@ +--TEST-- +"filter" tags accept multiple chained filters +--TEMPLATE-- +{% filter lower|title %} + {{ var }} +{% endfilter %} +--DATA-- +return array('var' => 'VAR') +--EXPECT-- + Var diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/nested.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/nested.test new file mode 100644 index 000000000..7e4e4eb33 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/nested.test @@ -0,0 +1,16 @@ +--TEST-- +"filter" tags can be nested at will +--TEMPLATE-- +{% filter lower|title %} + {{ var }} + {% filter upper %} + {{ var }} + {% endfilter %} + {{ var }} +{% endfilter %} +--DATA-- +return array('var' => 'var') +--EXPECT-- + Var + Var + Var diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/with_for_tag.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/with_for_tag.test new file mode 100644 index 000000000..22745eadf --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/with_for_tag.test @@ -0,0 +1,13 @@ +--TEST-- +"filter" tag applies the filter on "for" tags +--TEMPLATE-- +{% filter upper %} +{% for item in items %} +{{ item }} +{% endfor %} +{% endfilter %} +--DATA-- +return array('items' => array('a', 'b')) +--EXPECT-- +A +B diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/with_if_tag.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/with_if_tag.test new file mode 100644 index 000000000..afd95b296 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/filter/with_if_tag.test @@ -0,0 +1,29 @@ +--TEST-- +"filter" tag applies the filter on "if" tags +--TEMPLATE-- +{% filter upper %} +{% if items %} +{{ items|join(', ') }} +{% endif %} + +{% if items.3 is defined %} +FOO +{% else %} +{{ items.1 }} +{% endif %} + +{% if items.3 is defined %} +FOO +{% elseif items.1 %} +{{ items.0 }} +{% endif %} + +{% endfilter %} +--DATA-- +return array('items' => array('a', 'b')) +--EXPECT-- +A, B + +B + +A diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/condition.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/condition.test new file mode 100644 index 000000000..380531f78 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/condition.test @@ -0,0 +1,14 @@ +--TEST-- +"for" tag takes a condition +--TEMPLATE-- +{% for i in 1..5 if i is odd -%} + {{ loop.index }}.{{ i }}{{ foo.bar }} +{% endfor %} +--DATA-- +return array('foo' => array('bar' => 'X')) +--CONFIG-- +return array('strict_variables' => false) +--EXPECT-- +1.1X +2.3X +3.5X diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/context.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/context.test new file mode 100644 index 000000000..ddc69307b --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/context.test @@ -0,0 +1,18 @@ +--TEST-- +"for" tag keeps the context safe +--TEMPLATE-- +{% for item in items %} + {% for item in items %} + * {{ item }} + {% endfor %} + * {{ item }} +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXPECT-- + * a + * b + * a + * a + * b + * b diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/else.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/else.test new file mode 100644 index 000000000..20ccc880c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/else.test @@ -0,0 +1,23 @@ +--TEST-- +"for" tag can use an "else" clause +--TEMPLATE-- +{% for item in items %} + * {{ item }} +{% else %} + no item +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXPECT-- + * a + * b +--DATA-- +return array('items' => array()) +--EXPECT-- + no item +--DATA-- +return array() +--CONFIG-- +return array('strict_variables' => false) +--EXPECT-- + no item diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/inner_variables.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/inner_variables.test new file mode 100644 index 000000000..49fb9ca6f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/inner_variables.test @@ -0,0 +1,17 @@ +--TEST-- +"for" tag does not reset inner variables +--TEMPLATE-- +{% for i in 1..2 %} + {% for j in 0..2 %} + {{k}}{% set k = k+1 %} {{ loop.parent.loop.index }} + {% endfor %} +{% endfor %} +--DATA-- +return array('k' => 0) +--EXPECT-- + 0 1 + 1 1 + 2 1 + 3 2 + 4 2 + 5 2 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/keys.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/keys.test new file mode 100644 index 000000000..4e22cb473 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/keys.test @@ -0,0 +1,11 @@ +--TEST-- +"for" tag can iterate over keys +--TEMPLATE-- +{% for key in items|keys %} + * {{ key }} +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXPECT-- + * 0 + * 1 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/keys_and_values.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/keys_and_values.test new file mode 100644 index 000000000..4c211689d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/keys_and_values.test @@ -0,0 +1,11 @@ +--TEST-- +"for" tag can iterate over keys and values +--TEMPLATE-- +{% for key, item in items %} + * {{ key }}/{{ item }} +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXPECT-- + * 0/a + * 1/b diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_context.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_context.test new file mode 100644 index 000000000..93bc76a1f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_context.test @@ -0,0 +1,19 @@ +--TEST-- +"for" tag adds a loop variable to the context +--TEMPLATE-- +{% for item in items %} + * {{ loop.index }}/{{ loop.index0 }} + * {{ loop.revindex }}/{{ loop.revindex0 }} + * {{ loop.first }}/{{ loop.last }}/{{ loop.length }} + +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXPECT-- + * 1/0 + * 2/1 + * 1//2 + + * 2/1 + * 1/0 + * /1/2 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_context_local.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_context_local.test new file mode 100644 index 000000000..58af2c326 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_context_local.test @@ -0,0 +1,10 @@ +--TEST-- +"for" tag adds a loop variable to the context locally +--TEMPLATE-- +{% for item in items %} +{% endfor %} +{% if loop is not defined %}WORKS{% endif %} +--DATA-- +return array('items' => array()) +--EXPECT-- +WORKS diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test new file mode 100644 index 000000000..6a2af63b6 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined.test @@ -0,0 +1,10 @@ +--TEST-- +"for" tag +--TEMPLATE-- +{% for i, item in items if i > 0 %} + {{ loop.last }} +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXCEPTION-- +Twig_Error_Syntax: The "loop.last" variable is not defined when looping with a condition in "index.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test new file mode 100644 index 000000000..1e819ca0a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/loop_not_defined_cond.test @@ -0,0 +1,9 @@ +--TEST-- +"for" tag +--TEMPLATE-- +{% for i, item in items if loop.last > 0 %} +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXCEPTION-- +Twig_Error_Syntax: The "loop" variable cannot be used in a looping condition in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/nested_else.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/nested_else.test new file mode 100644 index 000000000..f8b9f6bc1 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/nested_else.test @@ -0,0 +1,17 @@ +--TEST-- +"for" tag can use an "else" clause +--TEMPLATE-- +{% for item in items %} + {% for item in items1 %} + * {{ item }} + {% else %} + no {{ item }} + {% endfor %} +{% else %} + no item1 +{% endfor %} +--DATA-- +return array('items' => array('a', 'b'), 'items1' => array()) +--EXPECT-- +no a + no b diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/objects.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/objects.test new file mode 100644 index 000000000..503443792 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/objects.test @@ -0,0 +1,43 @@ +--TEST-- +"for" tag iterates over iterable objects +--TEMPLATE-- +{% for item in items %} + * {{ item }} + * {{ loop.index }}/{{ loop.index0 }} + * {{ loop.first }} + +{% endfor %} + +{% for key, value in items %} + * {{ key }}/{{ value }} +{% endfor %} + +{% for key in items|keys %} + * {{ key }} +{% endfor %} +--DATA-- +class ItemsIterator implements Iterator +{ + protected $values = array('foo' => 'bar', 'bar' => 'foo'); + public function current() { return current($this->values); } + public function key() { return key($this->values); } + public function next() { return next($this->values); } + public function rewind() { return reset($this->values); } + public function valid() { return false !== current($this->values); } +} +return array('items' => new ItemsIterator()) +--EXPECT-- + * bar + * 1/0 + * 1 + + * foo + * 2/1 + * + + + * foo/bar + * bar/foo + + * foo + * bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/objects_countable.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/objects_countable.test new file mode 100644 index 000000000..4a1ff6119 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/objects_countable.test @@ -0,0 +1,47 @@ +--TEST-- +"for" tag iterates over iterable and countable objects +--TEMPLATE-- +{% for item in items %} + * {{ item }} + * {{ loop.index }}/{{ loop.index0 }} + * {{ loop.revindex }}/{{ loop.revindex0 }} + * {{ loop.first }}/{{ loop.last }}/{{ loop.length }} + +{% endfor %} + +{% for key, value in items %} + * {{ key }}/{{ value }} +{% endfor %} + +{% for key in items|keys %} + * {{ key }} +{% endfor %} +--DATA-- +class ItemsIteratorCountable implements Iterator, Countable +{ + protected $values = array('foo' => 'bar', 'bar' => 'foo'); + public function current() { return current($this->values); } + public function key() { return key($this->values); } + public function next() { return next($this->values); } + public function rewind() { return reset($this->values); } + public function valid() { return false !== current($this->values); } + public function count() { return count($this->values); } +} +return array('items' => new ItemsIteratorCountable()) +--EXPECT-- + * bar + * 1/0 + * 2/1 + * 1//2 + + * foo + * 2/1 + * 1/0 + * /1/2 + + + * foo/bar + * bar/foo + + * foo + * bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/recursive.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/recursive.test new file mode 100644 index 000000000..17b2e2223 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/recursive.test @@ -0,0 +1,18 @@ +--TEST-- +"for" tags can be nested +--TEMPLATE-- +{% for key, item in items %} +* {{ key }} ({{ loop.length }}): +{% for value in item %} + * {{ value }} ({{ loop.length }}) +{% endfor %} +{% endfor %} +--DATA-- +return array('items' => array('a' => array('a1', 'a2', 'a3'), 'b' => array('b1'))) +--EXPECT-- +* a (2): + * a1 (3) + * a2 (3) + * a3 (3) +* b (2): + * b1 (1) diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/values.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/values.test new file mode 100644 index 000000000..82f2ae8a4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/for/values.test @@ -0,0 +1,11 @@ +--TEST-- +"for" tag iterates over item values +--TEMPLATE-- +{% for item in items %} + * {{ item }} +{% endfor %} +--DATA-- +return array('items' => array('a', 'b')) +--EXPECT-- + * a + * b diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/from.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/from.test new file mode 100644 index 000000000..5f5da0ec1 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/from.test @@ -0,0 +1,14 @@ +--TEST-- +global variables +--TEMPLATE-- +{% include "included.twig" %} +{% from "included.twig" import foobar %} +{{ foobar() }} +--TEMPLATE(included.twig)-- +{% macro foobar() %} +called foobar +{% endmacro %} +--DATA-- +return array(); +--EXPECT-- +called foobar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/if/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/if/basic.test new file mode 100644 index 000000000..c1c3d2768 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/if/basic.test @@ -0,0 +1,22 @@ +--TEST-- +"if" creates a condition +--TEMPLATE-- +{% if a is defined %} + {{ a }} +{% elseif b is defined %} + {{ b }} +{% else %} + NOTHING +{% endif %} +--DATA-- +return array('a' => 'a') +--EXPECT-- + a +--DATA-- +return array('b' => 'b') +--EXPECT-- + b +--DATA-- +return array() +--EXPECT-- + NOTHING diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/if/expression.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/if/expression.test new file mode 100644 index 000000000..edfb73df4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/if/expression.test @@ -0,0 +1,22 @@ +--TEST-- +"if" takes an expression as a test +--TEMPLATE-- +{% if a < 2 %} + A1 +{% elseif a > 10 %} + A2 +{% else %} + A3 +{% endif %} +--DATA-- +return array('a' => 1) +--EXPECT-- + A1 +--DATA-- +return array('a' => 12) +--EXPECT-- + A2 +--DATA-- +return array('a' => 7) +--EXPECT-- + A3 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/basic.test new file mode 100644 index 000000000..8fe1a6c13 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/basic.test @@ -0,0 +1,16 @@ +--TEST-- +"include" tag +--TEMPLATE-- +FOO +{% include "foo.twig" %} + +BAR +--TEMPLATE(foo.twig)-- +FOOBAR +--DATA-- +return array() +--EXPECT-- +FOO + +FOOBAR +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/expression.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/expression.test new file mode 100644 index 000000000..eaeeb112e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/expression.test @@ -0,0 +1,16 @@ +--TEST-- +"include" tag allows expressions for the template to include +--TEMPLATE-- +FOO +{% include foo %} + +BAR +--TEMPLATE(foo.twig)-- +FOOBAR +--DATA-- +return array('foo' => 'foo.twig') +--EXPECT-- +FOO + +FOOBAR +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/ignore_missing.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/ignore_missing.test new file mode 100644 index 000000000..24aed06de --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/ignore_missing.test @@ -0,0 +1,10 @@ +--TEST-- +"include" tag +--TEMPLATE-- +{% include ["foo.twig", "bar.twig"] ignore missing %} +{% include "foo.twig" ignore missing %} +{% include "foo.twig" ignore missing with {} %} +{% include "foo.twig" ignore missing with {} only %} +--DATA-- +return array() +--EXPECT-- diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/missing.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/missing.test new file mode 100644 index 000000000..f25e87155 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/missing.test @@ -0,0 +1,8 @@ +--TEST-- +"include" tag +--TEMPLATE-- +{% include "foo.twig" %} +--DATA-- +return array(); +--EXCEPTION-- +Twig_Error_Loader: Template "foo.twig" is not defined in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/missing_nested.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/missing_nested.test new file mode 100644 index 000000000..86c186444 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/missing_nested.test @@ -0,0 +1,16 @@ +--TEST-- +"include" tag +--TEMPLATE-- +{% extends "base.twig" %} + +{% block content %} + {{ parent() }} +{% endblock %} +--TEMPLATE(base.twig)-- +{% block content %} + {% include "foo.twig" %} +{% endblock %} +--DATA-- +return array(); +--EXCEPTION-- +Twig_Error_Loader: Template "foo.twig" is not defined in "base.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/only.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/only.test new file mode 100644 index 000000000..77760a09e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/only.test @@ -0,0 +1,16 @@ +--TEST-- +"include" tag accept variables and only +--TEMPLATE-- +{% include "foo.twig" %} +{% include "foo.twig" only %} +{% include "foo.twig" with {'foo1': 'bar'} %} +{% include "foo.twig" with {'foo1': 'bar'} only %} +--TEMPLATE(foo.twig)-- +{% for k, v in _context %}{{ k }},{% endfor %} +--DATA-- +return array('foo' => 'bar') +--EXPECT-- +foo,global,_parent, +global,_parent, +foo,global,foo1,_parent, +foo1,global,_parent, diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/template_instance.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/template_instance.test new file mode 100644 index 000000000..6ba064a38 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/template_instance.test @@ -0,0 +1,10 @@ +--TEST-- +"include" tag accepts Twig_Template instance +--TEMPLATE-- +{% include foo %} FOO +--TEMPLATE(foo.twig)-- +BAR +--DATA-- +return array('foo' => $twig->loadTemplate('foo.twig')) +--EXPECT-- +BAR FOO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/templates_as_array.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/templates_as_array.test new file mode 100644 index 000000000..ab670ee06 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/templates_as_array.test @@ -0,0 +1,12 @@ +--TEST-- +"include" tag +--TEMPLATE-- +{% include ["foo.twig", "bar.twig"] %} +{% include ["bar.twig", "foo.twig"] %} +--TEMPLATE(foo.twig)-- +foo +--DATA-- +return array() +--EXPECT-- +foo +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/with_variables.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/with_variables.test new file mode 100644 index 000000000..41384ac7c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/include/with_variables.test @@ -0,0 +1,12 @@ +--TEST-- +"include" tag accept variables +--TEMPLATE-- +{% include "foo.twig" with {'foo': 'bar'} %} +{% include "foo.twig" with vars %} +--TEMPLATE(foo.twig)-- +{{ foo }} +--DATA-- +return array('vars' => array('foo' => 'bar')) +--EXPECT-- +bar +bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/basic.test new file mode 100644 index 000000000..0778a4b49 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/basic.test @@ -0,0 +1,14 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends "foo.twig" %} + +{% block content %} +FOO +{% endblock %} +--TEMPLATE(foo.twig)-- +{% block content %}{% endblock %} +--DATA-- +return array() +--EXPECT-- +FOO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/block_expr.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/block_expr.test new file mode 100644 index 000000000..9a81499ab --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/block_expr.test @@ -0,0 +1,32 @@ +--TEST-- +block_expr +--TEMPLATE-- +{% extends "base.twig" %} + +{% block element -%} + Element: + {{- parent() -}} +{% endblock %} +--TEMPLATE(base.twig)-- +{% spaceless %} +{% block element -%} +
    + {%- if item.children is defined %} + {%- for item in item.children %} + {{- block('element') -}} + {% endfor %} + {%- endif -%} +
    +{%- endblock %} +{% endspaceless %} +--DATA-- +return array( + 'item' => array( + 'children' => array( + null, + null, + ) + ) +) +--EXPECT-- +Element:
    Element:
    Element:
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/block_expr2.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/block_expr2.test new file mode 100644 index 000000000..3e868c0da --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/block_expr2.test @@ -0,0 +1,34 @@ +--TEST-- +block_expr2 +--TEMPLATE-- +{% extends "base2.twig" %} + +{% block element -%} + Element: + {{- parent() -}} +{% endblock %} +--TEMPLATE(base2.twig)-- +{% extends "base.twig" %} +--TEMPLATE(base.twig)-- +{% spaceless %} +{% block element -%} +
    + {%- if item.children is defined %} + {%- for item in item.children %} + {{- block('element') -}} + {% endfor %} + {%- endif -%} +
    +{%- endblock %} +{% endspaceless %} +--DATA-- +return array( + 'item' => array( + 'children' => array( + null, + null, + ) + ) +) +--EXPECT-- +Element:
    Element:
    Element:
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/conditional.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/conditional.test new file mode 100644 index 000000000..8576e773a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/conditional.test @@ -0,0 +1,14 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends standalone ? foo : 'bar.twig' %} + +{% block content %}{{ parent() }}FOO{% endblock %} +--TEMPLATE(foo.twig)-- +{% block content %}FOO{% endblock %} +--TEMPLATE(bar.twig)-- +{% block content %}BAR{% endblock %} +--DATA-- +return array('foo' => 'foo.twig', 'standalone' => true) +--EXPECT-- +FOOFOO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/dynamic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/dynamic.test new file mode 100644 index 000000000..ee06ddce3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/dynamic.test @@ -0,0 +1,14 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends foo %} + +{% block content %} +FOO +{% endblock %} +--TEMPLATE(foo.twig)-- +{% block content %}{% endblock %} +--DATA-- +return array('foo' => 'foo.twig') +--EXPECT-- +FOO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/empty.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/empty.test new file mode 100644 index 000000000..784f35718 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/empty.test @@ -0,0 +1,10 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends "foo.twig" %} +--TEMPLATE(foo.twig)-- +{% block content %}FOO{% endblock %} +--DATA-- +return array() +--EXPECT-- +FOO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array.test new file mode 100644 index 000000000..a1cb1ce8a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array.test @@ -0,0 +1,12 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends ["foo.twig", "bar.twig"] %} +--TEMPLATE(bar.twig)-- +{% block content %} +foo +{% endblock %} +--DATA-- +return array() +--EXPECT-- +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array_with_empty_name.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array_with_empty_name.test new file mode 100644 index 000000000..acc74f6a1 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array_with_empty_name.test @@ -0,0 +1,12 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends ["", "bar.twig"] %} +--TEMPLATE(bar.twig)-- +{% block content %} +foo +{% endblock %} +--DATA-- +return array() +--EXPECT-- +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array_with_null_name.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array_with_null_name.test new file mode 100644 index 000000000..cfa648d41 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array_with_null_name.test @@ -0,0 +1,12 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends [null, "bar.twig"] %} +--TEMPLATE(bar.twig)-- +{% block content %} +foo +{% endblock %} +--DATA-- +return array() +--EXPECT-- +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple.test new file mode 100644 index 000000000..dfc2b6c49 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple.test @@ -0,0 +1,12 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends "layout.twig" %}{% block content %}{{ parent() }}index {% endblock %} +--TEMPLATE(layout.twig)-- +{% extends "base.twig" %}{% block content %}{{ parent() }}layout {% endblock %} +--TEMPLATE(base.twig)-- +{% block content %}base {% endblock %} +--DATA-- +return array() +--EXPECT-- +base layout index diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple_dynamic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple_dynamic.test new file mode 100644 index 000000000..1d3e639ca --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple_dynamic.test @@ -0,0 +1,22 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% set foo = 1 %} +{{ include('parent.twig') }} +{{ include('parent.twig') }} +{% set foo = 2 %} +{{ include('parent.twig') }} +--TEMPLATE(parent.twig)-- +{% extends foo~'_parent.twig' %}{% block content %}{{ parent() }} parent{% endblock %} +--TEMPLATE(1_parent.twig)-- +{% block content %}1{% endblock %} +--TEMPLATE(2_parent.twig)-- +{% block content %}2{% endblock %} +--DATA-- +return array() +--EXPECT-- +1 parent + +1 parent + +2 parent diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_blocks.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_blocks.test new file mode 100644 index 000000000..faca92591 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_blocks.test @@ -0,0 +1,22 @@ +--TEST-- +"block" tag +--TEMPLATE-- +{% extends "foo.twig" %} + +{% block content %} + {% block subcontent %} + {% block subsubcontent %} + SUBSUBCONTENT + {% endblock %} + {% endblock %} +{% endblock %} +--TEMPLATE(foo.twig)-- +{% block content %} + {% block subcontent %} + SUBCONTENT + {% endblock %} +{% endblock %} +--DATA-- +return array() +--EXPECT-- +SUBSUBCONTENT diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_blocks_parent_only.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_blocks_parent_only.test new file mode 100644 index 000000000..0ad11d0c0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_blocks_parent_only.test @@ -0,0 +1,15 @@ +--TEST-- +"block" tag +--TEMPLATE-- +{% block content %} + CONTENT + {%- block subcontent -%} + SUBCONTENT + {%- endblock -%} + ENDCONTENT +{% endblock %} +--TEMPLATE(foo.twig)-- +--DATA-- +return array() +--EXPECT-- +CONTENTSUBCONTENTENDCONTENT diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_inheritance.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_inheritance.test new file mode 100644 index 000000000..71e3cdfd4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_inheritance.test @@ -0,0 +1,16 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends "layout.twig" %} +{% block inside %}INSIDE{% endblock inside %} +--TEMPLATE(layout.twig)-- +{% extends "base.twig" %} +{% block body %} + {% block inside '' %} +{% endblock body %} +--TEMPLATE(base.twig)-- +{% block body '' %} +--DATA-- +return array() +--EXPECT-- +INSIDE diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent.test new file mode 100644 index 000000000..4f975db80 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent.test @@ -0,0 +1,12 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends "foo.twig" %} + +{% block content %}{{ parent() }}FOO{{ parent() }}{% endblock %} +--TEMPLATE(foo.twig)-- +{% block content %}BAR{% endblock %} +--DATA-- +return array() +--EXPECT-- +BARFOOBAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_change.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_change.test new file mode 100644 index 000000000..a8bc90cef --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_change.test @@ -0,0 +1,16 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends foo ? 'foo.twig' : 'bar.twig' %} +--TEMPLATE(foo.twig)-- +FOO +--TEMPLATE(bar.twig)-- +BAR +--DATA-- +return array('foo' => true) +--EXPECT-- +FOO +--DATA-- +return array('foo' => false) +--EXPECT-- +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_in_a_block.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_in_a_block.test new file mode 100644 index 000000000..cca6dbc9b --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_in_a_block.test @@ -0,0 +1,8 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% block content %} + {% extends "foo.twig" %} +{% endblock %} +--EXCEPTION-- +Twig_Error_Syntax: Cannot extend from a block in "index.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_isolation.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_isolation.test new file mode 100644 index 000000000..628167135 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_isolation.test @@ -0,0 +1,20 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends "base.twig" %} +{% block content %}{% include "included.twig" %}{% endblock %} + +{% block footer %}Footer{% endblock %} +--TEMPLATE(included.twig)-- +{% extends "base.twig" %} +{% block content %}Included Content{% endblock %} +--TEMPLATE(base.twig)-- +{% block content %}Default Content{% endblock %} + +{% block footer %}Default Footer{% endblock %} +--DATA-- +return array() +--EXPECT-- +Included Content +Default Footer +Footer diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_nested.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_nested.test new file mode 100644 index 000000000..71e7c2080 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_nested.test @@ -0,0 +1,28 @@ +--TEST-- +"extends" tag +--TEMPLATE-- +{% extends "foo.twig" %} + +{% block content %} + {% block inside %} + INSIDE OVERRIDDEN + {% endblock %} + + BEFORE + {{ parent() }} + AFTER +{% endblock %} +--TEMPLATE(foo.twig)-- +{% block content %} + BAR +{% endblock %} +--DATA-- +return array() +--EXPECT-- + +INSIDE OVERRIDDEN + + BEFORE + BAR + + AFTER diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends.test new file mode 100644 index 000000000..e29b1ac4b --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends.test @@ -0,0 +1,8 @@ +--TEST-- +"parent" tag +--TEMPLATE-- +{% block content %} + {{ parent() }} +{% endblock %} +--EXCEPTION-- +Twig_Error_Syntax: Calling "parent" on a template that does not extend nor "use" another template is forbidden in "index.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends_but_traits.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends_but_traits.test new file mode 100644 index 000000000..63c730550 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends_but_traits.test @@ -0,0 +1,14 @@ +--TEST-- +"parent" tag +--TEMPLATE-- +{% use 'foo.twig' %} + +{% block content %} + {{ parent() }} +{% endblock %} +--TEMPLATE(foo.twig)-- +{% block content %}BAR{% endblock %} +--DATA-- +return array() +--EXPECT-- +BAR diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/template_instance.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/template_instance.test new file mode 100644 index 000000000..d1876a52d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/template_instance.test @@ -0,0 +1,14 @@ +--TEST-- +"extends" tag accepts Twig_Template instance +--TEMPLATE-- +{% extends foo %} + +{% block content %} +{{ parent() }}FOO +{% endblock %} +--TEMPLATE(foo.twig)-- +{% block content %}BAR{% endblock %} +--DATA-- +return array('foo' => $twig->loadTemplate('foo.twig')) +--EXPECT-- +BARFOO diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/use.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/use.test new file mode 100644 index 000000000..8f9ece7ce --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/inheritance/use.test @@ -0,0 +1,44 @@ +--TEST-- +"parent" function +--TEMPLATE-- +{% extends "parent.twig" %} + +{% use "use1.twig" %} +{% use "use2.twig" %} + +{% block content_parent %} + {{ parent() }} +{% endblock %} + +{% block content_use1 %} + {{ parent() }} +{% endblock %} + +{% block content_use2 %} + {{ parent() }} +{% endblock %} + +{% block content %} + {{ block('content_use1_only') }} + {{ block('content_use2_only') }} +{% endblock %} +--TEMPLATE(parent.twig)-- +{% block content_parent 'content_parent' %} +{% block content_use1 'content_parent' %} +{% block content_use2 'content_parent' %} +{% block content '' %} +--TEMPLATE(use1.twig)-- +{% block content_use1 'content_use1' %} +{% block content_use2 'content_use1' %} +{% block content_use1_only 'content_use1_only' %} +--TEMPLATE(use2.twig)-- +{% block content_use2 'content_use2' %} +{% block content_use2_only 'content_use2_only' %} +--DATA-- +return array() +--EXPECT-- + content_parent + content_use1 + content_use2 + content_use1_only + content_use2_only diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/basic.test new file mode 100644 index 000000000..eef0c10d5 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/basic.test @@ -0,0 +1,17 @@ +--TEST-- +"macro" tag +--TEMPLATE-- +{% import _self as macros %} + +{{ macros.input('username') }} +{{ macros.input('password', null, 'password', 1) }} + +{% macro input(name, value, type, size) %} + +{% endmacro %} +--DATA-- +return array() +--EXPECT-- + + + diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/endmacro_name.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/endmacro_name.test new file mode 100644 index 000000000..ae6203bb6 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/endmacro_name.test @@ -0,0 +1,16 @@ +--TEST-- +"macro" tag supports name for endmacro +--TEMPLATE-- +{% import _self as macros %} + +{{ macros.foo() }} +{{ macros.bar() }} + +{% macro foo() %}foo{% endmacro %} +{% macro bar() %}bar{% endmacro bar %} +--DATA-- +return array() +--EXPECT-- +foo +bar + diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/external.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/external.test new file mode 100644 index 000000000..5cd3dae66 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/external.test @@ -0,0 +1,17 @@ +--TEST-- +"macro" tag +--TEMPLATE-- +{% import 'forms.twig' as forms %} + +{{ forms.input('username') }} +{{ forms.input('password', null, 'password', 1) }} +--TEMPLATE(forms.twig)-- +{% macro input(name, value, type, size) %} + +{% endmacro %} +--DATA-- +return array() +--EXPECT-- + + + diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/from.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/from.test new file mode 100644 index 000000000..205f59182 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/from.test @@ -0,0 +1,18 @@ +--TEST-- +"macro" tag +--TEMPLATE-- +{% from 'forms.twig' import foo %} +{% from 'forms.twig' import foo as foobar, bar %} + +{{ foo('foo') }} +{{ foobar('foo') }} +{{ bar('foo') }} +--TEMPLATE(forms.twig)-- +{% macro foo(name) %}foo{{ name }}{% endmacro %} +{% macro bar(name) %}bar{{ name }}{% endmacro %} +--DATA-- +return array() +--EXPECT-- +foofoo +foofoo +barfoo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/from_with_reserved_name.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/from_with_reserved_name.test new file mode 100644 index 000000000..2de9765ff --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/from_with_reserved_name.test @@ -0,0 +1,9 @@ +--TEST-- +"from" tag with reserved name +--TEMPLATE-- +{% from 'forms.twig' import templateName %} +--TEMPLATE(forms.twig)-- +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: "templateName" cannot be an imported macro as it is a reserved keyword in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/global.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/global.test new file mode 100644 index 000000000..6b371768e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/global.test @@ -0,0 +1,14 @@ +--TEST-- +"macro" tag +--TEMPLATE-- +{% from 'forms.twig' import foo %} + +{{ foo('foo') }} +{{ foo() }} +--TEMPLATE(forms.twig)-- +{% macro foo(name) %}{{ name|default('foo') }}{{ global }}{% endmacro %} +--DATA-- +return array() +--EXPECT-- +fooglobal +fooglobal diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/import_with_reserved_nam.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/import_with_reserved_nam.test new file mode 100644 index 000000000..7bd93c62d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/import_with_reserved_nam.test @@ -0,0 +1,11 @@ +--TEST-- +"from" tag with reserved name +--TEMPLATE-- +{% import 'forms.twig' as macros %} + +{{ macros.parent() }} +--TEMPLATE(forms.twig)-- +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: "parent" cannot be called as macro as it is a reserved keyword in "index.twig" at line 4. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/reserved_name.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/reserved_name.test new file mode 100644 index 000000000..f7c102f02 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/reserved_name.test @@ -0,0 +1,10 @@ +--TEST-- +"macro" tag with reserved name +--TEMPLATE-- +{% macro parent(arg1, arg2) %} + parent +{% endmacro %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: "parent" cannot be used as a macro name as it is a reserved keyword in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/self_import.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/self_import.test new file mode 100644 index 000000000..17756cb6c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/self_import.test @@ -0,0 +1,17 @@ +--TEST-- +"macro" tag +--TEMPLATE-- +{% import _self as forms %} + +{{ forms.input('username') }} +{{ forms.input('password', null, 'password', 1) }} + +{% macro input(name, value, type, size) %} + +{% endmacro %} +--DATA-- +return array() +--EXPECT-- + + + diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/special_chars.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/special_chars.test new file mode 100644 index 000000000..372177073 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/special_chars.test @@ -0,0 +1,14 @@ +--TEST-- +"§" as a macro name +--TEMPLATE-- +{% import _self as macros %} + +{{ macros.§('foo') }} + +{% macro §(foo) %} + §{{ foo }}§ +{% endmacro %} +--DATA-- +return array() +--EXPECT-- +§foo§ diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/super_globals.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/super_globals.test new file mode 100644 index 000000000..567946281 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/macro/super_globals.test @@ -0,0 +1,14 @@ +--TEST-- +Super globals as macro arguments +--TEMPLATE-- +{% import _self as macros %} + +{{ macros.foo('foo') }} + +{% macro foo(GET) %} + {{ GET }} +{% endmacro %} +--DATA-- +return array() +--EXPECT-- +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/basic.legacy.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/basic.legacy.test new file mode 100644 index 000000000..0445e8530 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/basic.legacy.test @@ -0,0 +1,10 @@ +--TEST-- +"raw" tag +--TEMPLATE-- +{% raw %} +{{ foo }} +{% endraw %} +--DATA-- +return array() +--EXPECT-- +{{ foo }} diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/mixed_usage_with_raw.legacy.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/mixed_usage_with_raw.legacy.test new file mode 100644 index 000000000..99deefc32 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/mixed_usage_with_raw.legacy.test @@ -0,0 +1,10 @@ +--TEST-- +"raw" tag +--TEMPLATE-- +{% raw %} +{{ foo }} +{% endverbatim %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: Unexpected end of file: Unclosed "raw" block in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/whitespace_control.legacy.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/whitespace_control.legacy.test new file mode 100644 index 000000000..352bb1876 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/raw/whitespace_control.legacy.test @@ -0,0 +1,56 @@ +--TEST-- +"raw" tag +--TEMPLATE-- +1*** + +{%- raw %} + {{ 'bla' }} +{% endraw %} + +1*** +2*** + +{%- raw -%} + {{ 'bla' }} +{% endraw %} + +2*** +3*** + +{%- raw -%} + {{ 'bla' }} +{% endraw -%} + +3*** +4*** + +{%- raw -%} + {{ 'bla' }} +{%- endraw %} + +4*** +5*** + +{%- raw -%} + {{ 'bla' }} +{%- endraw -%} + +5*** +--DATA-- +return array() +--EXPECT-- +1*** + {{ 'bla' }} + + +1*** +2***{{ 'bla' }} + + +2*** +3***{{ 'bla' }} +3*** +4***{{ 'bla' }} + +4*** +5***{{ 'bla' }}5*** diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid1.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid1.test new file mode 100644 index 000000000..dfddc1513 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid1.test @@ -0,0 +1,11 @@ +--TEST-- +sandbox tag +--TEMPLATE-- +{%- sandbox %} + {%- include "foo.twig" %} + a +{%- endsandbox %} +--TEMPLATE(foo.twig)-- +foo +--EXCEPTION-- +Twig_Error_Syntax: Only "include" tags are allowed within a "sandbox" section in "index.twig" at line 4. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid2.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid2.test new file mode 100644 index 000000000..a33a13ee6 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/not_valid2.test @@ -0,0 +1,14 @@ +--TEST-- +sandbox tag +--TEMPLATE-- +{%- sandbox %} + {%- include "foo.twig" %} + + {% if 1 %} + {%- include "foo.twig" %} + {% endif %} +{%- endsandbox %} +--TEMPLATE(foo.twig)-- +foo +--EXCEPTION-- +Twig_Error_Syntax: Only "include" tags are allowed within a "sandbox" section in "index.twig" at line 5. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/simple.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/simple.test new file mode 100644 index 000000000..de20f3dba --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/sandbox/simple.test @@ -0,0 +1,22 @@ +--TEST-- +sandbox tag +--TEMPLATE-- +{%- sandbox %} + {%- include "foo.twig" %} +{%- endsandbox %} + +{%- sandbox %} + {%- include "foo.twig" %} + {%- include "foo.twig" %} +{%- endsandbox %} + +{%- sandbox %}{% include "foo.twig" %}{% endsandbox %} +--TEMPLATE(foo.twig)-- +foo +--DATA-- +return array() +--EXPECT-- +foo +foo +foo +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/basic.test new file mode 100644 index 000000000..a5a9f830e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/basic.test @@ -0,0 +1,20 @@ +--TEST-- +"set" tag +--TEMPLATE-- +{% set foo = 'foo' %} +{% set bar = 'foo
    ' %} + +{{ foo }} +{{ bar }} + +{% set foo, bar = 'foo', 'bar' %} + +{{ foo }}{{ bar }} +--DATA-- +return array() +--EXPECT-- +foo +foo<br /> + + +foobar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/capture-empty.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/capture-empty.test new file mode 100644 index 000000000..ec657f005 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/capture-empty.test @@ -0,0 +1,9 @@ +--TEST-- +"set" tag block empty capture +--TEMPLATE-- +{% set foo %}{% endset %} + +{% if foo %}FAIL{% endif %} +--DATA-- +return array() +--EXPECT-- diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/capture.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/capture.test new file mode 100644 index 000000000..f156a1a7f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/capture.test @@ -0,0 +1,10 @@ +--TEST-- +"set" tag block capture +--TEMPLATE-- +{% set foo %}f
    o
    o{% endset %} + +{{ foo }} +--DATA-- +return array() +--EXPECT-- +f
    o
    o diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/expression.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/expression.test new file mode 100644 index 000000000..8ff434a01 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/set/expression.test @@ -0,0 +1,12 @@ +--TEST-- +"set" tag +--TEMPLATE-- +{% set foo, bar = 'foo' ~ 'bar', 'bar' ~ 'foo' %} + +{{ foo }} +{{ bar }} +--DATA-- +return array() +--EXPECT-- +foobar +barfoo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/spaceless/simple.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/spaceless/simple.test new file mode 100644 index 000000000..dd06dec25 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/spaceless/simple.test @@ -0,0 +1,12 @@ +--TEST-- +"spaceless" tag removes whites between HTML tags +--TEMPLATE-- +{% spaceless %} + +
    foo
    + +{% endspaceless %} +--DATA-- +return array() +--EXPECT-- +
    foo
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/special_chars.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/special_chars.test new file mode 100644 index 000000000..789b4ba80 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/special_chars.test @@ -0,0 +1,8 @@ +--TEST-- +"§" custom tag +--TEMPLATE-- +{% § %} +--DATA-- +return array() +--EXPECT-- +§ diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/trim_block.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/trim_block.test new file mode 100644 index 000000000..1d2273f88 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/trim_block.test @@ -0,0 +1,74 @@ +--TEST-- +Whitespace trimming on tags. +--TEMPLATE-- +{{ 5 * '{#-'|length }} +{{ '{{-'|length * 5 + '{%-'|length }} + +Trim on control tag: +{% for i in range(1, 9) -%} + {{ i }} +{%- endfor %} + + +Trim on output tag: +{% for i in range(1, 9) %} + {{- i -}} +{% endfor %} + + +Trim comments: + +{#- Invisible -#} + +After the comment. + +Trim leading space: +{% if leading %} + + {{- leading }} +{% endif %} + +{%- if leading %} + {{- leading }} + +{%- endif %} + + +Trim trailing space: +{% if trailing -%} + {{ trailing -}} + +{% endif -%} + +Combined: + +{%- if both -%} +
      +
    • {{- both -}}
    • +
    + +{%- endif -%} + +end +--DATA-- +return array('leading' => 'leading space', 'trailing' => 'trailing space', 'both' => 'both') +--EXPECT-- +15 +18 + +Trim on control tag: +123456789 + +Trim on output tag: +123456789 + +Trim comments:After the comment. + +Trim leading space: +leading space +leading space + +Trim trailing space: +trailing spaceCombined:
      +
    • both
    • +
    end diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/aliases.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/aliases.test new file mode 100644 index 000000000..f887006f6 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/aliases.test @@ -0,0 +1,12 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use "blocks.twig" with content as foo %} + +{{ block('foo') }} +--TEMPLATE(blocks.twig)-- +{% block content 'foo' %} +--DATA-- +return array() +--EXPECT-- +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/basic.test new file mode 100644 index 000000000..7364d76de --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/basic.test @@ -0,0 +1,12 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use "blocks.twig" %} + +{{ block('content') }} +--TEMPLATE(blocks.twig)-- +{% block content 'foo' %} +--DATA-- +return array() +--EXPECT-- +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/deep.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/deep.test new file mode 100644 index 000000000..b551a1e60 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/deep.test @@ -0,0 +1,22 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use "foo.twig" %} + +{{ block('content') }} +{{ block('foo') }} +{{ block('bar') }} +--TEMPLATE(foo.twig)-- +{% use "bar.twig" %} + +{% block content 'foo' %} +{% block foo 'foo' %} +--TEMPLATE(bar.twig)-- +{% block content 'bar' %} +{% block bar 'bar' %} +--DATA-- +return array() +--EXPECT-- +foo +foo +bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/deep_empty.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/deep_empty.test new file mode 100644 index 000000000..05cca682e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/deep_empty.test @@ -0,0 +1,10 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use "foo.twig" %} +--TEMPLATE(foo.twig)-- +{% use "bar.twig" %} +--TEMPLATE(bar.twig)-- +--DATA-- +return array() +--EXPECT-- diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance.test new file mode 100644 index 000000000..0d0d470ee --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance.test @@ -0,0 +1,25 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use "parent.twig" %} + +{{ block('container') }} +--TEMPLATE(parent.twig)-- +{% use "ancestor.twig" %} + +{% block sub_container %} +
    overridden sub_container
    +{% endblock %} +--TEMPLATE(ancestor.twig)-- +{% block container %} +
    {{ block('sub_container') }}
    +{% endblock %} + +{% block sub_container %} +
    sub_container
    +{% endblock %} +--DATA-- +return array() +--EXPECT-- +
    overridden sub_container
    +
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance2.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance2.test new file mode 100644 index 000000000..df95599ce --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/inheritance2.test @@ -0,0 +1,24 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use "ancestor.twig" %} +{% use "parent.twig" %} + +{{ block('container') }} +--TEMPLATE(parent.twig)-- +{% block sub_container %} +
    overridden sub_container
    +{% endblock %} +--TEMPLATE(ancestor.twig)-- +{% block container %} +
    {{ block('sub_container') }}
    +{% endblock %} + +{% block sub_container %} +
    sub_container
    +{% endblock %} +--DATA-- +return array() +--EXPECT-- +
    overridden sub_container
    +
    diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/multiple.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/multiple.test new file mode 100644 index 000000000..198be0c5c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/multiple.test @@ -0,0 +1,21 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use "foo.twig" %} +{% use "bar.twig" %} + +{{ block('content') }} +{{ block('foo') }} +{{ block('bar') }} +--TEMPLATE(foo.twig)-- +{% block content 'foo' %} +{% block foo 'foo' %} +--TEMPLATE(bar.twig)-- +{% block content 'bar' %} +{% block bar 'bar' %} +--DATA-- +return array() +--EXPECT-- +bar +foo +bar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/multiple_aliases.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/multiple_aliases.test new file mode 100644 index 000000000..8de871a8a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/multiple_aliases.test @@ -0,0 +1,23 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use "foo.twig" with content as foo_content %} +{% use "bar.twig" %} + +{{ block('content') }} +{{ block('foo') }} +{{ block('bar') }} +{{ block('foo_content') }} +--TEMPLATE(foo.twig)-- +{% block content 'foo' %} +{% block foo 'foo' %} +--TEMPLATE(bar.twig)-- +{% block content 'bar' %} +{% block bar 'bar' %} +--DATA-- +return array() +--EXPECT-- +bar +foo +bar +foo diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block.test new file mode 100644 index 000000000..59db23d95 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block.test @@ -0,0 +1,24 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use 'file2.html.twig' with foobar as base_base_foobar %} +{% block foobar %} + {{- block('base_base_foobar') -}} + Content of block (second override) +{% endblock foobar %} +--TEMPLATE(file2.html.twig)-- +{% use 'file1.html.twig' with foobar as base_foobar %} +{% block foobar %} + {{- block('base_foobar') -}} + Content of block (first override) +{% endblock foobar %} +--TEMPLATE(file1.html.twig)-- +{% block foobar -%} + Content of block +{% endblock foobar %} +--DATA-- +return array() +--EXPECT-- +Content of block +Content of block (first override) +Content of block (second override) diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block2.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block2.test new file mode 100644 index 000000000..d3f302df0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block2.test @@ -0,0 +1,24 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use 'file2.html.twig'%} +{% block foobar %} + {{- parent() -}} + Content of block (second override) +{% endblock foobar %} +--TEMPLATE(file2.html.twig)-- +{% use 'file1.html.twig' %} +{% block foobar %} + {{- parent() -}} + Content of block (first override) +{% endblock foobar %} +--TEMPLATE(file1.html.twig)-- +{% block foobar -%} + Content of block +{% endblock foobar %} +--DATA-- +return array() +--EXPECT-- +Content of block +Content of block (first override) +Content of block (second override) diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block3.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block3.test new file mode 100644 index 000000000..95b55a469 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/use/parent_block3.test @@ -0,0 +1,38 @@ +--TEST-- +"use" tag +--TEMPLATE-- +{% use 'file2.html.twig' %} +{% use 'file1.html.twig' with foo %} +{% block foo %} + {{- parent() -}} + Content of foo (second override) +{% endblock foo %} +{% block bar %} + {{- parent() -}} + Content of bar (second override) +{% endblock bar %} +--TEMPLATE(file2.html.twig)-- +{% use 'file1.html.twig' %} +{% block foo %} + {{- parent() -}} + Content of foo (first override) +{% endblock foo %} +{% block bar %} + {{- parent() -}} + Content of bar (first override) +{% endblock bar %} +--TEMPLATE(file1.html.twig)-- +{% block foo -%} + Content of foo +{% endblock foo %} +{% block bar -%} + Content of bar +{% endblock bar %} +--DATA-- +return array() +--EXPECT-- +Content of foo +Content of foo (first override) +Content of foo (second override) +Content of bar +Content of bar (second override) diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/basic.test new file mode 100644 index 000000000..a95be5572 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/basic.test @@ -0,0 +1,10 @@ +--TEST-- +"verbatim" tag +--TEMPLATE-- +{% verbatim %} +{{ foo }} +{% endverbatim %} +--DATA-- +return array() +--EXPECT-- +{{ foo }} diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test new file mode 100644 index 000000000..28626a816 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/mixed_usage_with_raw.test @@ -0,0 +1,10 @@ +--TEST-- +"verbatim" tag +--TEMPLATE-- +{% verbatim %} +{{ foo }} +{% endraw %} +--DATA-- +return array() +--EXCEPTION-- +Twig_Error_Syntax: Unexpected end of file: Unclosed "verbatim" block in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/whitespace_control.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/whitespace_control.test new file mode 100644 index 000000000..eb6104446 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/verbatim/whitespace_control.test @@ -0,0 +1,56 @@ +--TEST-- +"verbatim" tag +--TEMPLATE-- +1*** + +{%- verbatim %} + {{ 'bla' }} +{% endverbatim %} + +1*** +2*** + +{%- verbatim -%} + {{ 'bla' }} +{% endverbatim %} + +2*** +3*** + +{%- verbatim -%} + {{ 'bla' }} +{% endverbatim -%} + +3*** +4*** + +{%- verbatim -%} + {{ 'bla' }} +{%- endverbatim %} + +4*** +5*** + +{%- verbatim -%} + {{ 'bla' }} +{%- endverbatim -%} + +5*** +--DATA-- +return array() +--EXPECT-- +1*** + {{ 'bla' }} + + +1*** +2***{{ 'bla' }} + + +2*** +3***{{ 'bla' }} +3*** +4***{{ 'bla' }} + +4*** +5***{{ 'bla' }}5*** diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/basic.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/basic.test new file mode 100644 index 000000000..264ca5e7e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/basic.test @@ -0,0 +1,13 @@ +--TEST-- +"with" tag +--TEMPLATE-- +{% with %} + {% set bar = 'BAZ' %} + {{ foo }}{{ bar }} +{% endwith %} +{{ foo }}{{ bar }} +--DATA-- +return array('foo' => 'foo', 'bar' => 'bar') +--EXPECT-- +fooBAZ +foobar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/expression.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/expression.test new file mode 100644 index 000000000..32ed0916c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/expression.test @@ -0,0 +1,10 @@ +--TEST-- +"with" tag with expression +--TEMPLATE-- +{% with {foo: 'foo', bar: 'BAZ'} %} + {{ foo }}{{ bar }} +{% endwith %} +--DATA-- +return array('foo' => 'baz') +--EXPECT-- +fooBAZ diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/nested.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/nested.test new file mode 100644 index 000000000..98e3aef43 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/nested.test @@ -0,0 +1,15 @@ +--TEST-- +nested "with" tags +--TEMPLATE-- +{% set foo, bar = 'foo', 'bar' %} +{% with {bar: 'BAZ'} %} + {% with {foo: 'FOO'} %} + {{ foo }}{{ bar }} + {% endwith %} +{% endwith %} +{{ foo }}{{ bar }} +--DATA-- +return array() +--EXPECT-- +FOOBAZ + foobar diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/with_no_hash.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/with_no_hash.test new file mode 100644 index 000000000..93689f42c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/with_no_hash.test @@ -0,0 +1,10 @@ +--TEST-- +"with" tag with an expression that is not a hash +--TEMPLATE-- +{% with vars %} + {{ foo }}{{ bar }} +{% endwith %} +--DATA-- +return array('vars' => 'no-hash') +--EXCEPTION-- +Twig_Error_Runtime: Variables passed to the "with" tag must be a hash in "index.twig" at line 2. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/with_only.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/with_only.test new file mode 100644 index 000000000..6247617e3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/with/with_only.test @@ -0,0 +1,10 @@ +--TEST-- +"with" tag with expression and only +--TEMPLATE-- +{% with {foo: 'foo', bar: 'BAZ'} only %} + {{ foo }}{{ bar }}{{ baz }} +{% endwith %} +--DATA-- +return array('foo' => 'baz', 'baz' => 'baz') +--EXCEPTION-- +Twig_Error_Runtime: Variable "baz" does not exist in "index.twig" at line 3. diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/array.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/array.test new file mode 100644 index 000000000..1429d3753 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/array.test @@ -0,0 +1,24 @@ +--TEST-- +array index test +--TEMPLATE-- +{% for key, value in days %} +{{ key }} +{% endfor %} +--DATA-- +return array('days' => array( + 1 => array('money' => 9), + 2 => array('money' => 21), + 3 => array('money' => 38), + 4 => array('money' => 6), + 18 => array('money' => 6), + 19 => array('money' => 3), + 31 => array('money' => 11), +)); +--EXPECT-- +1 +2 +3 +4 +18 +19 +31 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/constant.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/constant.test new file mode 100644 index 000000000..60218ac04 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/constant.test @@ -0,0 +1,14 @@ +--TEST-- +"const" test +--TEMPLATE-- +{{ 8 is constant('E_NOTICE') ? 'ok' : 'no' }} +{{ 'bar' is constant('TwigTestFoo::BAR_NAME') ? 'ok' : 'no' }} +{{ value is constant('TwigTestFoo::BAR_NAME') ? 'ok' : 'no' }} +{{ 2 is constant('ARRAY_AS_PROPS', object) ? 'ok' : 'no' }} +--DATA-- +return array('value' => 'bar', 'object' => new ArrayObject(array('hi'))); +--EXPECT-- +ok +ok +ok +ok \ No newline at end of file diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined.test new file mode 100644 index 000000000..d4e204efa --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined.test @@ -0,0 +1,129 @@ +--TEST-- +"defined" test +--TEMPLATE-- +{{ definedVar is defined ? 'ok' : 'ko' }} +{{ definedVar is not defined ? 'ko' : 'ok' }} +{{ undefinedVar is defined ? 'ko' : 'ok' }} +{{ undefinedVar is not defined ? 'ok' : 'ko' }} +{{ zeroVar is defined ? 'ok' : 'ko' }} +{{ nullVar is defined ? 'ok' : 'ko' }} +{{ nested.definedVar is defined ? 'ok' : 'ko' }} +{{ nested['definedVar'] is defined ? 'ok' : 'ko' }} +{{ nested.definedVar is not defined ? 'ko' : 'ok' }} +{{ nested.undefinedVar is defined ? 'ko' : 'ok' }} +{{ nested['undefinedVar'] is defined ? 'ko' : 'ok' }} +{{ nested.undefinedVar is not defined ? 'ok' : 'ko' }} +{{ nested.zeroVar is defined ? 'ok' : 'ko' }} +{{ nested.nullVar is defined ? 'ok' : 'ko' }} +{{ nested.definedArray.0 is defined ? 'ok' : 'ko' }} +{{ nested['definedArray'][0] is defined ? 'ok' : 'ko' }} +{{ object.foo is defined ? 'ok' : 'ko' }} +{{ object.undefinedMethod is defined ? 'ko' : 'ok' }} +{{ object.getFoo() is defined ? 'ok' : 'ko' }} +{{ object.getFoo('a') is defined ? 'ok' : 'ko' }} +{{ object.undefinedMethod() is defined ? 'ko' : 'ok' }} +{{ object.undefinedMethod('a') is defined ? 'ko' : 'ok' }} +{{ object.self.foo is defined ? 'ok' : 'ko' }} +{{ object.self.undefinedMethod is defined ? 'ko' : 'ok' }} +{{ object.undefinedMethod.self is defined ? 'ko' : 'ok' }} +{{ 0 is defined ? 'ok' : 'ko' }} +{{ "foo" is defined ? 'ok' : 'ko' }} +{{ true is defined ? 'ok' : 'ko' }} +{{ false is defined ? 'ok' : 'ko' }} +{{ null is defined ? 'ok' : 'ko' }} +{{ [1, 2] is defined ? 'ok' : 'ko' }} +{{ { foo: "bar" } is defined ? 'ok' : 'ko' }} +--DATA-- +return array( + 'definedVar' => 'defined', + 'zeroVar' => 0, + 'nullVar' => null, + 'nested' => array( + 'definedVar' => 'defined', + 'zeroVar' => 0, + 'nullVar' => null, + 'definedArray' => array(0), + ), + 'object' => new TwigTestFoo(), +); +--EXPECT-- +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +--DATA-- +return array( + 'definedVar' => 'defined', + 'zeroVar' => 0, + 'nullVar' => null, + 'nested' => array( + 'definedVar' => 'defined', + 'zeroVar' => 0, + 'nullVar' => null, + 'definedArray' => array(0), + ), + 'object' => new TwigTestFoo(), +); +--CONFIG-- +return array('strict_variables' => false) +--EXPECT-- +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_attribute.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_attribute.test new file mode 100644 index 000000000..4a5b8dcdb --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_attribute.test @@ -0,0 +1,35 @@ +--TEST-- +"defined" support for attribute +--TEMPLATE-- +{{ attribute(nested, "definedVar") is defined ? 'ok' : 'ko' }} +{{ attribute(nested, "undefinedVar") is not defined ? 'ok' : 'ko' }} +{{ attribute(nested, definedVarName) is defined ? 'ok' : 'ko' }} +{{ attribute(nested, undefinedVarName) is not defined ? 'ok' : 'ko' }} +--DATA-- +return array( + 'nested' => array( + 'definedVar' => 'defined', + ), + 'definedVarName' => 'definedVar', + 'undefinedVarName' => 'undefinedVar', +); +--EXPECT-- +ok +ok +ok +ok +--DATA-- +return array( + 'nested' => array( + 'definedVar' => 'defined', + ), + 'definedVarName' => 'definedVar', + 'undefinedVarName' => 'undefinedVar', +); +--CONFIG-- +return array('strict_variables' => false) +--EXPECT-- +ok +ok +ok +ok diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_blocks.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_blocks.test new file mode 100644 index 000000000..64d7d0431 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_blocks.test @@ -0,0 +1,38 @@ +--TEST-- +"defined" support for blocks +--TEMPLATE-- +{% extends 'parent' %} +{% block icon %}icon{% endblock %} +{% block body %} + {{ parent() }} + {{ block('foo') is defined ? 'ok' : 'ko' }} + {{ block('footer') is defined ? 'ok' : 'ko' }} + {{ block('icon') is defined ? 'ok' : 'ko' }} + {{ block('block1') is defined ? 'ok' : 'ko' }} + {%- embed 'embed' %} + {% block content %}content{% endblock %} + {% endembed %} +{% endblock %} +{% use 'blocks' %} +--TEMPLATE(parent)-- +{% block body %} + {{ block('icon') is defined ? 'ok' : 'ko' -}} +{% endblock %} +{% block footer %}{% endblock %} +--TEMPLATE(embed)-- +{{ block('icon') is defined ? 'ok' : 'ko' }} +{{ block('content') is defined ? 'ok' : 'ko' }} +{{ block('block1') is defined ? 'ok' : 'ko' }} +--TEMPLATE(blocks)-- +{% block block1 %}{%endblock %} +--DATA-- +return array() +--EXPECT-- +ok + ko + ok + ok + ok +ko +ok +ko diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_blocks_with_template.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_blocks_with_template.test new file mode 100644 index 000000000..2c651657e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_blocks_with_template.test @@ -0,0 +1,17 @@ +--TEST-- +"defined" support for blocks with a template argument +--TEMPLATE-- +{{ block('foo', 'included.twig') is defined ? 'ok' : 'ko' }} +{{ block('foo', included_loaded) is defined ? 'ok' : 'ko' }} +{{ block('foo', included_loaded_internal) is defined ? 'ok' : 'ko' }} +--TEMPLATE(included.twig)-- +{% block foo %}FOO{% endblock %} +--DATA-- +return array( + 'included_loaded' => $twig->load('included.twig'), + 'included_loaded_internal' => $twig->loadTemplate('included.twig'), +) +--EXPECT-- +ok +ok +ok diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_constants.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_constants.test new file mode 100644 index 000000000..2fa9929d3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/defined_for_constants.test @@ -0,0 +1,14 @@ +--TEST-- +"defined" support for constants +--TEMPLATE-- +{{ constant('DATE_W3C') is defined ? 'ok' : 'ko' }} +{{ constant('ARRAY_AS_PROPS', object) is defined ? 'ok' : 'ko' }} +{{ constant('FOOBAR') is not defined ? 'ok' : 'ko' }} +{{ constant('FOOBAR', object) is not defined ? 'ok' : 'ko' }} +--DATA-- +return array('expect' => DATE_W3C, 'object' => new ArrayObject(array('hi'))); +--EXPECT-- +ok +ok +ok +ok diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/empty.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/empty.test new file mode 100644 index 000000000..807c0ed4a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/empty.test @@ -0,0 +1,42 @@ +--TEST-- +"empty" test +--TEMPLATE-- +{{ string_empty is empty ? 'ok' : 'ko' }} +{{ string_zero is empty ? 'ko' : 'ok' }} +{{ value_null is empty ? 'ok' : 'ko' }} +{{ value_false is empty ? 'ok' : 'ko' }} +{{ value_int_zero is empty ? 'ko' : 'ok' }} +{{ array_empty is empty ? 'ok' : 'ko' }} +{{ array_not_empty is empty ? 'ko' : 'ok' }} +{{ magically_callable is empty ? 'ko' : 'ok' }} +{{ countable_empty is empty ? 'ok' : 'ko' }} +{{ countable_not_empty is empty ? 'ko' : 'ok' }} +{{ tostring_empty is empty ? 'ok' : 'ko' }} +{{ tostring_not_empty is empty ? 'ko' : 'ok' }} +{{ markup_empty is empty ? 'ok' : 'ko' }} +{{ markup_not_empty is empty ? 'ko' : 'ok' }} +--DATA-- +return array( + 'string_empty' => '', 'string_zero' => '0', + 'value_null' => null, 'value_false' => false, 'value_int_zero' => 0, + 'array_empty' => array(), 'array_not_empty' => array(1, 2), + 'magically_callable' => new MagicCallStub(), + 'countable_empty' => new CountableStub(array()), 'countable_not_empty' => new CountableStub(array(1, 2)), + 'tostring_empty' => new ToStringStub(''), 'tostring_not_empty' => new ToStringStub('0' /* edge case of using "0" as the string */), + 'markup_empty' => new Twig_Markup('', 'UTF-8'), 'markup_not_empty' => new Twig_Markup('test', 'UTF-8'), +); +--EXPECT-- +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/even.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/even.test new file mode 100644 index 000000000..695b4c2f8 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/even.test @@ -0,0 +1,14 @@ +--TEST-- +"even" test +--TEMPLATE-- +{{ 1 is even ? 'ko' : 'ok' }} +{{ 2 is even ? 'ok' : 'ko' }} +{{ 1 is not even ? 'ok' : 'ko' }} +{{ 2 is not even ? 'ko' : 'ok' }} +--DATA-- +return array() +--EXPECT-- +ok +ok +ok +ok diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/in.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/in.test new file mode 100644 index 000000000..545f51f81 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/in.test @@ -0,0 +1,128 @@ +--TEST-- +Twig supports the in operator +--TEMPLATE-- +{% if bar in foo %} +TRUE +{% endif %} +{% if not (bar in foo) %} +{% else %} +TRUE +{% endif %} +{% if bar not in foo %} +{% else %} +TRUE +{% endif %} +{% if 'a' in bar %} +TRUE +{% endif %} +{% if 'c' not in bar %} +TRUE +{% endif %} +{% if '' in bar %} +TRUE +{% endif %} +{% if '' in '' %} +TRUE +{% endif %} +{% if '0' not in '' %} +TRUE +{% endif %} +{% if 'a' not in '0' %} +TRUE +{% endif %} +{% if '0' in '0' %} +TRUE +{% endif %} + +{{ false in [0, 1] ? 'TRUE' : 'FALSE' }} +{{ true in [0, 1] ? 'TRUE' : 'FALSE' }} +{{ '0' in [0, 1] ? 'TRUE' : 'FALSE' }} +{{ '' in [0, 1] ? 'TRUE' : 'FALSE' }} +{{ 0 in ['', 1] ? 'TRUE' : 'FALSE' }} + +{{ '' in 'foo' ? 'TRUE' : 'FALSE' }} +{{ 0 in 'foo' ? 'TRUE' : 'FALSE' }} +{{ false in 'foo' ? 'TRUE' : 'FALSE' }} +{{ false in '100' ? 'TRUE' : 'FALSE' }} +{{ true in '100' ? 'TRUE' : 'FALSE' }} + +{{ [] in [true, false] ? 'TRUE' : 'FALSE' }} +{{ [] in [true, ''] ? 'TRUE' : 'FALSE' }} +{{ [] in [true, []] ? 'TRUE' : 'FALSE' }} + +{{ resource ? 'TRUE' : 'FALSE' }} +{{ resource in 'foo'~resource ? 'TRUE' : 'FALSE' }} +{{ object in 'stdClass' ? 'TRUE' : 'FALSE' }} +{{ [] in 'Array' ? 'TRUE' : 'FALSE' }} +{{ dir_object in 'foo'~dir_object ? 'TRUE' : 'FALSE' }} + +{{ ''~resource in resource ? 'TRUE' : 'FALSE' }} +{{ 'stdClass' in object ? 'TRUE' : 'FALSE' }} +{{ 'Array' in [] ? 'TRUE' : 'FALSE' }} +{{ ''~dir_object in dir_object ? 'TRUE' : 'FALSE' }} + +{{ resource in [''~resource] ? 'TRUE' : 'FALSE' }} +{{ resource in [resource + 1 - 1] ? 'TRUE' : 'FALSE' }} +{{ dir_object in [''~dir_object] ? 'TRUE' : 'FALSE' }} + +{{ 5 in 125 ? 'TRUE' : 'FALSE' }} +{{ 5 in '125' ? 'TRUE' : 'FALSE' }} +{{ '5' in 125 ? 'TRUE' : 'FALSE' }} +{{ '5' in '125' ? 'TRUE' : 'FALSE' }} + +{{ 5.5 in 125.5 ? 'TRUE' : 'FALSE' }} +{{ 5.5 in '125.5' ? 'TRUE' : 'FALSE' }} +{{ '5.5' in 125.5 ? 'TRUE' : 'FALSE' }} +--DATA-- +return array('bar' => 'bar', 'foo' => array('bar' => 'bar'), 'dir_object' => new SplFileInfo(dirname(__FILE__)), 'object' => new stdClass(), 'resource' => opendir(dirname(__FILE__))) +--EXPECT-- +TRUE +TRUE +TRUE +TRUE +TRUE +TRUE +TRUE +TRUE +TRUE +TRUE + +TRUE +TRUE +TRUE +TRUE +TRUE + +TRUE +FALSE +FALSE +FALSE +FALSE + +TRUE +FALSE +TRUE + +TRUE +FALSE +FALSE +FALSE +FALSE + +FALSE +FALSE +FALSE +FALSE + +FALSE +FALSE +FALSE + +FALSE +TRUE +FALSE +TRUE + +FALSE +TRUE +FALSE diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/in_with_objects.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/in_with_objects.test new file mode 100644 index 000000000..8e08061bb --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/in_with_objects.test @@ -0,0 +1,19 @@ +--TEST-- +Twig supports the in operator when using objects +--TEMPLATE-- +{% if object in object_list %} +TRUE +{% endif %} +--DATA-- +$foo = new TwigTestFoo(); +$foo1 = new TwigTestFoo(); + +$foo->position = $foo1; +$foo1->position = $foo; + +return array( + 'object' => $foo, + 'object_list' => array($foo1, $foo), +); +--EXPECT-- +TRUE diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/iterable.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/iterable.test new file mode 100644 index 000000000..ec5255013 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/iterable.test @@ -0,0 +1,19 @@ +--TEST-- +"iterable" test +--TEMPLATE-- +{{ foo is iterable ? 'ok' : 'ko' }} +{{ traversable is iterable ? 'ok' : 'ko' }} +{{ obj is iterable ? 'ok' : 'ko' }} +{{ val is iterable ? 'ok' : 'ko' }} +--DATA-- +return array( + 'foo' => array(), + 'traversable' => new ArrayIterator(array()), + 'obj' => new stdClass(), + 'val' => 'test', +); +--EXPECT-- +ok +ok +ko +ko \ No newline at end of file diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/null_coalesce.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/null_coalesce.test new file mode 100644 index 000000000..3d148c893 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/null_coalesce.test @@ -0,0 +1,30 @@ +--TEST-- +Twig supports the ?? operator +--TEMPLATE-- +{{ 'OK' ?? 'KO' }} +{{ null ?? 'OK' }} +{{ bar ?? 'KO' }} +{{ baz ?? 'OK' }} +{{ foo.bar ?? 'KO' }} +{{ foo.missing ?? 'OK' }} +{{ foo.bar.baz.missing ?? 'OK' }} +{{ foo['bar'] ?? 'KO' }} +{{ foo['missing'] ?? 'OK' }} +{{ nope ?? nada ?? 'OK' }} +{{ 1 + nope ?? nada ?? 2 }} +{{ 1 + nope ?? 3 + nada ?? 2 }} +--DATA-- +return array('bar' => 'OK', 'foo' => array('bar' => 'OK')) +--EXPECT-- +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +3 +6 diff --git a/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/odd.test b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/odd.test new file mode 100644 index 000000000..1b8311e3d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Fixtures/tests/odd.test @@ -0,0 +1,10 @@ +--TEST-- +"odd" test +--TEMPLATE-- +{{ 1 is odd ? 'ok' : 'ko' }} +{{ 2 is odd ? 'ko' : 'ok' }} +--DATA-- +return array() +--EXPECT-- +ok +ok \ No newline at end of file diff --git a/vendor/twig/twig/test/Twig/Tests/IntegrationTest.php b/vendor/twig/twig/test/Twig/Tests/IntegrationTest.php new file mode 100644 index 000000000..5d20112de --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/IntegrationTest.php @@ -0,0 +1,309 @@ +position = 0; + } + + public function current() + { + return $this->array[$this->position]; + } + + public function key() + { + return 'a'; + } + + public function next() + { + ++$this->position; + } + + public function valid() + { + return isset($this->array[$this->position]); + } +} + +class TwigTestTokenParser_§ extends Twig_TokenParser +{ + public function parse(Twig_Token $token) + { + $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + + return new Twig_Node_Print(new Twig_Node_Expression_Constant('§', -1), -1); + } + + public function getTag() + { + return '§'; + } +} + +class TwigTestExtension extends Twig_Extension +{ + public function getTokenParsers() + { + return array( + new TwigTestTokenParser_§(), + ); + } + + public function getFilters() + { + return array( + new Twig_SimpleFilter('§', array($this, '§Filter')), + new Twig_SimpleFilter('escape_and_nl2br', array($this, 'escape_and_nl2br'), array('needs_environment' => true, 'is_safe' => array('html'))), + new Twig_SimpleFilter('nl2br', array($this, 'nl2br'), array('pre_escape' => 'html', 'is_safe' => array('html'))), + new Twig_SimpleFilter('escape_something', array($this, 'escape_something'), array('is_safe' => array('something'))), + new Twig_SimpleFilter('preserves_safety', array($this, 'preserves_safety'), array('preserves_safety' => array('html'))), + new Twig_SimpleFilter('static_call_string', 'TwigTestExtension::staticCall'), + new Twig_SimpleFilter('static_call_array', array('TwigTestExtension', 'staticCall')), + new Twig_SimpleFilter('magic_call', array($this, 'magicCall')), + new Twig_SimpleFilter('magic_call_string', 'TwigTestExtension::magicStaticCall'), + new Twig_SimpleFilter('magic_call_array', array('TwigTestExtension', 'magicStaticCall')), + new Twig_SimpleFilter('*_path', array($this, 'dynamic_path')), + new Twig_SimpleFilter('*_foo_*_bar', array($this, 'dynamic_foo')), + ); + } + + public function getFunctions() + { + return array( + new Twig_SimpleFunction('§', array($this, '§Function')), + new Twig_SimpleFunction('safe_br', array($this, 'br'), array('is_safe' => array('html'))), + new Twig_SimpleFunction('unsafe_br', array($this, 'br')), + new Twig_SimpleFunction('static_call_string', 'TwigTestExtension::staticCall'), + new Twig_SimpleFunction('static_call_array', array('TwigTestExtension', 'staticCall')), + new Twig_SimpleFunction('*_path', array($this, 'dynamic_path')), + new Twig_SimpleFunction('*_foo_*_bar', array($this, 'dynamic_foo')), + ); + } + + public function getTests() + { + return array( + new Twig_SimpleTest('multi word', array($this, 'is_multi_word')), + ); + } + + public function §Filter($value) + { + return "§{$value}§"; + } + + public function §Function($value) + { + return "§{$value}§"; + } + + /** + * nl2br which also escapes, for testing escaper filters. + */ + public function escape_and_nl2br($env, $value, $sep = '
    ') + { + return $this->nl2br(twig_escape_filter($env, $value, 'html'), $sep); + } + + /** + * nl2br only, for testing filters with pre_escape. + */ + public function nl2br($value, $sep = '
    ') + { + // not secure if $value contains html tags (not only entities) + // don't use + return str_replace("\n", "$sep\n", $value); + } + + public function dynamic_path($element, $item) + { + return $element.'/'.$item; + } + + public function dynamic_foo($foo, $bar, $item) + { + return $foo.'/'.$bar.'/'.$item; + } + + public function escape_something($value) + { + return strtoupper($value); + } + + public function preserves_safety($value) + { + return strtoupper($value); + } + + public static function staticCall($value) + { + return "*$value*"; + } + + public function br() + { + return '
    '; + } + + public function is_multi_word($value) + { + return false !== strpos($value, ' '); + } + + public function __call($method, $arguments) + { + if ('magicCall' !== $method) { + throw new BadMethodCallException('Unexpected call to __call'); + } + + return 'magic_'.$arguments[0]; + } + + public static function __callStatic($method, $arguments) + { + if ('magicStaticCall' !== $method) { + throw new BadMethodCallException('Unexpected call to __callStatic'); + } + + return 'static_magic_'.$arguments[0]; + } +} + +/** + * This class is used in tests for the "length" filter and "empty" test. It asserts that __call is not + * used to convert such objects to strings. + */ +class MagicCallStub +{ + public function __call($name, $args) + { + throw new Exception('__call shall not be called'); + } +} + +class ToStringStub +{ + /** + * @var string + */ + private $string; + + public function __construct($string) + { + $this->string = $string; + } + + public function __toString() + { + return $this->string; + } +} + +/** + * This class is used in tests for the length filter and empty test to show + * that when \Countable is implemented, it is preferred over the __toString() + * method. + */ +class CountableStub implements \Countable +{ + private $count; + + public function __construct($count) + { + $this->count = $count; + } + + public function count() + { + return $this->count; + } + + public function __toString() + { + throw new Exception('__toString shall not be called on \Countables'); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/LegacyFixtures/autoescape/filename.legacy.test b/vendor/twig/twig/test/Twig/Tests/LegacyFixtures/autoescape/filename.legacy.test new file mode 100644 index 000000000..b091ad34d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/LegacyFixtures/autoescape/filename.legacy.test @@ -0,0 +1,18 @@ +--TEST-- +"filename" autoescape strategy +--TEMPLATE-- +{{ br -}} +{{ include('index.html.twig') -}} +{{ include('index.txt.twig') -}} +--TEMPLATE(index.html.twig)-- +{{ br -}} +--TEMPLATE(index.txt.twig)-- +{{ br -}} +--DATA-- +return array('br' => '
    ') +--CONFIG-- +return array('autoescape' => 'filename') +--EXPECT-- +<br /> +<br /> +
    diff --git a/vendor/twig/twig/test/Twig/Tests/LegacyFixtures/functions/undefined_block.legacy.test b/vendor/twig/twig/test/Twig/Tests/LegacyFixtures/functions/undefined_block.legacy.test new file mode 100644 index 000000000..62e24f0f4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/LegacyFixtures/functions/undefined_block.legacy.test @@ -0,0 +1,12 @@ +--TEST-- +"block" function with undefined block +--TEMPLATE-- +{% extends "base.twig" %} +{% block foo %}{{ parent() }}{{ block('unknown') }}{{ block('bar') }}{% endblock %} +--TEMPLATE(base.twig)-- +{% block foo %}Foo{% endblock %} +{% block bar %}Bar{% endblock %} +--DATA-- +return array() +--EXPECT-- +FooBarBar diff --git a/vendor/twig/twig/test/Twig/Tests/LegacyFixtures/test.legacy.test b/vendor/twig/twig/test/Twig/Tests/LegacyFixtures/test.legacy.test new file mode 100644 index 000000000..d9c1d5085 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/LegacyFixtures/test.legacy.test @@ -0,0 +1,8 @@ +--TEST-- +Old test classes usage +--TEMPLATE-- +{{ 'foo' is multi word ? 'yes' : 'no' }} +--DATA-- +return array() +--EXPECT-- +no diff --git a/vendor/twig/twig/test/Twig/Tests/LegacyIntegrationTest.php b/vendor/twig/twig/test/Twig/Tests/LegacyIntegrationTest.php new file mode 100644 index 000000000..2ed758038 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/LegacyIntegrationTest.php @@ -0,0 +1,54 @@ + new Twig_Test_Method($this, 'is_multi_word'), + ); + } + + public function is_multi_word($value) + { + return false !== strpos($value, ' '); + } + + public function getName() + { + return 'legacy_integration_test'; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/LexerTest.php b/vendor/twig/twig/test/Twig/Tests/LexerTest.php new file mode 100644 index 000000000..c46044971 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/LexerTest.php @@ -0,0 +1,347 @@ +getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize('{{ foo }}', 'foo'); + $this->assertEquals('foo', $stream->getFilename()); + $this->assertEquals('{{ foo }}', $stream->getSource()); + } + + public function testNameLabelForTag() + { + $template = '{% § %}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + + $stream->expect(Twig_Token::BLOCK_START_TYPE); + $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue()); + } + + public function testNameLabelForFunction() + { + $template = '{{ §() }}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + + $stream->expect(Twig_Token::VAR_START_TYPE); + $this->assertSame('§', $stream->expect(Twig_Token::NAME_TYPE)->getValue()); + } + + public function testBracketsNesting() + { + $template = '{{ {"a":{"b":"c"}} }}'; + + $this->assertEquals(2, $this->countToken($template, Twig_Token::PUNCTUATION_TYPE, '{')); + $this->assertEquals(2, $this->countToken($template, Twig_Token::PUNCTUATION_TYPE, '}')); + } + + protected function countToken($template, $type, $value = null) + { + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + + $count = 0; + while (!$stream->isEOF()) { + $token = $stream->next(); + if ($type === $token->getType()) { + if (null === $value || $value === $token->getValue()) { + ++$count; + } + } + } + + return $count; + } + + public function testLineDirective() + { + $template = "foo\n" + ."bar\n" + ."{% line 10 %}\n" + ."{{\n" + ."baz\n" + ."}}\n"; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + + // foo\nbar\n + $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine()); + // \n (after {% line %}) + $this->assertSame(10, $stream->expect(Twig_Token::TEXT_TYPE)->getLine()); + // {{ + $this->assertSame(11, $stream->expect(Twig_Token::VAR_START_TYPE)->getLine()); + // baz + $this->assertSame(12, $stream->expect(Twig_Token::NAME_TYPE)->getLine()); + } + + public function testLineDirectiveInline() + { + $template = "foo\n" + ."bar{% line 10 %}{{\n" + ."baz\n" + ."}}\n"; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + + // foo\nbar + $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine()); + // {{ + $this->assertSame(10, $stream->expect(Twig_Token::VAR_START_TYPE)->getLine()); + // baz + $this->assertSame(11, $stream->expect(Twig_Token::NAME_TYPE)->getLine()); + } + + public function testLongComments() + { + $template = '{# '.str_repeat('*', 100000).' #}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $lexer->tokenize(new Twig_Source($template, 'index')); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + public function testLongVerbatim() + { + $template = '{% verbatim %}'.str_repeat('*', 100000).'{% endverbatim %}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $lexer->tokenize(new Twig_Source($template, 'index')); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + public function testLongVar() + { + $template = '{{ '.str_repeat('x', 100000).' }}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $lexer->tokenize(new Twig_Source($template, 'index')); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + public function testLongBlock() + { + $template = '{% '.str_repeat('x', 100000).' %}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $lexer->tokenize(new Twig_Source($template, 'index')); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + public function testBigNumbers() + { + $template = '{{ 922337203685477580700 }}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + $stream->next(); + $node = $stream->next(); + $this->assertEquals('922337203685477580700', $node->getValue()); + } + + public function testStringWithEscapedDelimiter() + { + $tests = array( + "{{ 'foo \' bar' }}" => 'foo \' bar', + '{{ "foo \" bar" }}' => 'foo " bar', + ); + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + foreach ($tests as $template => $expected) { + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + $stream->expect(Twig_Token::VAR_START_TYPE); + $stream->expect(Twig_Token::STRING_TYPE, $expected); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + } + + public function testStringWithInterpolation() + { + $template = 'foo {{ "bar #{ baz + 1 }" }}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + $stream->expect(Twig_Token::TEXT_TYPE, 'foo '); + $stream->expect(Twig_Token::VAR_START_TYPE); + $stream->expect(Twig_Token::STRING_TYPE, 'bar '); + $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); + $stream->expect(Twig_Token::NAME_TYPE, 'baz'); + $stream->expect(Twig_Token::OPERATOR_TYPE, '+'); + $stream->expect(Twig_Token::NUMBER_TYPE, '1'); + $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); + $stream->expect(Twig_Token::VAR_END_TYPE); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + public function testStringWithEscapedInterpolation() + { + $template = '{{ "bar \#{baz+1}" }}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + $stream->expect(Twig_Token::VAR_START_TYPE); + $stream->expect(Twig_Token::STRING_TYPE, 'bar #{baz+1}'); + $stream->expect(Twig_Token::VAR_END_TYPE); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + public function testStringWithHash() + { + $template = '{{ "bar # baz" }}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + $stream->expect(Twig_Token::VAR_START_TYPE); + $stream->expect(Twig_Token::STRING_TYPE, 'bar # baz'); + $stream->expect(Twig_Token::VAR_END_TYPE); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unclosed """ + */ + public function testStringWithUnterminatedInterpolation() + { + $template = '{{ "bar #{x" }}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $lexer->tokenize(new Twig_Source($template, 'index')); + } + + public function testStringWithNestedInterpolations() + { + $template = '{{ "bar #{ "foo#{bar}" }" }}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + $stream->expect(Twig_Token::VAR_START_TYPE); + $stream->expect(Twig_Token::STRING_TYPE, 'bar '); + $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); + $stream->expect(Twig_Token::STRING_TYPE, 'foo'); + $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); + $stream->expect(Twig_Token::NAME_TYPE, 'bar'); + $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); + $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); + $stream->expect(Twig_Token::VAR_END_TYPE); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + public function testStringWithNestedInterpolationsInBlock() + { + $template = '{% foo "bar #{ "foo#{bar}" }" %}'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + $stream->expect(Twig_Token::BLOCK_START_TYPE); + $stream->expect(Twig_Token::NAME_TYPE, 'foo'); + $stream->expect(Twig_Token::STRING_TYPE, 'bar '); + $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); + $stream->expect(Twig_Token::STRING_TYPE, 'foo'); + $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); + $stream->expect(Twig_Token::NAME_TYPE, 'bar'); + $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); + $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + public function testOperatorEndingWithALetterAtTheEndOfALine() + { + $template = "{{ 1 and\n0}}"; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $stream = $lexer->tokenize(new Twig_Source($template, 'index')); + $stream->expect(Twig_Token::VAR_START_TYPE); + $stream->expect(Twig_Token::NUMBER_TYPE, 1); + $stream->expect(Twig_Token::OPERATOR_TYPE, 'and'); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without throwing any exceptions + $this->addToAssertionCount(1); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unclosed "variable" in "index" at line 3 + */ + public function testUnterminatedVariable() + { + $template = ' + +{{ + +bar + + +'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $lexer->tokenize(new Twig_Source($template, 'index')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unclosed "block" in "index" at line 3 + */ + public function testUnterminatedBlock() + { + $template = ' + +{% + +bar + + +'; + + $lexer = new Twig_Lexer(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $lexer->tokenize(new Twig_Source($template, 'index')); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/ArrayTest.php b/vendor/twig/twig/test/Twig/Tests/Loader/ArrayTest.php new file mode 100644 index 000000000..7e1ea8129 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/ArrayTest.php @@ -0,0 +1,137 @@ + 'bar')); + + $this->assertEquals('bar', $loader->getSource('foo')); + } + + /** + * @group legacy + * @expectedException Twig_Error_Loader + */ + public function testGetSourceWhenTemplateDoesNotExist() + { + $loader = new Twig_Loader_Array(array()); + + $loader->getSource('foo'); + } + + /** + * @expectedException Twig_Error_Loader + */ + public function testGetSourceContextWhenTemplateDoesNotExist() + { + $loader = new Twig_Loader_Array(array()); + + $loader->getSourceContext('foo'); + } + + public function testGetCacheKey() + { + $loader = new Twig_Loader_Array(array('foo' => 'bar')); + + $this->assertEquals('foo:bar', $loader->getCacheKey('foo')); + } + + public function testGetCacheKeyWhenTemplateHasDuplicateContent() + { + $loader = new Twig_Loader_Array(array( + 'foo' => 'bar', + 'baz' => 'bar', + )); + + $this->assertEquals('foo:bar', $loader->getCacheKey('foo')); + $this->assertEquals('baz:bar', $loader->getCacheKey('baz')); + } + + public function testGetCacheKeyIsProtectedFromEdgeCollisions() + { + $loader = new Twig_Loader_Array(array( + 'foo__' => 'bar', + 'foo' => '__bar', + )); + + $this->assertEquals('foo__:bar', $loader->getCacheKey('foo__')); + $this->assertEquals('foo:__bar', $loader->getCacheKey('foo')); + } + + /** + * @expectedException Twig_Error_Loader + */ + public function testGetCacheKeyWhenTemplateDoesNotExist() + { + $loader = new Twig_Loader_Array(array()); + + $loader->getCacheKey('foo'); + } + + public function testSetTemplate() + { + $loader = new Twig_Loader_Array(array()); + $loader->setTemplate('foo', 'bar'); + + $this->assertEquals('bar', $loader->getSourceContext('foo')->getCode()); + } + + public function testIsFresh() + { + $loader = new Twig_Loader_Array(array('foo' => 'bar')); + $this->assertTrue($loader->isFresh('foo', time())); + } + + /** + * @expectedException Twig_Error_Loader + */ + public function testIsFreshWhenTemplateDoesNotExist() + { + $loader = new Twig_Loader_Array(array()); + + $loader->isFresh('foo', time()); + } + + public function testTemplateReference() + { + $name = new Twig_Test_Loader_TemplateReference('foo'); + $loader = new Twig_Loader_Array(array('foo' => 'bar')); + + $loader->getCacheKey($name); + $loader->getSourceContext($name); + $loader->isFresh($name, time()); + $loader->setTemplate($name, 'foo:bar'); + + // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above + // can be executed without crashing PHP + $this->addToAssertionCount(1); + } +} + +class Twig_Test_Loader_TemplateReference +{ + private $name; + + public function __construct($name) + { + $this->name = $name; + } + + public function __toString() + { + return $this->name; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/ChainTest.php b/vendor/twig/twig/test/Twig/Tests/Loader/ChainTest.php new file mode 100644 index 000000000..733de4f02 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/ChainTest.php @@ -0,0 +1,124 @@ + 'bar')), + new Twig_Loader_Array(array('foo' => 'foobar', 'bar' => 'foo')), + )); + + $this->assertEquals('bar', $loader->getSource('foo')); + $this->assertEquals('foo', $loader->getSource('bar')); + } + + public function testGetSourceContext() + { + $path = dirname(__FILE__).'/../Fixtures'; + $loader = new Twig_Loader_Chain(array( + new Twig_Loader_Array(array('foo' => 'bar')), + new Twig_Loader_Array(array('errors/index.html' => 'baz')), + new Twig_Loader_Filesystem(array($path)), + )); + + $this->assertEquals('foo', $loader->getSourceContext('foo')->getName()); + $this->assertSame('', $loader->getSourceContext('foo')->getPath()); + + $this->assertEquals('errors/index.html', $loader->getSourceContext('errors/index.html')->getName()); + $this->assertSame('', $loader->getSourceContext('errors/index.html')->getPath()); + $this->assertEquals('baz', $loader->getSourceContext('errors/index.html')->getCode()); + + $this->assertEquals('errors/base.html', $loader->getSourceContext('errors/base.html')->getName()); + $this->assertEquals(realpath($path.'/errors/base.html'), realpath($loader->getSourceContext('errors/base.html')->getPath())); + $this->assertNotEquals('baz', $loader->getSourceContext('errors/base.html')->getCode()); + } + + /** + * @expectedException Twig_Error_Loader + */ + public function testGetSourceContextWhenTemplateDoesNotExist() + { + $loader = new Twig_Loader_Chain(array()); + + $loader->getSourceContext('foo'); + } + + /** + * @group legacy + * @expectedException Twig_Error_Loader + */ + public function testGetSourceWhenTemplateDoesNotExist() + { + $loader = new Twig_Loader_Chain(array()); + + $loader->getSource('foo'); + } + + public function testGetCacheKey() + { + $loader = new Twig_Loader_Chain(array( + new Twig_Loader_Array(array('foo' => 'bar')), + new Twig_Loader_Array(array('foo' => 'foobar', 'bar' => 'foo')), + )); + + $this->assertEquals('foo:bar', $loader->getCacheKey('foo')); + $this->assertEquals('bar:foo', $loader->getCacheKey('bar')); + } + + /** + * @expectedException Twig_Error_Loader + */ + public function testGetCacheKeyWhenTemplateDoesNotExist() + { + $loader = new Twig_Loader_Chain(array()); + + $loader->getCacheKey('foo'); + } + + public function testAddLoader() + { + $loader = new Twig_Loader_Chain(); + $loader->addLoader(new Twig_Loader_Array(array('foo' => 'bar'))); + + $this->assertEquals('bar', $loader->getSourceContext('foo')->getCode()); + } + + public function testExists() + { + $loader1 = $this->getMockBuilder('Twig_ChainTestLoaderWithExistsInterface')->getMock(); + $loader1->expects($this->once())->method('exists')->will($this->returnValue(false)); + $loader1->expects($this->never())->method('getSourceContext'); + + // can be removed in 2.0 + $loader2 = $this->getMockBuilder('Twig_ChainTestLoaderInterface')->getMock(); + //$loader2 = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock(); + $loader2->expects($this->once())->method('getSourceContext')->will($this->returnValue(new Twig_Source('content', 'index'))); + + $loader = new Twig_Loader_Chain(); + $loader->addLoader($loader1); + $loader->addLoader($loader2); + + $this->assertTrue($loader->exists('foo')); + } +} + +interface Twig_ChainTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface +{ +} + +interface Twig_ChainTestLoaderWithExistsInterface extends Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface +{ +} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/FilesystemTest.php b/vendor/twig/twig/test/Twig/Tests/Loader/FilesystemTest.php new file mode 100644 index 000000000..c8cbaf718 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/FilesystemTest.php @@ -0,0 +1,226 @@ +assertEquals('errors/index.html', $loader->getSourceContext('errors/index.html')->getName()); + $this->assertEquals(realpath($path.'/errors/index.html'), realpath($loader->getSourceContext('errors/index.html')->getPath())); + } + + /** + * @dataProvider getSecurityTests + */ + public function testSecurity($template) + { + $loader = new Twig_Loader_Filesystem(array(dirname(__FILE__).'/../Fixtures')); + + try { + $loader->getCacheKey($template); + $this->fail(); + } catch (Twig_Error_Loader $e) { + $this->assertNotContains('Unable to find template', $e->getMessage()); + } + } + + public function getSecurityTests() + { + return array( + array("AutoloaderTest\0.php"), + array('..\\AutoloaderTest.php'), + array('..\\\\\\AutoloaderTest.php'), + array('../AutoloaderTest.php'), + array('..////AutoloaderTest.php'), + array('./../AutoloaderTest.php'), + array('.\\..\\AutoloaderTest.php'), + array('././././././../AutoloaderTest.php'), + array('.\\./.\\./.\\./../AutoloaderTest.php'), + array('foo/../../AutoloaderTest.php'), + array('foo\\..\\..\\AutoloaderTest.php'), + array('foo/../bar/../../AutoloaderTest.php'), + array('foo/bar/../../../AutoloaderTest.php'), + array('filters/../../AutoloaderTest.php'), + array('filters//..//..//AutoloaderTest.php'), + array('filters\\..\\..\\AutoloaderTest.php'), + array('filters\\\\..\\\\..\\\\AutoloaderTest.php'), + array('filters\\//../\\/\\..\\AutoloaderTest.php'), + array('/../AutoloaderTest.php'), + ); + } + + /** + * @dataProvider getBasePaths + */ + public function testPaths($basePath, $cacheKey, $rootPath) + { + $loader = new Twig_Loader_Filesystem(array($basePath.'/normal', $basePath.'/normal_bis'), $rootPath); + $loader->setPaths(array($basePath.'/named', $basePath.'/named_bis'), 'named'); + $loader->addPath($basePath.'/named_ter', 'named'); + $loader->addPath($basePath.'/normal_ter'); + $loader->prependPath($basePath.'/normal_final'); + $loader->prependPath($basePath.'/named/../named_quater', 'named'); + $loader->prependPath($basePath.'/named_final', 'named'); + + $this->assertEquals(array( + $basePath.'/normal_final', + $basePath.'/normal', + $basePath.'/normal_bis', + $basePath.'/normal_ter', + ), $loader->getPaths()); + $this->assertEquals(array( + $basePath.'/named_final', + $basePath.'/named/../named_quater', + $basePath.'/named', + $basePath.'/named_bis', + $basePath.'/named_ter', + ), $loader->getPaths('named')); + + // do not use realpath here as it would make the test unuseful + $this->assertEquals($cacheKey, str_replace('\\', '/', $loader->getCacheKey('@named/named_absolute.html'))); + $this->assertEquals("path (final)\n", $loader->getSourceContext('index.html')->getCode()); + $this->assertEquals("path (final)\n", $loader->getSourceContext('@__main__/index.html')->getCode()); + $this->assertEquals("named path (final)\n", $loader->getSourceContext('@named/index.html')->getCode()); + } + + public function getBasePaths() + { + return array( + array( + dirname(__FILE__).'/Fixtures', + 'test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html', + null, + ), + array( + dirname(__FILE__).'/Fixtures/../Fixtures', + 'test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html', + null, + ), + array( + 'test/Twig/Tests/Loader/Fixtures', + 'test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html', + getcwd(), + ), + array( + 'Fixtures', + 'Fixtures/named_quater/named_absolute.html', + getcwd().'/test/Twig/Tests/Loader', + ), + array( + 'Fixtures', + 'Fixtures/named_quater/named_absolute.html', + getcwd().'/test/../test/Twig/Tests/Loader', + ), + ); + } + + public function testEmptyConstructor() + { + $loader = new Twig_Loader_Filesystem(); + $this->assertEquals(array(), $loader->getPaths()); + } + + public function testGetNamespaces() + { + $loader = new Twig_Loader_Filesystem(sys_get_temp_dir()); + $this->assertEquals(array(Twig_Loader_Filesystem::MAIN_NAMESPACE), $loader->getNamespaces()); + + $loader->addPath(sys_get_temp_dir(), 'named'); + $this->assertEquals(array(Twig_Loader_Filesystem::MAIN_NAMESPACE, 'named'), $loader->getNamespaces()); + } + + public function testFindTemplateExceptionNamespace() + { + $basePath = dirname(__FILE__).'/Fixtures'; + + $loader = new Twig_Loader_Filesystem(array($basePath.'/normal')); + $loader->addPath($basePath.'/named', 'named'); + + try { + $loader->getSourceContext('@named/nowhere.html'); + } catch (Exception $e) { + $this->assertInstanceof('Twig_Error_Loader', $e); + $this->assertContains('Unable to find template "@named/nowhere.html"', $e->getMessage()); + } + } + + public function testFindTemplateWithCache() + { + $basePath = dirname(__FILE__).'/Fixtures'; + + $loader = new Twig_Loader_Filesystem(array($basePath.'/normal')); + $loader->addPath($basePath.'/named', 'named'); + + // prime the cache for index.html in the named namespace + $namedSource = $loader->getSourceContext('@named/index.html')->getCode(); + $this->assertEquals("named path\n", $namedSource); + + // get index.html from the main namespace + $this->assertEquals("path\n", $loader->getSourceContext('index.html')->getCode()); + } + + public function testLoadTemplateAndRenderBlockWithCache() + { + $loader = new Twig_Loader_Filesystem(array()); + $loader->addPath(dirname(__FILE__).'/Fixtures/themes/theme2'); + $loader->addPath(dirname(__FILE__).'/Fixtures/themes/theme1'); + $loader->addPath(dirname(__FILE__).'/Fixtures/themes/theme1', 'default_theme'); + + $twig = new Twig_Environment($loader); + + $template = $twig->loadTemplate('blocks.html.twig'); + $this->assertSame('block from theme 1', $template->renderBlock('b1', array())); + + $template = $twig->loadTemplate('blocks.html.twig'); + $this->assertSame('block from theme 2', $template->renderBlock('b2', array())); + } + + public function getArrayInheritanceTests() + { + return array( + 'valid array inheritance' => array('array_inheritance_valid_parent.html.twig'), + 'array inheritance with null first template' => array('array_inheritance_null_parent.html.twig'), + 'array inheritance with empty first template' => array('array_inheritance_empty_parent.html.twig'), + 'array inheritance with non-existent first template' => array('array_inheritance_nonexistent_parent.html.twig'), + ); + } + + /** + * @dataProvider getArrayInheritanceTests + * + * @param $templateName string Template name with array inheritance + */ + public function testArrayInheritance($templateName) + { + $loader = new Twig_Loader_Filesystem(array()); + $loader->addPath(dirname(__FILE__).'/Fixtures/inheritance'); + + $twig = new Twig_Environment($loader); + + $template = $twig->loadTemplate($templateName); + $this->assertSame('VALID Child', $template->renderBlock('body', array())); + } + + /** + * @requires PHP 5.3 + */ + public function testLoadTemplateFromPhar() + { + $loader = new Twig_Loader_Filesystem(array()); + // phar-sample.phar was created with the following script: + // $f = new Phar('phar-test.phar'); + // $f->addFromString('hello.twig', 'hello from phar'); + $loader->addPath('phar://'.dirname(__FILE__).'/Fixtures/phar/phar-sample.phar'); + $this->assertSame('hello from phar', $loader->getSourceContext('hello.twig')->getCode()); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_empty_parent.html.twig b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_empty_parent.html.twig new file mode 100644 index 000000000..6977ebf66 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_empty_parent.html.twig @@ -0,0 +1,3 @@ +{% extends ['','parent.html.twig'] %} + +{% block body %}{{ parent() }} Child{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_nonexistent_parent.html.twig b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_nonexistent_parent.html.twig new file mode 100644 index 000000000..5b50a8b21 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_nonexistent_parent.html.twig @@ -0,0 +1,3 @@ +{% extends ['nonexistent.html.twig','parent.html.twig'] %} + +{% block body %}{{ parent() }} Child{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_null_parent.html.twig b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_null_parent.html.twig new file mode 100644 index 000000000..a16b3aded --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_null_parent.html.twig @@ -0,0 +1,3 @@ +{% extends [null,'parent.html.twig'] %} + +{% block body %}{{ parent() }} Child{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_valid_parent.html.twig b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_valid_parent.html.twig new file mode 100644 index 000000000..4940dad41 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/array_inheritance_valid_parent.html.twig @@ -0,0 +1,3 @@ +{% extends ['parent.html.twig','spare_parent.html.twig'] %} + +{% block body %}{{ parent() }} Child{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/parent.html.twig b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/parent.html.twig new file mode 100644 index 000000000..d594c0ed4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/parent.html.twig @@ -0,0 +1 @@ +{% block body %}VALID{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/spare_parent.html.twig b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/spare_parent.html.twig new file mode 100644 index 000000000..70b7360a2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/inheritance/spare_parent.html.twig @@ -0,0 +1 @@ +{% block body %}SPARE PARENT{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named/index.html b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named/index.html new file mode 100644 index 000000000..9e5449c7c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named/index.html @@ -0,0 +1 @@ +named path diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_bis/index.html b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_bis/index.html new file mode 100644 index 000000000..d3a272b19 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_bis/index.html @@ -0,0 +1 @@ +named path (bis) diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_final/index.html b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_final/index.html new file mode 100644 index 000000000..9f05d1507 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_final/index.html @@ -0,0 +1 @@ +named path (final) diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html new file mode 100644 index 000000000..b1fb5f5d7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_quater/named_absolute.html @@ -0,0 +1 @@ +named path (quater) diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_ter/index.html b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_ter/index.html new file mode 100644 index 000000000..24fb68ad2 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/named_ter/index.html @@ -0,0 +1 @@ +named path (ter) diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal/index.html b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal/index.html new file mode 100644 index 000000000..e7a8fd4d0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal/index.html @@ -0,0 +1 @@ +path diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_bis/index.html b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_bis/index.html new file mode 100644 index 000000000..bfa916049 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_bis/index.html @@ -0,0 +1 @@ +path (bis) diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_final/index.html b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_final/index.html new file mode 100644 index 000000000..73a089bbd --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_final/index.html @@ -0,0 +1 @@ +path (final) diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_ter/index.html b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_ter/index.html new file mode 100644 index 000000000..b7ad97d8f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/normal_ter/index.html @@ -0,0 +1 @@ +path (ter) diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/phar/phar-sample.phar b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/phar/phar-sample.phar new file mode 100644 index 000000000..092bbfae3 Binary files /dev/null and b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/phar/phar-sample.phar differ diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/themes/theme1/blocks.html.twig b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/themes/theme1/blocks.html.twig new file mode 100644 index 000000000..dd0cbc2e7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/themes/theme1/blocks.html.twig @@ -0,0 +1,3 @@ +{% block b1 %}block from theme 1{% endblock %} + +{% block b2 %}block from theme 1{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/themes/theme2/blocks.html.twig b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/themes/theme2/blocks.html.twig new file mode 100644 index 000000000..07cf9db0d --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Loader/Fixtures/themes/theme2/blocks.html.twig @@ -0,0 +1,3 @@ +{% use '@default_theme/blocks.html.twig' %} + +{% block b2 %}block from theme 2{% endblock %} diff --git a/vendor/twig/twig/test/Twig/Tests/NativeExtensionTest.php b/vendor/twig/twig/test/Twig/Tests/NativeExtensionTest.php new file mode 100644 index 000000000..f1278eec3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/NativeExtensionTest.php @@ -0,0 +1,32 @@ + '{{ d1.date }}{{ d2.date }}')), array( + 'debug' => true, + 'cache' => false, + 'autoescape' => false, + )); + + $d1 = new DateTime(); + $d2 = new DateTime(); + $output = $twig->render('index', compact('d1', 'd2')); + + // If it fails, PHP will crash. + $this->assertEquals($output, $d1->date.$d2->date); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/AutoEscapeTest.php b/vendor/twig/twig/test/Twig/Tests/Node/AutoEscapeTest.php new file mode 100644 index 000000000..25d16023f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/AutoEscapeTest.php @@ -0,0 +1,32 @@ +assertEquals($body, $node->getNode('body')); + $this->assertTrue($node->getAttribute('value')); + } + + public function getTests() + { + $body = new Twig_Node(array(new Twig_Node_Text('foo', 1))); + $node = new Twig_Node_AutoEscape(true, $body, 1); + + return array( + array($node, "// line 1\necho \"foo\";"), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/BlockReferenceTest.php b/vendor/twig/twig/test/Twig/Tests/Node/BlockReferenceTest.php new file mode 100644 index 000000000..84dac9bfa --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/BlockReferenceTest.php @@ -0,0 +1,31 @@ +assertEquals('foo', $node->getAttribute('name')); + } + + public function getTests() + { + return array( + array(new Twig_Node_BlockReference('foo', 1), <<displayBlock('foo', \$context, \$blocks); +EOF + ), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/BlockTest.php b/vendor/twig/twig/test/Twig/Tests/Node/BlockTest.php new file mode 100644 index 000000000..e7246dcc3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/BlockTest.php @@ -0,0 +1,39 @@ +assertEquals($body, $node->getNode('body')); + $this->assertEquals('foo', $node->getAttribute('name')); + } + + public function getTests() + { + $body = new Twig_Node_Text('foo', 1); + $node = new Twig_Node_Block('foo', $body, 1); + + return array( + array($node, <<assertEquals($expr, $node->getNode('expr')); + } + + public function getTests() + { + $tests = array(); + + $expr = new Twig_Node_Expression_Constant('foo', 1); + $node = new Twig_Node_Do($expr, 1); + $tests[] = array($node, "// line 1\n\"foo\";"); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/ArrayTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/ArrayTest.php new file mode 100644 index 000000000..4f83ab176 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/ArrayTest.php @@ -0,0 +1,37 @@ +assertEquals($foo, $node->getNode(1)); + } + + public function getTests() + { + $elements = array( + new Twig_Node_Expression_Constant('foo', 1), + new Twig_Node_Expression_Constant('bar', 1), + + new Twig_Node_Expression_Constant('bar', 1), + new Twig_Node_Expression_Constant('foo', 1), + ); + $node = new Twig_Node_Expression_Array($elements, 1); + + return array( + array($node, 'array("foo" => "bar", "bar" => "foo")'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/AssignNameTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/AssignNameTest.php new file mode 100644 index 000000000..bf365de49 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/AssignNameTest.php @@ -0,0 +1,29 @@ +assertEquals('foo', $node->getAttribute('name')); + } + + public function getTests() + { + $node = new Twig_Node_Expression_AssignName('foo', 1); + + return array( + array($node, '$context["foo"]'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/AddTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/AddTest.php new file mode 100644 index 000000000..02310a1b0 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/AddTest.php @@ -0,0 +1,34 @@ +assertEquals($left, $node->getNode('left')); + $this->assertEquals($right, $node->getNode('right')); + } + + public function getTests() + { + $left = new Twig_Node_Expression_Constant(1, 1); + $right = new Twig_Node_Expression_Constant(2, 1); + $node = new Twig_Node_Expression_Binary_Add($left, $right, 1); + + return array( + array($node, '(1 + 2)'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/AndTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/AndTest.php new file mode 100644 index 000000000..2df3c8e45 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/AndTest.php @@ -0,0 +1,34 @@ +assertEquals($left, $node->getNode('left')); + $this->assertEquals($right, $node->getNode('right')); + } + + public function getTests() + { + $left = new Twig_Node_Expression_Constant(1, 1); + $right = new Twig_Node_Expression_Constant(2, 1); + $node = new Twig_Node_Expression_Binary_And($left, $right, 1); + + return array( + array($node, '(1 && 2)'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/ConcatTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/ConcatTest.php new file mode 100644 index 000000000..759e48289 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/ConcatTest.php @@ -0,0 +1,34 @@ +assertEquals($left, $node->getNode('left')); + $this->assertEquals($right, $node->getNode('right')); + } + + public function getTests() + { + $left = new Twig_Node_Expression_Constant(1, 1); + $right = new Twig_Node_Expression_Constant(2, 1); + $node = new Twig_Node_Expression_Binary_Concat($left, $right, 1); + + return array( + array($node, '(1 . 2)'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/DivTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/DivTest.php new file mode 100644 index 000000000..0e54b10a3 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/DivTest.php @@ -0,0 +1,34 @@ +assertEquals($left, $node->getNode('left')); + $this->assertEquals($right, $node->getNode('right')); + } + + public function getTests() + { + $left = new Twig_Node_Expression_Constant(1, 1); + $right = new Twig_Node_Expression_Constant(2, 1); + $node = new Twig_Node_Expression_Binary_Div($left, $right, 1); + + return array( + array($node, '(1 / 2)'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/FloorDivTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/FloorDivTest.php new file mode 100644 index 000000000..5813dce6e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/FloorDivTest.php @@ -0,0 +1,34 @@ +assertEquals($left, $node->getNode('left')); + $this->assertEquals($right, $node->getNode('right')); + } + + public function getTests() + { + $left = new Twig_Node_Expression_Constant(1, 1); + $right = new Twig_Node_Expression_Constant(2, 1); + $node = new Twig_Node_Expression_Binary_FloorDiv($left, $right, 1); + + return array( + array($node, '(int) floor((1 / 2))'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/ModTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/ModTest.php new file mode 100644 index 000000000..4c663c787 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/ModTest.php @@ -0,0 +1,34 @@ +assertEquals($left, $node->getNode('left')); + $this->assertEquals($right, $node->getNode('right')); + } + + public function getTests() + { + $left = new Twig_Node_Expression_Constant(1, 1); + $right = new Twig_Node_Expression_Constant(2, 1); + $node = new Twig_Node_Expression_Binary_Mod($left, $right, 1); + + return array( + array($node, '(1 % 2)'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/MulTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/MulTest.php new file mode 100644 index 000000000..e92c95e64 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/MulTest.php @@ -0,0 +1,34 @@ +assertEquals($left, $node->getNode('left')); + $this->assertEquals($right, $node->getNode('right')); + } + + public function getTests() + { + $left = new Twig_Node_Expression_Constant(1, 1); + $right = new Twig_Node_Expression_Constant(2, 1); + $node = new Twig_Node_Expression_Binary_Mul($left, $right, 1); + + return array( + array($node, '(1 * 2)'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/OrTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/OrTest.php new file mode 100644 index 000000000..ec37c83eb --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/OrTest.php @@ -0,0 +1,34 @@ +assertEquals($left, $node->getNode('left')); + $this->assertEquals($right, $node->getNode('right')); + } + + public function getTests() + { + $left = new Twig_Node_Expression_Constant(1, 1); + $right = new Twig_Node_Expression_Constant(2, 1); + $node = new Twig_Node_Expression_Binary_Or($left, $right, 1); + + return array( + array($node, '(1 || 2)'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/SubTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/SubTest.php new file mode 100644 index 000000000..061cb270f --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Binary/SubTest.php @@ -0,0 +1,34 @@ +assertEquals($left, $node->getNode('left')); + $this->assertEquals($right, $node->getNode('right')); + } + + public function getTests() + { + $left = new Twig_Node_Expression_Constant(1, 1); + $right = new Twig_Node_Expression_Constant(2, 1); + $node = new Twig_Node_Expression_Binary_Sub($left, $right, 1); + + return array( + array($node, '(1 - 2)'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/CallTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/CallTest.php new file mode 100644 index 000000000..be7b417b9 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/CallTest.php @@ -0,0 +1,143 @@ + 'function', 'name' => 'date')); + $this->assertEquals(array('U', null), $node->getArguments('date', array('format' => 'U', 'timestamp' => null))); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Positional arguments cannot be used after named arguments for function "date". + */ + public function testGetArgumentsWhenPositionalArgumentsAfterNamedArguments() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'date')); + $node->getArguments('date', array('timestamp' => 123456, 'Y-m-d')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Argument "format" is defined twice for function "date". + */ + public function testGetArgumentsWhenArgumentIsDefinedTwice() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'date')); + $node->getArguments('date', array('Y-m-d', 'format' => 'U')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown argument "unknown" for function "date(format, timestamp)". + */ + public function testGetArgumentsWithWrongNamedArgumentName() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'date')); + $node->getArguments('date', array('Y-m-d', 'timestamp' => null, 'unknown' => '')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown arguments "unknown1", "unknown2" for function "date(format, timestamp)". + */ + public function testGetArgumentsWithWrongNamedArgumentNames() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'date')); + $node->getArguments('date', array('Y-m-d', 'timestamp' => null, 'unknown1' => '', 'unknown2' => '')); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Argument "case_sensitivity" could not be assigned for function "substr_compare(main_str, str, offset, length, case_sensitivity)" because it is mapped to an internal PHP function which cannot determine default value for optional argument "length". + */ + public function testResolveArgumentsWithMissingValueForOptionalArgument() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'substr_compare')); + $node->getArguments('substr_compare', array('abcd', 'bc', 'offset' => 1, 'case_sensitivity' => true)); + } + + public function testResolveArgumentsOnlyNecessaryArgumentsForCustomFunction() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'custom_function')); + + $this->assertEquals(array('arg1'), $node->getArguments(array($this, 'customFunction'), array('arg1' => 'arg1'))); + } + + public function testGetArgumentsForStaticMethod() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'custom_static_function')); + $this->assertEquals(array('arg1'), $node->getArguments(__CLASS__.'::customStaticFunction', array('arg1' => 'arg1'))); + } + + /** + * @expectedException LogicException + * @expectedExceptionMessage The last parameter of "Twig_Tests_Node_Expression_CallTest::customFunctionWithArbitraryArguments" for function "foo" must be an array with default value, eg. "array $arg = array()". + */ + public function testResolveArgumentsWithMissingParameterForArbitraryArguments() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'foo', 'is_variadic' => true)); + $node->getArguments(array($this, 'customFunctionWithArbitraryArguments'), array()); + } + + public static function customStaticFunction($arg1, $arg2 = 'default', $arg3 = array()) + { + } + + public function customFunction($arg1, $arg2 = 'default', $arg3 = array()) + { + } + + public function customFunctionWithArbitraryArguments() + { + } + + /** + * @expectedException LogicException + * @expectedExceptionMessageRegExp #^The last parameter of "custom_Twig_Tests_Node_Expression_CallTest_function" for function "foo" must be an array with default value, eg\. "array \$arg \= array\(\)"\.$# + */ + public function testResolveArgumentsWithMissingParameterForArbitraryArgumentsOnFunction() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'foo', 'is_variadic' => true)); + $node->getArguments('custom_Twig_Tests_Node_Expression_CallTest_function', array()); + } + + /** + * @expectedException LogicException + * @expectedExceptionMessageRegExp #^The last parameter of "CallableTestClass\:\:__invoke" for function "foo" must be an array with default value, eg\. "array \$arg \= array\(\)"\.$# + */ + public function testResolveArgumentsWithMissingParameterForArbitraryArgumentsOnObject() + { + $node = new Twig_Tests_Node_Expression_Call(array(), array('type' => 'function', 'name' => 'foo', 'is_variadic' => true)); + $node->getArguments(new CallableTestClass(), array()); + } +} + +class Twig_Tests_Node_Expression_Call extends Twig_Node_Expression_Call +{ + public function getArguments($callable, $arguments) + { + return parent::getArguments($callable, $arguments); + } +} + +class CallableTestClass +{ + public function __invoke($required) + { + } +} + +function custom_Twig_Tests_Node_Expression_CallTest_function($required) +{ +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/ConditionalTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/ConditionalTest.php new file mode 100644 index 000000000..a3e8badff --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/ConditionalTest.php @@ -0,0 +1,38 @@ +assertEquals($expr1, $node->getNode('expr1')); + $this->assertEquals($expr2, $node->getNode('expr2')); + $this->assertEquals($expr3, $node->getNode('expr3')); + } + + public function getTests() + { + $tests = array(); + + $expr1 = new Twig_Node_Expression_Constant(1, 1); + $expr2 = new Twig_Node_Expression_Constant(2, 1); + $expr3 = new Twig_Node_Expression_Constant(3, 1); + $node = new Twig_Node_Expression_Conditional($expr1, $expr2, $expr3, 1); + $tests[] = array($node, '((1) ? (2) : (3))'); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/ConstantTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/ConstantTest.php new file mode 100644 index 000000000..2ff931822 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/ConstantTest.php @@ -0,0 +1,30 @@ +assertEquals('foo', $node->getAttribute('value')); + } + + public function getTests() + { + $tests = array(); + + $node = new Twig_Node_Expression_Constant('foo', 1); + $tests[] = array($node, '"foo"'); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/FilterTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/FilterTest.php new file mode 100644 index 000000000..773375c94 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/FilterTest.php @@ -0,0 +1,154 @@ +assertEquals($expr, $node->getNode('node')); + $this->assertEquals($name, $node->getNode('filter')); + $this->assertEquals($args, $node->getNode('arguments')); + } + + public function getTests() + { + $environment = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $environment->addFilter(new Twig_SimpleFilter('bar', 'bar', array('needs_environment' => true))); + $environment->addFilter(new Twig_SimpleFilter('barbar', 'twig_tests_filter_barbar', array('needs_context' => true, 'is_variadic' => true))); + + $tests = array(); + + $expr = new Twig_Node_Expression_Constant('foo', 1); + $node = $this->createFilter($expr, 'upper'); + $node = $this->createFilter($node, 'number_format', array(new Twig_Node_Expression_Constant(2, 1), new Twig_Node_Expression_Constant('.', 1), new Twig_Node_Expression_Constant(',', 1))); + + if (function_exists('mb_get_info')) { + $tests[] = array($node, 'twig_number_format_filter($this->env, twig_upper_filter($this->env, "foo"), 2, ".", ",")'); + } else { + $tests[] = array($node, 'twig_number_format_filter($this->env, strtoupper("foo"), 2, ".", ",")'); + } + + // named arguments + $date = new Twig_Node_Expression_Constant(0, 1); + $node = $this->createFilter($date, 'date', array( + 'timezone' => new Twig_Node_Expression_Constant('America/Chicago', 1), + 'format' => new Twig_Node_Expression_Constant('d/m/Y H:i:s P', 1), + )); + $tests[] = array($node, 'twig_date_format_filter($this->env, 0, "d/m/Y H:i:s P", "America/Chicago")'); + + // skip an optional argument + $date = new Twig_Node_Expression_Constant(0, 1); + $node = $this->createFilter($date, 'date', array( + 'timezone' => new Twig_Node_Expression_Constant('America/Chicago', 1), + )); + $tests[] = array($node, 'twig_date_format_filter($this->env, 0, null, "America/Chicago")'); + + // underscores vs camelCase for named arguments + $string = new Twig_Node_Expression_Constant('abc', 1); + $node = $this->createFilter($string, 'reverse', array( + 'preserve_keys' => new Twig_Node_Expression_Constant(true, 1), + )); + $tests[] = array($node, 'twig_reverse_filter($this->env, "abc", true)'); + $node = $this->createFilter($string, 'reverse', array( + 'preserveKeys' => new Twig_Node_Expression_Constant(true, 1), + )); + $tests[] = array($node, 'twig_reverse_filter($this->env, "abc", true)'); + + // filter as an anonymous function + if (PHP_VERSION_ID >= 50300) { + $node = $this->createFilter(new Twig_Node_Expression_Constant('foo', 1), 'anonymous'); + $tests[] = array($node, 'call_user_func_array($this->env->getFilter(\'anonymous\')->getCallable(), array("foo"))'); + } + + // needs environment + $node = $this->createFilter($string, 'bar'); + $tests[] = array($node, 'bar($this->env, "abc")', $environment); + + $node = $this->createFilter($string, 'bar', array(new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'bar($this->env, "abc", "bar")', $environment); + + // arbitrary named arguments + $node = $this->createFilter($string, 'barbar'); + $tests[] = array($node, 'twig_tests_filter_barbar($context, "abc")', $environment); + + $node = $this->createFilter($string, 'barbar', array('foo' => new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'twig_tests_filter_barbar($context, "abc", null, null, array("foo" => "bar"))', $environment); + + $node = $this->createFilter($string, 'barbar', array('arg2' => new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'twig_tests_filter_barbar($context, "abc", null, "bar")', $environment); + + $node = $this->createFilter($string, 'barbar', array( + new Twig_Node_Expression_Constant('1', 1), + new Twig_Node_Expression_Constant('2', 1), + new Twig_Node_Expression_Constant('3', 1), + 'foo' => new Twig_Node_Expression_Constant('bar', 1), + )); + $tests[] = array($node, 'twig_tests_filter_barbar($context, "abc", "1", "2", array(0 => "3", "foo" => "bar"))', $environment); + + return $tests; + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown argument "foobar" for filter "date(format, timezone)" at line 1. + */ + public function testCompileWithWrongNamedArgumentName() + { + $date = new Twig_Node_Expression_Constant(0, 1); + $node = $this->createFilter($date, 'date', array( + 'foobar' => new Twig_Node_Expression_Constant('America/Chicago', 1), + )); + + $compiler = $this->getCompiler(); + $compiler->compile($node); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Value for argument "from" is required for filter "replace". + */ + public function testCompileWithMissingNamedArgument() + { + $value = new Twig_Node_Expression_Constant(0, 1); + $node = $this->createFilter($value, 'replace', array( + 'to' => new Twig_Node_Expression_Constant('foo', 1), + )); + + $compiler = $this->getCompiler(); + $compiler->compile($node); + } + + protected function createFilter($node, $name, array $arguments = array()) + { + $name = new Twig_Node_Expression_Constant($name, 1); + $arguments = new Twig_Node($arguments); + + return new Twig_Node_Expression_Filter($node, $name, $arguments, 1); + } + + protected function getEnvironment() + { + if (PHP_VERSION_ID >= 50300) { + return include 'PHP53/FilterInclude.php'; + } + + return parent::getEnvironment(); + } +} + +function twig_tests_filter_barbar($context, $string, $arg1 = null, $arg2 = null, array $args = array()) +{ +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/FunctionTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/FunctionTest.php new file mode 100644 index 000000000..2e82e2f11 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/FunctionTest.php @@ -0,0 +1,110 @@ +assertEquals($name, $node->getAttribute('name')); + $this->assertEquals($args, $node->getNode('arguments')); + } + + public function getTests() + { + $environment = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $environment->addFunction(new Twig_SimpleFunction('foo', 'foo', array())); + $environment->addFunction(new Twig_SimpleFunction('bar', 'bar', array('needs_environment' => true))); + $environment->addFunction(new Twig_SimpleFunction('foofoo', 'foofoo', array('needs_context' => true))); + $environment->addFunction(new Twig_SimpleFunction('foobar', 'foobar', array('needs_environment' => true, 'needs_context' => true))); + $environment->addFunction(new Twig_SimpleFunction('barbar', 'twig_tests_function_barbar', array('is_variadic' => true))); + + $tests = array(); + + $node = $this->createFunction('foo'); + $tests[] = array($node, 'foo()', $environment); + + $node = $this->createFunction('foo', array(new Twig_Node_Expression_Constant('bar', 1), new Twig_Node_Expression_Constant('foobar', 1))); + $tests[] = array($node, 'foo("bar", "foobar")', $environment); + + $node = $this->createFunction('bar'); + $tests[] = array($node, 'bar($this->env)', $environment); + + $node = $this->createFunction('bar', array(new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'bar($this->env, "bar")', $environment); + + $node = $this->createFunction('foofoo'); + $tests[] = array($node, 'foofoo($context)', $environment); + + $node = $this->createFunction('foofoo', array(new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'foofoo($context, "bar")', $environment); + + $node = $this->createFunction('foobar'); + $tests[] = array($node, 'foobar($this->env, $context)', $environment); + + $node = $this->createFunction('foobar', array(new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'foobar($this->env, $context, "bar")', $environment); + + // named arguments + $node = $this->createFunction('date', array( + 'timezone' => new Twig_Node_Expression_Constant('America/Chicago', 1), + 'date' => new Twig_Node_Expression_Constant(0, 1), + )); + $tests[] = array($node, 'twig_date_converter($this->env, 0, "America/Chicago")'); + + // arbitrary named arguments + $node = $this->createFunction('barbar'); + $tests[] = array($node, 'twig_tests_function_barbar()', $environment); + + $node = $this->createFunction('barbar', array('foo' => new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'twig_tests_function_barbar(null, null, array("foo" => "bar"))', $environment); + + $node = $this->createFunction('barbar', array('arg2' => new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'twig_tests_function_barbar(null, "bar")', $environment); + + $node = $this->createFunction('barbar', array( + new Twig_Node_Expression_Constant('1', 1), + new Twig_Node_Expression_Constant('2', 1), + new Twig_Node_Expression_Constant('3', 1), + 'foo' => new Twig_Node_Expression_Constant('bar', 1), + )); + $tests[] = array($node, 'twig_tests_function_barbar("1", "2", array(0 => "3", "foo" => "bar"))', $environment); + + // function as an anonymous function + if (PHP_VERSION_ID >= 50300) { + $node = $this->createFunction('anonymous', array(new Twig_Node_Expression_Constant('foo', 1))); + $tests[] = array($node, 'call_user_func_array($this->env->getFunction(\'anonymous\')->getCallable(), array("foo"))'); + } + + return $tests; + } + + protected function createFunction($name, array $arguments = array()) + { + return new Twig_Node_Expression_Function($name, new Twig_Node($arguments), 1); + } + + protected function getEnvironment() + { + if (PHP_VERSION_ID >= 50300) { + return include 'PHP53/FunctionInclude.php'; + } + + return parent::getEnvironment(); + } +} + +function twig_tests_function_barbar($arg1 = null, $arg2 = null, array $args = array()) +{ +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/GetAttrTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/GetAttrTest.php new file mode 100644 index 000000000..2764478c4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/GetAttrTest.php @@ -0,0 +1,50 @@ +addElement(new Twig_Node_Expression_Name('foo', 1)); + $args->addElement(new Twig_Node_Expression_Constant('bar', 1)); + $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_Template::ARRAY_CALL, 1); + + $this->assertEquals($expr, $node->getNode('node')); + $this->assertEquals($attr, $node->getNode('attribute')); + $this->assertEquals($args, $node->getNode('arguments')); + $this->assertEquals(Twig_Template::ARRAY_CALL, $node->getAttribute('type')); + } + + public function getTests() + { + $tests = array(); + + $expr = new Twig_Node_Expression_Name('foo', 1); + $attr = new Twig_Node_Expression_Constant('bar', 1); + $args = new Twig_Node_Expression_Array(array(), 1); + $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_Template::ANY_CALL, 1); + $tests[] = array($node, sprintf('%s%s, "bar", array())', $this->getAttributeGetter(), $this->getVariableGetter('foo', 1))); + + $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_Template::ARRAY_CALL, 1); + $tests[] = array($node, sprintf('%s%s, "bar", array(), "array")', $this->getAttributeGetter(), $this->getVariableGetter('foo', 1))); + + $args = new Twig_Node_Expression_Array(array(), 1); + $args->addElement(new Twig_Node_Expression_Name('foo', 1)); + $args->addElement(new Twig_Node_Expression_Constant('bar', 1)); + $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_Template::METHOD_CALL, 1); + $tests[] = array($node, sprintf('%s%s, "bar", array(0 => %s, 1 => "bar"), "method")', $this->getAttributeGetter(), $this->getVariableGetter('foo', 1), $this->getVariableGetter('foo'))); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/NameTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/NameTest.php new file mode 100644 index 000000000..70721a8bf --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/NameTest.php @@ -0,0 +1,43 @@ +assertEquals('foo', $node->getAttribute('name')); + } + + public function getTests() + { + $node = new Twig_Node_Expression_Name('foo', 1); + $context = new Twig_Node_Expression_Name('_context', 1); + + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('strict_variables' => true)); + $env1 = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('strict_variables' => false)); + + if (PHP_VERSION_ID >= 70000) { + $output = '($context["foo"] ?? $this->getContext($context, "foo"))'; + } elseif (PHP_VERSION_ID >= 50400) { + $output = '(isset($context["foo"]) ? $context["foo"] : $this->getContext($context, "foo"))'; + } else { + $output = '$this->getContext($context, "foo")'; + } + + return array( + array($node, "// line 1\n".$output, $env), + array($node, $this->getVariableGetter('foo', 1), $env1), + array($context, "// line 1\n\$context"), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/NullCoalesceTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/NullCoalesceTest.php new file mode 100644 index 000000000..a37490baf --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/NullCoalesceTest.php @@ -0,0 +1,31 @@ += 70000) { + $tests[] = array($node, "((// line 1\n\$context[\"foo\"]) ?? (2))"); + } elseif (PHP_VERSION_ID >= 50400) { + $tests[] = array($node, "(((// line 1\narray_key_exists(\"foo\", \$context) && !(null === (isset(\$context[\"foo\"]) ? \$context[\"foo\"] : null)))) ? ((isset(\$context[\"foo\"]) ? \$context[\"foo\"] : null)) : (2))"); + } else { + $tests[] = array($node, "(((// line 1\narray_key_exists(\"foo\", \$context) && !(null === \$this->getContext(\$context, \"foo\")))) ? (\$this->getContext(\$context, \"foo\")) : (2))"); + } + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FilterInclude.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FilterInclude.php new file mode 100644 index 000000000..b5394bcf4 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FilterInclude.php @@ -0,0 +1,6 @@ +addFilter(new Twig_SimpleFilter('anonymous', function () {})); + +return $env; diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FunctionInclude.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FunctionInclude.php new file mode 100644 index 000000000..e8f68c728 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/FunctionInclude.php @@ -0,0 +1,6 @@ +addFunction(new Twig_SimpleFunction('anonymous', function () {})); + +return $env; diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/TestInclude.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/TestInclude.php new file mode 100644 index 000000000..9f818bc41 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/PHP53/TestInclude.php @@ -0,0 +1,6 @@ +addTest(new Twig_SimpleTest('anonymous', function () {})); + +return $env; diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/ParentTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/ParentTest.php new file mode 100644 index 000000000..ab2bbe074 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/ParentTest.php @@ -0,0 +1,28 @@ +assertEquals('foo', $node->getAttribute('name')); + } + + public function getTests() + { + $tests = array(); + $tests[] = array(new Twig_Node_Expression_Parent('foo', 1), '$this->renderParentBlock("foo", $context, $blocks)'); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/TestTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/TestTest.php new file mode 100644 index 000000000..a5f96d245 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/TestTest.php @@ -0,0 +1,82 @@ +assertEquals($expr, $node->getNode('node')); + $this->assertEquals($args, $node->getNode('arguments')); + $this->assertEquals($name, $node->getAttribute('name')); + } + + public function getTests() + { + $environment = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $environment->addTest(new Twig_SimpleTest('barbar', 'twig_tests_test_barbar', array('is_variadic' => true, 'need_context' => true))); + + $tests = array(); + + $expr = new Twig_Node_Expression_Constant('foo', 1); + $node = new Twig_Node_Expression_Test_Null($expr, 'null', new Twig_Node(array()), 1); + $tests[] = array($node, '(null === "foo")'); + + // test as an anonymous function + if (PHP_VERSION_ID >= 50300) { + $node = $this->createTest(new Twig_Node_Expression_Constant('foo', 1), 'anonymous', array(new Twig_Node_Expression_Constant('foo', 1))); + $tests[] = array($node, 'call_user_func_array($this->env->getTest(\'anonymous\')->getCallable(), array("foo", "foo"))'); + } + + // arbitrary named arguments + $string = new Twig_Node_Expression_Constant('abc', 1); + $node = $this->createTest($string, 'barbar'); + $tests[] = array($node, 'twig_tests_test_barbar("abc")', $environment); + + $node = $this->createTest($string, 'barbar', array('foo' => new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'twig_tests_test_barbar("abc", null, null, array("foo" => "bar"))', $environment); + + $node = $this->createTest($string, 'barbar', array('arg2' => new Twig_Node_Expression_Constant('bar', 1))); + $tests[] = array($node, 'twig_tests_test_barbar("abc", null, "bar")', $environment); + + $node = $this->createTest($string, 'barbar', array( + new Twig_Node_Expression_Constant('1', 1), + new Twig_Node_Expression_Constant('2', 1), + new Twig_Node_Expression_Constant('3', 1), + 'foo' => new Twig_Node_Expression_Constant('bar', 1), + )); + $tests[] = array($node, 'twig_tests_test_barbar("abc", "1", "2", array(0 => "3", "foo" => "bar"))', $environment); + + return $tests; + } + + protected function createTest($node, $name, array $arguments = array()) + { + return new Twig_Node_Expression_Test($node, $name, new Twig_Node($arguments), 1); + } + + protected function getEnvironment() + { + if (PHP_VERSION_ID >= 50300) { + return include 'PHP53/TestInclude.php'; + } + + return parent::getEnvironment(); + } +} + +function twig_tests_test_barbar($string, $arg1 = null, $arg2 = null, array $args = array()) +{ +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/NegTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/NegTest.php new file mode 100644 index 000000000..b63337117 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/NegTest.php @@ -0,0 +1,32 @@ +assertEquals($expr, $node->getNode('node')); + } + + public function getTests() + { + $node = new Twig_Node_Expression_Constant(1, 1); + $node = new Twig_Node_Expression_Unary_Neg($node, 1); + + return array( + array($node, '-1'), + array(new Twig_Node_Expression_Unary_Neg($node, 1), '- -1'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/NotTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/NotTest.php new file mode 100644 index 000000000..d7c6f85e7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/NotTest.php @@ -0,0 +1,31 @@ +assertEquals($expr, $node->getNode('node')); + } + + public function getTests() + { + $node = new Twig_Node_Expression_Constant(1, 1); + $node = new Twig_Node_Expression_Unary_Not($node, 1); + + return array( + array($node, '!1'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/PosTest.php b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/PosTest.php new file mode 100644 index 000000000..057250f37 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/Expression/Unary/PosTest.php @@ -0,0 +1,31 @@ +assertEquals($expr, $node->getNode('node')); + } + + public function getTests() + { + $node = new Twig_Node_Expression_Constant(1, 1); + $node = new Twig_Node_Expression_Unary_Pos($node, 1); + + return array( + array($node, '+1'), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/ForTest.php b/vendor/twig/twig/test/Twig/Tests/Node/ForTest.php new file mode 100644 index 000000000..2bf4c7b43 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/ForTest.php @@ -0,0 +1,191 @@ +setAttribute('with_loop', false); + + $this->assertEquals($keyTarget, $node->getNode('key_target')); + $this->assertEquals($valueTarget, $node->getNode('value_target')); + $this->assertEquals($seq, $node->getNode('seq')); + $this->assertTrue($node->getAttribute('ifexpr')); + $this->assertEquals('Twig_Node_If', get_class($node->getNode('body'))); + $this->assertEquals($body, $node->getNode('body')->getNode('tests')->getNode(1)->getNode(0)); + $this->assertFalse($node->hasNode('else')); + + $else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1); + $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1); + $node->setAttribute('with_loop', false); + $this->assertEquals($else, $node->getNode('else')); + } + + public function getTests() + { + $tests = array(); + + $keyTarget = new Twig_Node_Expression_AssignName('key', 1); + $valueTarget = new Twig_Node_Expression_AssignName('item', 1); + $seq = new Twig_Node_Expression_Name('items', 1); + $ifexpr = null; + $body = new Twig_Node(array(new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1)), array(), 1); + $else = null; + $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1); + $node->setAttribute('with_loop', false); + + $tests[] = array($node, <<getVariableGetter('items')}); +foreach (\$context['_seq'] as \$context["key"] => \$context["item"]) { + echo {$this->getVariableGetter('foo')}; +} +\$_parent = \$context['_parent']; +unset(\$context['_seq'], \$context['_iterated'], \$context['key'], \$context['item'], \$context['_parent'], \$context['loop']); +\$context = array_intersect_key(\$context, \$_parent) + \$_parent; +EOF + ); + + $keyTarget = new Twig_Node_Expression_AssignName('k', 1); + $valueTarget = new Twig_Node_Expression_AssignName('v', 1); + $seq = new Twig_Node_Expression_Name('values', 1); + $ifexpr = null; + $body = new Twig_Node(array(new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1)), array(), 1); + $else = null; + $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1); + $node->setAttribute('with_loop', true); + + $tests[] = array($node, <<getVariableGetter('values')}); +\$context['loop'] = array( + 'parent' => \$context['_parent'], + 'index0' => 0, + 'index' => 1, + 'first' => true, +); +if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) { + \$length = count(\$context['_seq']); + \$context['loop']['revindex0'] = \$length - 1; + \$context['loop']['revindex'] = \$length; + \$context['loop']['length'] = \$length; + \$context['loop']['last'] = 1 === \$length; +} +foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) { + echo {$this->getVariableGetter('foo')}; + ++\$context['loop']['index0']; + ++\$context['loop']['index']; + \$context['loop']['first'] = false; + if (isset(\$context['loop']['length'])) { + --\$context['loop']['revindex0']; + --\$context['loop']['revindex']; + \$context['loop']['last'] = 0 === \$context['loop']['revindex0']; + } +} +\$_parent = \$context['_parent']; +unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']); +\$context = array_intersect_key(\$context, \$_parent) + \$_parent; +EOF + ); + + $keyTarget = new Twig_Node_Expression_AssignName('k', 1); + $valueTarget = new Twig_Node_Expression_AssignName('v', 1); + $seq = new Twig_Node_Expression_Name('values', 1); + $ifexpr = new Twig_Node_Expression_Constant(true, 1); + $body = new Twig_Node(array(new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1)), array(), 1); + $else = null; + $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1); + $node->setAttribute('with_loop', true); + + $tests[] = array($node, <<getVariableGetter('values')}); +\$context['loop'] = array( + 'parent' => \$context['_parent'], + 'index0' => 0, + 'index' => 1, + 'first' => true, +); +foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) { + if (true) { + echo {$this->getVariableGetter('foo')}; + ++\$context['loop']['index0']; + ++\$context['loop']['index']; + \$context['loop']['first'] = false; + } +} +\$_parent = \$context['_parent']; +unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']); +\$context = array_intersect_key(\$context, \$_parent) + \$_parent; +EOF + ); + + $keyTarget = new Twig_Node_Expression_AssignName('k', 1); + $valueTarget = new Twig_Node_Expression_AssignName('v', 1); + $seq = new Twig_Node_Expression_Name('values', 1); + $ifexpr = null; + $body = new Twig_Node(array(new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1)), array(), 1); + $else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1); + $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1); + $node->setAttribute('with_loop', true); + + $tests[] = array($node, <<getVariableGetter('values')}); +\$context['_iterated'] = false; +\$context['loop'] = array( + 'parent' => \$context['_parent'], + 'index0' => 0, + 'index' => 1, + 'first' => true, +); +if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) { + \$length = count(\$context['_seq']); + \$context['loop']['revindex0'] = \$length - 1; + \$context['loop']['revindex'] = \$length; + \$context['loop']['length'] = \$length; + \$context['loop']['last'] = 1 === \$length; +} +foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) { + echo {$this->getVariableGetter('foo')}; + \$context['_iterated'] = true; + ++\$context['loop']['index0']; + ++\$context['loop']['index']; + \$context['loop']['first'] = false; + if (isset(\$context['loop']['length'])) { + --\$context['loop']['revindex0']; + --\$context['loop']['revindex']; + \$context['loop']['last'] = 0 === \$context['loop']['revindex0']; + } +} +if (!\$context['_iterated']) { + echo {$this->getVariableGetter('foo')}; +} +\$_parent = \$context['_parent']; +unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']); +\$context = array_intersect_key(\$context, \$_parent) + \$_parent; +EOF + ); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/IfTest.php b/vendor/twig/twig/test/Twig/Tests/Node/IfTest.php new file mode 100644 index 000000000..4ab0e4cc7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/IfTest.php @@ -0,0 +1,88 @@ +assertEquals($t, $node->getNode('tests')); + $this->assertFalse($node->hasNode('else')); + + $else = new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 1), 1); + $node = new Twig_Node_If($t, $else, 1); + $this->assertEquals($else, $node->getNode('else')); + } + + public function getTests() + { + $tests = array(); + + $t = new Twig_Node(array( + new Twig_Node_Expression_Constant(true, 1), + new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1), + ), array(), 1); + $else = null; + $node = new Twig_Node_If($t, $else, 1); + + $tests[] = array($node, <<getVariableGetter('foo')}; +} +EOF + ); + + $t = new Twig_Node(array( + new Twig_Node_Expression_Constant(true, 1), + new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1), + new Twig_Node_Expression_Constant(false, 1), + new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 1), 1), + ), array(), 1); + $else = null; + $node = new Twig_Node_If($t, $else, 1); + + $tests[] = array($node, <<getVariableGetter('foo')}; +} elseif (false) { + echo {$this->getVariableGetter('bar')}; +} +EOF + ); + + $t = new Twig_Node(array( + new Twig_Node_Expression_Constant(true, 1), + new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 1), 1), + ), array(), 1); + $else = new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 1), 1); + $node = new Twig_Node_If($t, $else, 1); + + $tests[] = array($node, <<getVariableGetter('foo')}; +} else { + echo {$this->getVariableGetter('bar')}; +} +EOF + ); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/ImportTest.php b/vendor/twig/twig/test/Twig/Tests/Node/ImportTest.php new file mode 100644 index 000000000..36525b251 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/ImportTest.php @@ -0,0 +1,40 @@ +assertEquals($macro, $node->getNode('expr')); + $this->assertEquals($var, $node->getNode('var')); + } + + public function getTests() + { + $tests = array(); + + $macro = new Twig_Node_Expression_Constant('foo.twig', 1); + $var = new Twig_Node_Expression_AssignName('macro', 1); + $node = new Twig_Node_Import($macro, $var, 1); + + $tests[] = array($node, <<loadTemplate("foo.twig", null, 1); +EOF + ); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/IncludeTest.php b/vendor/twig/twig/test/Twig/Tests/Node/IncludeTest.php new file mode 100644 index 000000000..d801f3387 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/IncludeTest.php @@ -0,0 +1,83 @@ +assertFalse($node->hasNode('variables')); + $this->assertEquals($expr, $node->getNode('expr')); + $this->assertFalse($node->getAttribute('only')); + + $vars = new Twig_Node_Expression_Array(array(new Twig_Node_Expression_Constant('foo', 1), new Twig_Node_Expression_Constant(true, 1)), 1); + $node = new Twig_Node_Include($expr, $vars, true, false, 1); + $this->assertEquals($vars, $node->getNode('variables')); + $this->assertTrue($node->getAttribute('only')); + } + + public function getTests() + { + $tests = array(); + + $expr = new Twig_Node_Expression_Constant('foo.twig', 1); + $node = new Twig_Node_Include($expr, null, false, false, 1); + $tests[] = array($node, <<loadTemplate("foo.twig", null, 1)->display(\$context); +EOF + ); + + $expr = new Twig_Node_Expression_Conditional( + new Twig_Node_Expression_Constant(true, 1), + new Twig_Node_Expression_Constant('foo', 1), + new Twig_Node_Expression_Constant('foo', 1), + 0 + ); + $node = new Twig_Node_Include($expr, null, false, false, 1); + $tests[] = array($node, <<loadTemplate(((true) ? ("foo") : ("foo")), null, 1)->display(\$context); +EOF + ); + + $expr = new Twig_Node_Expression_Constant('foo.twig', 1); + $vars = new Twig_Node_Expression_Array(array(new Twig_Node_Expression_Constant('foo', 1), new Twig_Node_Expression_Constant(true, 1)), 1); + $node = new Twig_Node_Include($expr, $vars, false, false, 1); + $tests[] = array($node, <<loadTemplate("foo.twig", null, 1)->display(array_merge(\$context, array("foo" => true))); +EOF + ); + + $node = new Twig_Node_Include($expr, $vars, true, false, 1); + $tests[] = array($node, <<loadTemplate("foo.twig", null, 1)->display(array("foo" => true)); +EOF + ); + + $node = new Twig_Node_Include($expr, $vars, true, true, 1); + $tests[] = array($node, <<loadTemplate("foo.twig", null, 1)->display(array("foo" => true)); +} catch (Twig_Error_Loader \$e) { + // ignore missing template +} +EOF + ); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php b/vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php new file mode 100644 index 000000000..c7edfa251 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/MacroTest.php @@ -0,0 +1,74 @@ +assertEquals($body, $node->getNode('body')); + $this->assertEquals($arguments, $node->getNode('arguments')); + $this->assertEquals('foo', $node->getAttribute('name')); + } + + public function getTests() + { + $body = new Twig_Node_Text('foo', 1); + $arguments = new Twig_Node(array( + 'foo' => new Twig_Node_Expression_Constant(null, 1), + 'bar' => new Twig_Node_Expression_Constant('Foo', 1), + ), array(), 1); + $node = new Twig_Node_Macro('foo', $body, $arguments, 1); + + if (PHP_VERSION_ID >= 50600) { + $declaration = ', ...$__varargs__'; + $varargs = '$__varargs__'; + } else { + $declaration = ''; + $varargs = 'func_num_args() > 2 ? array_slice(func_get_args(), 2) : array()'; + } + + return array( + array($node, <<env->mergeGlobals(array( + "foo" => \$__foo__, + "bar" => \$__bar__, + "varargs" => $varargs, + )); + + \$blocks = array(); + + ob_start(); + try { + echo "foo"; + } catch (Exception \$e) { + ob_end_clean(); + + throw \$e; + } catch (Throwable \$e) { + ob_end_clean(); + + throw \$e; + } + + return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset()); +} +EOF + ), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php b/vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php new file mode 100644 index 000000000..54a8989c7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/ModuleTest.php @@ -0,0 +1,223 @@ +assertEquals($body, $node->getNode('body')); + $this->assertEquals($blocks, $node->getNode('blocks')); + $this->assertEquals($macros, $node->getNode('macros')); + $this->assertEquals($parent, $node->getNode('parent')); + $this->assertEquals($source->getName(), $node->getTemplateName()); + } + + public function getTests() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + + $tests = array(); + + $body = new Twig_Node_Text('foo', 1); + $extends = null; + $blocks = new Twig_Node(); + $macros = new Twig_Node(); + $traits = new Twig_Node(); + $source = new Twig_Source('{{ foo }}', 'foo.twig'); + + $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $source); + $tests[] = array($node, <<parent = false; + + \$this->blocks = array( + ); + } + + protected function doDisplay(array \$context, array \$blocks = array()) + { + // line 1 + echo "foo"; + } + + public function getTemplateName() + { + return "foo.twig"; + } + + public function getDebugInfo() + { + return array ( 19 => 1,); + } + + /** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */ + public function getSource() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED); + + return \$this->getSourceContext()->getCode(); + } + + public function getSourceContext() + { + return new Twig_Source("", "foo.twig", ""); + } +} +EOF + , $twig, true); + + $import = new Twig_Node_Import(new Twig_Node_Expression_Constant('foo.twig', 1), new Twig_Node_Expression_AssignName('macro', 1), 2); + + $body = new Twig_Node(array($import)); + $extends = new Twig_Node_Expression_Constant('layout.twig', 1); + + $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $source); + $tests[] = array($node, <<parent = \$this->loadTemplate("layout.twig", "foo.twig", 1); + \$this->blocks = array( + ); + } + + protected function doGetParent(array \$context) + { + return "layout.twig"; + } + + protected function doDisplay(array \$context, array \$blocks = array()) + { + // line 2 + \$context["macro"] = \$this->loadTemplate("foo.twig", "foo.twig", 2); + // line 1 + \$this->parent->display(\$context, array_merge(\$this->blocks, \$blocks)); + } + + public function getTemplateName() + { + return "foo.twig"; + } + + public function isTraitable() + { + return false; + } + + public function getDebugInfo() + { + return array ( 26 => 1, 24 => 2, 11 => 1,); + } + + /** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */ + public function getSource() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED); + + return \$this->getSourceContext()->getCode(); + } + + public function getSourceContext() + { + return new Twig_Source("", "foo.twig", ""); + } +} +EOF + , $twig, true); + + $set = new Twig_Node_Set(false, new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 4))), new Twig_Node(array(new Twig_Node_Expression_Constant('foo', 4))), 4); + $body = new Twig_Node(array($set)); + $extends = new Twig_Node_Expression_Conditional( + new Twig_Node_Expression_Constant(true, 2), + new Twig_Node_Expression_Constant('foo', 2), + new Twig_Node_Expression_Constant('foo', 2), + 2 + ); + + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('debug' => true)); + $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, new Twig_Node(array()), $source); + $tests[] = array($node, <<loadTemplate(((true) ? ("foo") : ("foo")), "foo.twig", 2); + } + + protected function doDisplay(array \$context, array \$blocks = array()) + { + // line 4 + \$context["foo"] = "foo"; + // line 2 + \$this->getParent(\$context)->display(\$context, array_merge(\$this->blocks, \$blocks)); + } + + public function getTemplateName() + { + return "foo.twig"; + } + + public function isTraitable() + { + return false; + } + + public function getDebugInfo() + { + return array ( 17 => 2, 15 => 4, 9 => 2,); + } + + /** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */ + public function getSource() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED); + + return \$this->getSourceContext()->getCode(); + } + + public function getSourceContext() + { + return new Twig_Source("{{ foo }}", "foo.twig", ""); + } +} +EOF + , $twig, true); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/PrintTest.php b/vendor/twig/twig/test/Twig/Tests/Node/PrintTest.php new file mode 100644 index 000000000..4e0990fac --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/PrintTest.php @@ -0,0 +1,29 @@ +assertEquals($expr, $node->getNode('expr')); + } + + public function getTests() + { + $tests = array(); + $tests[] = array(new Twig_Node_Print(new Twig_Node_Expression_Constant('foo', 1), 1), "// line 1\necho \"foo\";"); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/SandboxTest.php b/vendor/twig/twig/test/Twig/Tests/Node/SandboxTest.php new file mode 100644 index 000000000..56f487730 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/SandboxTest.php @@ -0,0 +1,44 @@ +assertEquals($body, $node->getNode('body')); + } + + public function getTests() + { + $tests = array(); + + $body = new Twig_Node_Text('foo', 1); + $node = new Twig_Node_Sandbox($body, 1); + + $tests[] = array($node, <<env->getExtension('Twig_Extension_Sandbox'); +if (!\$alreadySandboxed = \$sandbox->isSandboxed()) { + \$sandbox->enableSandbox(); +} +echo "foo"; +if (!\$alreadySandboxed) { + \$sandbox->disableSandbox(); +} +EOF + ); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/SandboxedPrintTest.php b/vendor/twig/twig/test/Twig/Tests/Node/SandboxedPrintTest.php new file mode 100644 index 000000000..8bc8a755c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/SandboxedPrintTest.php @@ -0,0 +1,33 @@ +assertEquals($expr, $node->getNode('expr')); + } + + public function getTests() + { + $tests = array(); + + $tests[] = array(new Twig_Node_SandboxedPrint(new Twig_Node_Expression_Constant('foo', 1), 1), <<env->getExtension('Twig_Extension_Sandbox')->ensureToStringAllowed("foo"); +EOF + ); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/SetTest.php b/vendor/twig/twig/test/Twig/Tests/Node/SetTest.php new file mode 100644 index 000000000..62ad2803e --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/SetTest.php @@ -0,0 +1,69 @@ +assertEquals($names, $node->getNode('names')); + $this->assertEquals($values, $node->getNode('values')); + $this->assertFalse($node->getAttribute('capture')); + } + + public function getTests() + { + $tests = array(); + + $names = new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 1)), array(), 1); + $values = new Twig_Node(array(new Twig_Node_Expression_Constant('foo', 1)), array(), 1); + $node = new Twig_Node_Set(false, $names, $values, 1); + $tests[] = array($node, <<env->getCharset()); +EOF + ); + + $names = new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 1)), array(), 1); + $values = new Twig_Node_Text('foo', 1); + $node = new Twig_Node_Set(true, $names, $values, 1); + $tests[] = array($node, <<env->getCharset()); +EOF + ); + + $names = new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 1), new Twig_Node_Expression_AssignName('bar', 1)), array(), 1); + $values = new Twig_Node(array(new Twig_Node_Expression_Constant('foo', 1), new Twig_Node_Expression_Name('bar', 1)), array(), 1); + $node = new Twig_Node_Set(false, $names, $values, 1); + $tests[] = array($node, <<getVariableGetter('bar')}); +EOF + ); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/SpacelessTest.php b/vendor/twig/twig/test/Twig/Tests/Node/SpacelessTest.php new file mode 100644 index 000000000..222ca0920 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/SpacelessTest.php @@ -0,0 +1,37 @@ +
    foo
    ', 1))); + $node = new Twig_Node_Spaceless($body, 1); + + $this->assertEquals($body, $node->getNode('body')); + } + + public function getTests() + { + $body = new Twig_Node(array(new Twig_Node_Text('
    foo
    ', 1))); + $node = new Twig_Node_Spaceless($body, 1); + + return array( + array($node, <<
    foo
    "; +echo trim(preg_replace('/>\s+<', ob_get_clean())); +EOF + ), + ); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Node/TextTest.php b/vendor/twig/twig/test/Twig/Tests/Node/TextTest.php new file mode 100644 index 000000000..ceaf67f4c --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Node/TextTest.php @@ -0,0 +1,28 @@ +assertEquals('foo', $node->getAttribute('data')); + } + + public function getTests() + { + $tests = array(); + $tests[] = array(new Twig_Node_Text('foo', 1), "// line 1\necho \"foo\";"); + + return $tests; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php b/vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php new file mode 100644 index 000000000..0a48e6dd7 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php @@ -0,0 +1,124 @@ +getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + + $stream = $env->parse($env->tokenize(new Twig_Source('{{ block("foo") }}', 'index'))); + + $node = $stream->getNode('body')->getNode(0); + + $this->assertEquals('Twig_Node_Expression_BlockReference', get_class($node)); + $this->assertTrue($node->getAttribute('output')); + } + + public function testRenderParentBlockOptimizer() + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + + $stream = $env->parse($env->tokenize(new Twig_Source('{% extends "foo" %}{% block content %}{{ parent() }}{% endblock %}', 'index'))); + + $node = $stream->getNode('blocks')->getNode('content')->getNode(0)->getNode('body'); + + $this->assertEquals('Twig_Node_Expression_Parent', get_class($node)); + $this->assertTrue($node->getAttribute('output')); + } + + public function testRenderVariableBlockOptimizer() + { + if (PHP_VERSION_ID >= 50400) { + $this->markTestSkipped('not needed on PHP >= 5.4'); + } + + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false, 'autoescape' => false)); + $stream = $env->parse($env->tokenize(new Twig_Source('{{ block(name|lower) }}', 'index'))); + + $node = $stream->getNode('body')->getNode(0)->getNode(1); + + $this->assertEquals('Twig_Node_Expression_BlockReference', get_class($node)); + $this->assertTrue($node->getAttribute('output')); + } + + /** + * @dataProvider getTestsForForOptimizer + */ + public function testForOptimizer($template, $expected) + { + $env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('cache' => false)); + + $stream = $env->parse($env->tokenize(new Twig_Source($template, 'index'))); + + foreach ($expected as $target => $withLoop) { + $this->assertTrue($this->checkForConfiguration($stream, $target, $withLoop), sprintf('variable %s is %soptimized', $target, $withLoop ? 'not ' : '')); + } + } + + public function getTestsForForOptimizer() + { + return array( + array('{% for i in foo %}{% endfor %}', array('i' => false)), + + array('{% for i in foo %}{{ loop.index }}{% endfor %}', array('i' => true)), + + array('{% for i in foo %}{% for j in foo %}{% endfor %}{% endfor %}', array('i' => false, 'j' => false)), + + array('{% for i in foo %}{% include "foo" %}{% endfor %}', array('i' => true)), + + array('{% for i in foo %}{% include "foo" only %}{% endfor %}', array('i' => false)), + + array('{% for i in foo %}{% include "foo" with { "foo": "bar" } only %}{% endfor %}', array('i' => false)), + + array('{% for i in foo %}{% include "foo" with { "foo": loop.index } only %}{% endfor %}', array('i' => true)), + + array('{% for i in foo %}{% for j in foo %}{{ loop.index }}{% endfor %}{% endfor %}', array('i' => false, 'j' => true)), + + array('{% for i in foo %}{% for j in foo %}{{ loop.parent.loop.index }}{% endfor %}{% endfor %}', array('i' => true, 'j' => true)), + + array('{% for i in foo %}{% set l = loop %}{% for j in foo %}{{ l.index }}{% endfor %}{% endfor %}', array('i' => true, 'j' => false)), + + array('{% for i in foo %}{% for j in foo %}{{ foo.parent.loop.index }}{% endfor %}{% endfor %}', array('i' => false, 'j' => false)), + + array('{% for i in foo %}{% for j in foo %}{{ loop["parent"].loop.index }}{% endfor %}{% endfor %}', array('i' => true, 'j' => true)), + + array('{% for i in foo %}{{ include("foo") }}{% endfor %}', array('i' => true)), + + array('{% for i in foo %}{{ include("foo", with_context = false) }}{% endfor %}', array('i' => false)), + + array('{% for i in foo %}{{ include("foo", with_context = true) }}{% endfor %}', array('i' => true)), + + array('{% for i in foo %}{{ include("foo", { "foo": "bar" }, with_context = false) }}{% endfor %}', array('i' => false)), + + array('{% for i in foo %}{{ include("foo", { "foo": loop.index }, with_context = false) }}{% endfor %}', array('i' => true)), + ); + } + + public function checkForConfiguration(Twig_NodeInterface $node = null, $target, $withLoop) + { + if (null === $node) { + return; + } + + foreach ($node as $n) { + if ($n instanceof Twig_Node_For) { + if ($target === $n->getNode('value_target')->getAttribute('name')) { + return $withLoop == $n->getAttribute('with_loop'); + } + } + + $ret = $this->checkForConfiguration($n, $target, $withLoop); + if (null !== $ret) { + return $ret; + } + } + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/ParserTest.php b/vendor/twig/twig/test/Twig/Tests/ParserTest.php new file mode 100644 index 000000000..1bc2b0965 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/ParserTest.php @@ -0,0 +1,198 @@ +getParser(); + $parser->setMacro('parent', $this->getMockBuilder('Twig_Node_Macro')->disableOriginalConstructor()->getMock()); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown "foo" tag. Did you mean "for" at line 1? + */ + public function testUnknownTag() + { + $stream = new Twig_TokenStream(array( + new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 1), + new Twig_Token(Twig_Token::NAME_TYPE, 'foo', 1), + new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 1), + new Twig_Token(Twig_Token::EOF_TYPE, '', 1), + )); + $parser = new Twig_Parser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $parser->parse($stream); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unknown "foobar" tag at line 1. + */ + public function testUnknownTagWithoutSuggestions() + { + $stream = new Twig_TokenStream(array( + new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 1), + new Twig_Token(Twig_Token::NAME_TYPE, 'foobar', 1), + new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 1), + new Twig_Token(Twig_Token::EOF_TYPE, '', 1), + )); + $parser = new Twig_Parser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $parser->parse($stream); + } + + /** + * @dataProvider getFilterBodyNodesData + */ + public function testFilterBodyNodes($input, $expected) + { + $parser = $this->getParser(); + + $this->assertEquals($expected, $parser->filterBodyNodes($input)); + } + + public function getFilterBodyNodesData() + { + return array( + array( + new Twig_Node(array(new Twig_Node_Text(' ', 1))), + new Twig_Node(array()), + ), + array( + $input = new Twig_Node(array(new Twig_Node_Set(false, new Twig_Node(), new Twig_Node(), 1))), + $input, + ), + array( + $input = new Twig_Node(array(new Twig_Node_Set(true, new Twig_Node(), new Twig_Node(array(new Twig_Node(array(new Twig_Node_Text('foo', 1))))), 1))), + $input, + ), + ); + } + + /** + * @dataProvider getFilterBodyNodesDataThrowsException + * @expectedException Twig_Error_Syntax + */ + public function testFilterBodyNodesThrowsException($input) + { + $parser = $this->getParser(); + + $parser->filterBodyNodes($input); + } + + public function getFilterBodyNodesDataThrowsException() + { + return array( + array(new Twig_Node_Text('foo', 1)), + array(new Twig_Node(array(new Twig_Node(array(new Twig_Node_Text('foo', 1)))))), + ); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage A template that extends another one cannot start with a byte order mark (BOM); it must be removed at line 1 + */ + public function testFilterBodyNodesWithBOM() + { + $parser = $this->getParser(); + $parser->filterBodyNodes(new Twig_Node_Text(chr(0xEF).chr(0xBB).chr(0xBF), 1)); + } + + public function testParseIsReentrant() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array( + 'autoescape' => false, + 'optimizations' => 0, + )); + $twig->addTokenParser(new TestTokenParser()); + + $parser = new Twig_Parser($twig); + + $parser->parse(new Twig_TokenStream(array( + new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 1), + new Twig_Token(Twig_Token::NAME_TYPE, 'test', 1), + new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 1), + new Twig_Token(Twig_Token::VAR_START_TYPE, '', 1), + new Twig_Token(Twig_Token::NAME_TYPE, 'foo', 1), + new Twig_Token(Twig_Token::VAR_END_TYPE, '', 1), + new Twig_Token(Twig_Token::EOF_TYPE, '', 1), + ))); + + $this->assertNull($parser->getParent()); + } + + public function testGetVarName() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array( + 'autoescape' => false, + 'optimizations' => 0, + )); + + $twig->parse($twig->tokenize(new Twig_Source(<<addToAssertionCount(1); + } + + protected function getParser() + { + $parser = new TestParser(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + $parser->setParent(new Twig_Node()); + $parser->stream = new Twig_TokenStream(array()); + + return $parser; + } +} + +class TestParser extends Twig_Parser +{ + public $stream; + + public function filterBodyNodes(Twig_NodeInterface $node) + { + return parent::filterBodyNodes($node); + } +} + +class TestTokenParser extends Twig_TokenParser +{ + public function parse(Twig_Token $token) + { + // simulate the parsing of another template right in the middle of the parsing of the current template + $this->parser->parse(new Twig_TokenStream(array( + new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 1), + new Twig_Token(Twig_Token::NAME_TYPE, 'extends', 1), + new Twig_Token(Twig_Token::STRING_TYPE, 'base', 1), + new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 1), + new Twig_Token(Twig_Token::EOF_TYPE, '', 1), + ))); + + $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + + return new Twig_Node(array()); + } + + public function getTag() + { + return 'test'; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/AbstractTest.php b/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/AbstractTest.php new file mode 100644 index 000000000..da97f478a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/AbstractTest.php @@ -0,0 +1,101 @@ +getMockBuilder('Twig_Profiler_Profile')->disableOriginalConstructor()->getMock(); + + $profile->expects($this->any())->method('isRoot')->will($this->returnValue(true)); + $profile->expects($this->any())->method('getName')->will($this->returnValue('main')); + $profile->expects($this->any())->method('getDuration')->will($this->returnValue(1)); + $profile->expects($this->any())->method('getMemoryUsage')->will($this->returnValue(0)); + $profile->expects($this->any())->method('getPeakMemoryUsage')->will($this->returnValue(0)); + + $subProfiles = array( + $this->getIndexProfile( + array( + $this->getEmbeddedBlockProfile(), + $this->getEmbeddedTemplateProfile( + array( + $this->getIncludedTemplateProfile(), + ) + ), + $this->getMacroProfile(), + $this->getEmbeddedTemplateProfile( + array( + $this->getIncludedTemplateProfile(), + ) + ), + ) + ), + ); + + $profile->expects($this->any())->method('getProfiles')->will($this->returnValue($subProfiles)); + $profile->expects($this->any())->method('getIterator')->will($this->returnValue(new ArrayIterator($subProfiles))); + + return $profile; + } + + private function getIndexProfile(array $subProfiles = array()) + { + return $this->generateProfile('main', 1, true, 'template', 'index.twig', $subProfiles); + } + + private function getEmbeddedBlockProfile(array $subProfiles = array()) + { + return $this->generateProfile('body', 0.0001, false, 'block', 'embedded.twig', $subProfiles); + } + + private function getEmbeddedTemplateProfile(array $subProfiles = array()) + { + return $this->generateProfile('main', 0.0001, true, 'template', 'embedded.twig', $subProfiles); + } + + private function getIncludedTemplateProfile(array $subProfiles = array()) + { + return $this->generateProfile('main', 0.0001, true, 'template', 'included.twig', $subProfiles); + } + + private function getMacroProfile(array $subProfiles = array()) + { + return $this->generateProfile('foo', 0.0001, false, 'macro', 'index.twig', $subProfiles); + } + + /** + * @param string $name + * @param float $duration + * @param bool $isTemplate + * @param string $type + * @param string $templateName + * @param array $subProfiles + * + * @return Twig_Profiler_Profile + */ + private function generateProfile($name, $duration, $isTemplate, $type, $templateName, array $subProfiles = array()) + { + $profile = $this->getMockBuilder('Twig_Profiler_Profile')->disableOriginalConstructor()->getMock(); + + $profile->expects($this->any())->method('isRoot')->will($this->returnValue(false)); + $profile->expects($this->any())->method('getName')->will($this->returnValue($name)); + $profile->expects($this->any())->method('getDuration')->will($this->returnValue($duration)); + $profile->expects($this->any())->method('getMemoryUsage')->will($this->returnValue(0)); + $profile->expects($this->any())->method('getPeakMemoryUsage')->will($this->returnValue(0)); + $profile->expects($this->any())->method('isTemplate')->will($this->returnValue($isTemplate)); + $profile->expects($this->any())->method('getType')->will($this->returnValue($type)); + $profile->expects($this->any())->method('getTemplate')->will($this->returnValue($templateName)); + $profile->expects($this->any())->method('getProfiles')->will($this->returnValue($subProfiles)); + $profile->expects($this->any())->method('getIterator')->will($this->returnValue(new ArrayIterator($subProfiles))); + + return $profile; + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/BlackfireTest.php b/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/BlackfireTest.php new file mode 100644 index 000000000..1a1b9d299 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/BlackfireTest.php @@ -0,0 +1,32 @@ +assertStringMatchesFormat(<<index.twig//1 %d %d %d +index.twig==>embedded.twig::block(body)//1 %d %d 0 +index.twig==>embedded.twig//2 %d %d %d +embedded.twig==>included.twig//2 %d %d %d +index.twig==>index.twig::macro(foo)//1 %d %d %d +EOF + , $dumper->dump($this->getProfile())); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/HtmlTest.php b/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/HtmlTest.php new file mode 100644 index 000000000..66a68c4be --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/HtmlTest.php @@ -0,0 +1,30 @@ +assertStringMatchesFormat(<<main %d.%dms/%d% +└ index.twig %d.%dms/%d% + └ embedded.twig::block(body) + └ embedded.twig + │ └ included.twig + └ index.twig::macro(foo) + └ embedded.twig + └ included.twig + +EOF + , $dumper->dump($this->getProfile())); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/TextTest.php b/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/TextTest.php new file mode 100644 index 000000000..e2ea165ac --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Profiler/Dumper/TextTest.php @@ -0,0 +1,30 @@ +assertStringMatchesFormat(<<dump($this->getProfile())); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Profiler/ProfileTest.php b/vendor/twig/twig/test/Twig/Tests/Profiler/ProfileTest.php new file mode 100644 index 000000000..f786f06ca --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Profiler/ProfileTest.php @@ -0,0 +1,100 @@ +assertEquals('template', $profile->getTemplate()); + $this->assertEquals('type', $profile->getType()); + $this->assertEquals('name', $profile->getName()); + } + + public function testIsRoot() + { + $profile = new Twig_Profiler_Profile('template', Twig_Profiler_Profile::ROOT); + $this->assertTrue($profile->isRoot()); + + $profile = new Twig_Profiler_Profile('template', Twig_Profiler_Profile::TEMPLATE); + $this->assertFalse($profile->isRoot()); + } + + public function testIsTemplate() + { + $profile = new Twig_Profiler_Profile('template', Twig_Profiler_Profile::TEMPLATE); + $this->assertTrue($profile->isTemplate()); + + $profile = new Twig_Profiler_Profile('template', Twig_Profiler_Profile::ROOT); + $this->assertFalse($profile->isTemplate()); + } + + public function testIsBlock() + { + $profile = new Twig_Profiler_Profile('template', Twig_Profiler_Profile::BLOCK); + $this->assertTrue($profile->isBlock()); + + $profile = new Twig_Profiler_Profile('template', Twig_Profiler_Profile::ROOT); + $this->assertFalse($profile->isBlock()); + } + + public function testIsMacro() + { + $profile = new Twig_Profiler_Profile('template', Twig_Profiler_Profile::MACRO); + $this->assertTrue($profile->isMacro()); + + $profile = new Twig_Profiler_Profile('template', Twig_Profiler_Profile::ROOT); + $this->assertFalse($profile->isMacro()); + } + + public function testGetAddProfile() + { + $profile = new Twig_Profiler_Profile(); + $profile->addProfile($a = new Twig_Profiler_Profile()); + $profile->addProfile($b = new Twig_Profiler_Profile()); + + $this->assertSame(array($a, $b), $profile->getProfiles()); + $this->assertSame(array($a, $b), iterator_to_array($profile)); + } + + public function testGetDuration() + { + $profile = new Twig_Profiler_Profile(); + usleep(1); + $profile->leave(); + + $this->assertTrue($profile->getDuration() > 0, sprintf('Expected duration > 0, got: %f', $profile->getDuration())); + } + + public function testSerialize() + { + $profile = new Twig_Profiler_Profile('template', 'type', 'name'); + $profile1 = new Twig_Profiler_Profile('template1', 'type1', 'name1'); + $profile->addProfile($profile1); + $profile->leave(); + $profile1->leave(); + + $profile2 = unserialize(serialize($profile)); + $profiles = $profile->getProfiles(); + $this->assertCount(1, $profiles); + $profile3 = $profiles[0]; + + $this->assertEquals($profile->getTemplate(), $profile2->getTemplate()); + $this->assertEquals($profile->getType(), $profile2->getType()); + $this->assertEquals($profile->getName(), $profile2->getName()); + $this->assertEquals($profile->getDuration(), $profile2->getDuration()); + + $this->assertEquals($profile1->getTemplate(), $profile3->getTemplate()); + $this->assertEquals($profile1->getType(), $profile3->getType()); + $this->assertEquals($profile1->getName(), $profile3->getName()); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/TemplateTest.php b/vendor/twig/twig/test/Twig/Tests/TemplateTest.php new file mode 100644 index 000000000..4da2d5750 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/TemplateTest.php @@ -0,0 +1,761 @@ +getMockForAbstractClass('Twig_Template', array(), '', false); + $template->displayBlock('foo', array(), array('foo' => array(new stdClass(), 'foo'))); + } + + /** + * @dataProvider getAttributeExceptions + */ + public function testGetAttributeExceptions($template, $message) + { + $templates = array('index' => $template); + $env = new Twig_Environment(new Twig_Loader_Array($templates), array('strict_variables' => true)); + $template = $env->loadTemplate('index'); + + $context = array( + 'string' => 'foo', + 'null' => null, + 'empty_array' => array(), + 'array' => array('foo' => 'foo'), + 'array_access' => new Twig_TemplateArrayAccessObject(), + 'magic_exception' => new Twig_TemplateMagicPropertyObjectWithException(), + 'object' => new stdClass(), + ); + + try { + $template->render($context); + $this->fail('Accessing an invalid attribute should throw an exception.'); + } catch (Twig_Error_Runtime $e) { + $this->assertSame(sprintf($message, 'index'), $e->getMessage()); + } + } + + public function getAttributeExceptions() + { + return array( + array('{{ string["a"] }}', 'Impossible to access a key ("a") on a string variable ("foo") in "%s" at line 1.'), + array('{{ null["a"] }}', 'Impossible to access a key ("a") on a null variable in "%s" at line 1.'), + array('{{ empty_array["a"] }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.'), + array('{{ array["a"] }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.'), + array('{{ array_access["a"] }}', 'Key "a" in object with ArrayAccess of class "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1.'), + array('{{ string.a }}', 'Impossible to access an attribute ("a") on a string variable ("foo") in "%s" at line 1.'), + array('{{ string.a() }}', 'Impossible to invoke a method ("a") on a string variable ("foo") in "%s" at line 1.'), + array('{{ null.a }}', 'Impossible to access an attribute ("a") on a null variable in "%s" at line 1.'), + array('{{ null.a() }}', 'Impossible to invoke a method ("a") on a null variable in "%s" at line 1.'), + array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.'), + array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.'), + array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1.'), + array('{{ array_access.a }}', 'Neither the property "a" nor one of the methods "a()", "geta()"/"isa()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.'), + array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Neither the property "missing_method" nor one of the methods "missing_method()", "getmissing_method()"/"ismissing_method()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1.'), + array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.'), + array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1.'), + ); + } + + /** + * @dataProvider getGetAttributeWithSandbox + */ + public function testGetAttributeWithSandbox($object, $item, $allowed) + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + $policy = new Twig_Sandbox_SecurityPolicy(array(), array(), array(/*method*/), array(/*prop*/), array()); + $twig->addExtension(new Twig_Extension_Sandbox($policy, !$allowed)); + $template = new Twig_TemplateTest($twig); + + try { + $template->getAttribute($object, $item, array(), 'any'); + + if (!$allowed) { + $this->fail(); + } else { + $this->addToAssertionCount(1); + } + } catch (Twig_Sandbox_SecurityError $e) { + if ($allowed) { + $this->fail(); + } else { + $this->addToAssertionCount(1); + } + + $this->assertContains('is not allowed', $e->getMessage()); + } + } + + public function getGetAttributeWithSandbox() + { + return array( + array(new Twig_TemplatePropertyObject(), 'defined', false), + array(new Twig_TemplatePropertyObject(), 'defined', true), + array(new Twig_TemplateMethodObject(), 'defined', false), + array(new Twig_TemplateMethodObject(), 'defined', true), + ); + } + + /** + * @group legacy + */ + public function testGetAttributeWithTemplateAsObject() + { + // to be removed in 2.0 + $twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock()); + //$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface')->getMock()); + + $template = new Twig_TemplateTest($twig, 'index.twig'); + $template1 = new Twig_TemplateTest($twig, 'index1.twig'); + + $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'string')); + $this->assertEquals('some_string', $template->getAttribute($template1, 'string')); + + $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'true')); + $this->assertEquals('1', $template->getAttribute($template1, 'true')); + + $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'zero')); + $this->assertEquals('0', $template->getAttribute($template1, 'zero')); + + $this->assertNotInstanceof('Twig_Markup', $template->getAttribute($template1, 'empty')); + $this->assertSame('', $template->getAttribute($template1, 'empty')); + + $this->assertFalse($template->getAttribute($template1, 'env', array(), Twig_Template::ANY_CALL, true)); + $this->assertFalse($template->getAttribute($template1, 'environment', array(), Twig_Template::ANY_CALL, true)); + $this->assertFalse($template->getAttribute($template1, 'getEnvironment', array(), Twig_Template::METHOD_CALL, true)); + $this->assertFalse($template->getAttribute($template1, 'displayWithErrorHandling', array(), Twig_Template::METHOD_CALL, true)); + } + + /** + * @group legacy + * @expectedDeprecation Calling "string" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. + * @expectedDeprecation Calling "string" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. + * @expectedDeprecation Calling "true" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. + * @expectedDeprecation Calling "true" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. + * @expectedDeprecation Calling "zero" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. + * @expectedDeprecation Calling "zero" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. + * @expectedDeprecation Calling "empty" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. + * @expectedDeprecation Calling "empty" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. + * @expectedDeprecation Calling "renderBlock" on template "index.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use block("name") instead). + * @expectedDeprecation Calling "displayBlock" on template "index.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use block("name") instead). + * @expectedDeprecation Calling "hasBlock" on template "index.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use "block("name") is defined" instead). + * @expectedDeprecation Calling "render" on template "index.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use include("index.twig") instead). + * @expectedDeprecation Calling "display" on template "index.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use include("index.twig") instead). + * @expectedDeprecation Calling "renderBlock" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use block("name", template) instead). + * @expectedDeprecation Calling "displayBlock" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use block("name", template) instead). + * @expectedDeprecation Calling "hasBlock" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use "block("name", template) is defined" instead). + * @expectedDeprecation Calling "render" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use include("index1.twig") instead). + * @expectedDeprecation Calling "display" on template "index1.twig" from template "index.twig" is deprecated since version 1.28 and won't be supported anymore in 2.0. Use include("index1.twig") instead). + */ + public function testGetAttributeWithTemplateAsObjectForDeprecations() + { + // to be removed in 2.0 + $twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock()); + //$twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface')->getMock()); + + $template = new Twig_TemplateTest($twig, 'index.twig'); + $template1 = new Twig_TemplateTest($twig, 'index1.twig'); + + $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'string')); + $this->assertEquals('some_string', $template->getAttribute($template1, 'string')); + + $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'true')); + $this->assertEquals('1', $template->getAttribute($template1, 'true')); + + $this->assertInstanceof('Twig_Markup', $template->getAttribute($template1, 'zero')); + $this->assertEquals('0', $template->getAttribute($template1, 'zero')); + + $this->assertNotInstanceof('Twig_Markup', $template->getAttribute($template1, 'empty')); + $this->assertSame('', $template->getAttribute($template1, 'empty')); + + $blocks = array('name' => array($template1, 'block_name')); + + // trigger some deprecation notice messages to check them with @expectedDeprecation + $template->getAttribute($template, 'renderBlock', array('name', array(), $blocks)); + $template->getAttribute($template, 'displayBlock', array('name', array(), $blocks)); + $template->getAttribute($template, 'hasBlock', array('name', array())); + $template->getAttribute($template, 'render', array(array())); + $template->getAttribute($template, 'display', array(array())); + + $template->getAttribute($template1, 'renderBlock', array('name', array(), $blocks)); + $template->getAttribute($template1, 'displayBlock', array('name', array(), $blocks)); + $template->getAttribute($template1, 'hasBlock', array('name', array())); + $template->getAttribute($template1, 'render', array(array())); + $template->getAttribute($template1, 'display', array(array())); + + $this->assertFalse($template->getAttribute($template1, 'env', array(), Twig_Template::ANY_CALL, true)); + $this->assertFalse($template->getAttribute($template1, 'environment', array(), Twig_Template::ANY_CALL, true)); + $this->assertFalse($template->getAttribute($template1, 'getEnvironment', array(), Twig_Template::METHOD_CALL, true)); + $this->assertFalse($template->getAttribute($template1, 'displayWithErrorHandling', array(), Twig_Template::METHOD_CALL, true)); + } + + /** + * @group legacy + * @expectedDeprecation Silent display of undefined block "unknown" in template "index.twig" is deprecated since version 1.29 and will throw an exception in 2.0. Use the "block('unknown') is defined" expression to test for block existence. + * @expectedDeprecation Silent display of undefined block "unknown" in template "index.twig" is deprecated since version 1.29 and will throw an exception in 2.0. Use the "block('unknown') is defined" expression to test for block existence. + */ + public function testRenderBlockWithUndefinedBlock() + { + $twig = new Twig_Environment($this->getMockBuilder('Twig_TemplateTestLoaderInterface')->getMock()); + + $template = new Twig_TemplateTest($twig, 'index.twig'); + $template->renderBlock('unknown', array()); + $template->displayBlock('unknown', array()); + } + + public function testGetAttributeOnArrayWithConfusableKey() + { + $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + + $array = array('Zero', 'One', -1 => 'MinusOne', '' => 'EmptyString', '1.5' => 'FloatButString', '01' => 'IntegerButStringWithLeadingZeros'); + + $this->assertSame('Zero', $array[false]); + $this->assertSame('One', $array[true]); + $this->assertSame('One', $array[1.5]); + $this->assertSame('One', $array['1']); + $this->assertSame('MinusOne', $array[-1.5]); + $this->assertSame('FloatButString', $array['1.5']); + $this->assertSame('IntegerButStringWithLeadingZeros', $array['01']); + $this->assertSame('EmptyString', $array[null]); + + $this->assertSame('Zero', $template->getAttribute($array, false), 'false is treated as 0 when accessing an array (equals PHP behavior)'); + $this->assertSame('One', $template->getAttribute($array, true), 'true is treated as 1 when accessing an array (equals PHP behavior)'); + $this->assertSame('One', $template->getAttribute($array, 1.5), 'float is casted to int when accessing an array (equals PHP behavior)'); + $this->assertSame('One', $template->getAttribute($array, '1'), '"1" is treated as integer 1 when accessing an array (equals PHP behavior)'); + $this->assertSame('MinusOne', $template->getAttribute($array, -1.5), 'negative float is casted to int when accessing an array (equals PHP behavior)'); + $this->assertSame('FloatButString', $template->getAttribute($array, '1.5'), '"1.5" is treated as-is when accessing an array (equals PHP behavior)'); + $this->assertSame('IntegerButStringWithLeadingZeros', $template->getAttribute($array, '01'), '"01" is treated as-is when accessing an array (equals PHP behavior)'); + $this->assertSame('EmptyString', $template->getAttribute($array, null), 'null is treated as "" when accessing an array (equals PHP behavior)'); + } + + /** + * @dataProvider getGetAttributeTests + */ + public function testGetAttribute($defined, $value, $object, $item, $arguments, $type) + { + $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + + $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type)); + } + + /** + * @dataProvider getGetAttributeTests + */ + public function testGetAttributeStrict($defined, $value, $object, $item, $arguments, $type, $exceptionMessage = null) + { + $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('strict_variables' => true))); + + if ($defined) { + $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type)); + } else { + if (method_exists($this, 'expectException')) { + $this->expectException('Twig_Error_Runtime'); + if (null !== $exceptionMessage) { + $this->expectExceptionMessage($exceptionMessage); + } + } else { + $this->setExpectedException('Twig_Error_Runtime', $exceptionMessage); + } + $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type)); + } + } + + /** + * @dataProvider getGetAttributeTests + */ + public function testGetAttributeDefined($defined, $value, $object, $item, $arguments, $type) + { + $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + + $this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true)); + } + + /** + * @dataProvider getGetAttributeTests + */ + public function testGetAttributeDefinedStrict($defined, $value, $object, $item, $arguments, $type) + { + $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('strict_variables' => true))); + + $this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true)); + } + + public function testGetAttributeCallExceptions() + { + $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock())); + + $object = new Twig_TemplateMagicMethodExceptionObject(); + + $this->assertNull($template->getAttribute($object, 'foo')); + } + + public function getGetAttributeTests() + { + $array = array( + 'defined' => 'defined', + 'zero' => 0, + 'null' => null, + '1' => 1, + 'bar' => true, + 'baz' => 'baz', + '09' => '09', + '+4' => '+4', + ); + + $objectArray = new Twig_TemplateArrayAccessObject(); + $stdObject = (object) $array; + $magicPropertyObject = new Twig_TemplateMagicPropertyObject(); + $propertyObject = new Twig_TemplatePropertyObject(); + $propertyObject1 = new Twig_TemplatePropertyObjectAndIterator(); + $propertyObject2 = new Twig_TemplatePropertyObjectAndArrayAccess(); + $propertyObject3 = new Twig_TemplatePropertyObjectDefinedWithUndefinedValue(); + $methodObject = new Twig_TemplateMethodObject(); + $magicMethodObject = new Twig_TemplateMagicMethodObject(); + + $anyType = Twig_Template::ANY_CALL; + $methodType = Twig_Template::METHOD_CALL; + $arrayType = Twig_Template::ARRAY_CALL; + + $basicTests = array( + // array(defined, value, property to fetch) + array(true, 'defined', 'defined'), + array(false, null, 'undefined'), + array(false, null, 'protected'), + array(true, 0, 'zero'), + array(true, 1, 1), + array(true, 1, 1.0), + array(true, null, 'null'), + array(true, true, 'bar'), + array(true, 'baz', 'baz'), + array(true, '09', '09'), + array(true, '+4', '+4'), + ); + $testObjects = array( + // array(object, type of fetch) + array($array, $arrayType), + array($objectArray, $arrayType), + array($stdObject, $anyType), + array($magicPropertyObject, $anyType), + array($methodObject, $methodType), + array($methodObject, $anyType), + array($propertyObject, $anyType), + array($propertyObject1, $anyType), + array($propertyObject2, $anyType), + ); + + $tests = array(); + foreach ($testObjects as $testObject) { + foreach ($basicTests as $test) { + // properties cannot be numbers + if (($testObject[0] instanceof stdClass || $testObject[0] instanceof Twig_TemplatePropertyObject) && is_numeric($test[2])) { + continue; + } + + if ('+4' === $test[2] && $methodObject === $testObject[0]) { + continue; + } + + $tests[] = array($test[0], $test[1], $testObject[0], $test[2], array(), $testObject[1]); + } + } + + // additional properties tests + $tests = array_merge($tests, array( + array(true, null, $propertyObject3, 'foo', array(), $anyType), + )); + + // additional method tests + $tests = array_merge($tests, array( + array(true, 'defined', $methodObject, 'defined', array(), $methodType), + array(true, 'defined', $methodObject, 'DEFINED', array(), $methodType), + array(true, 'defined', $methodObject, 'getDefined', array(), $methodType), + array(true, 'defined', $methodObject, 'GETDEFINED', array(), $methodType), + array(true, 'static', $methodObject, 'static', array(), $methodType), + array(true, 'static', $methodObject, 'getStatic', array(), $methodType), + + array(true, '__call_undefined', $magicMethodObject, 'undefined', array(), $methodType), + array(true, '__call_UNDEFINED', $magicMethodObject, 'UNDEFINED', array(), $methodType), + )); + + // add the same tests for the any type + foreach ($tests as $test) { + if ($anyType !== $test[5]) { + $test[5] = $anyType; + $tests[] = $test; + } + } + + $methodAndPropObject = new Twig_TemplateMethodAndPropObject(); + + // additional method tests + $tests = array_merge($tests, array( + array(true, 'a', $methodAndPropObject, 'a', array(), $anyType), + array(true, 'a', $methodAndPropObject, 'a', array(), $methodType), + array(false, null, $methodAndPropObject, 'a', array(), $arrayType), + + array(true, 'b_prop', $methodAndPropObject, 'b', array(), $anyType), + array(true, 'b', $methodAndPropObject, 'B', array(), $anyType), + array(true, 'b', $methodAndPropObject, 'b', array(), $methodType), + array(true, 'b', $methodAndPropObject, 'B', array(), $methodType), + array(false, null, $methodAndPropObject, 'b', array(), $arrayType), + + array(false, null, $methodAndPropObject, 'c', array(), $anyType), + array(false, null, $methodAndPropObject, 'c', array(), $methodType), + array(false, null, $methodAndPropObject, 'c', array(), $arrayType), + )); + + // tests when input is not an array or object + $tests = array_merge($tests, array( + array(false, null, 42, 'a', array(), $anyType, 'Impossible to access an attribute ("a") on a integer variable ("42") in "index.twig".'), + array(false, null, 'string', 'a', array(), $anyType, 'Impossible to access an attribute ("a") on a string variable ("string") in "index.twig".'), + array(false, null, array(), 'a', array(), $anyType, 'Key "a" does not exist as the array is empty in "index.twig".'), + )); + + return $tests; + } + + /** + * @expectedException Twig_Error_Runtime + */ + public function testGetIsMethods() + { + $getIsObject = new Twig_TemplateGetIsMethods(); + $template = new Twig_TemplateTest(new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock(), array('strict_variables' => true))); + // first time should not create a cache for "get" + $this->assertNull($template->getAttribute($getIsObject, 'get')); + // 0 should be in the method cache now, so this should fail + $this->assertNull($template->getAttribute($getIsObject, 0)); + } +} + +class Twig_TemplateTest extends Twig_Template +{ + private $name; + + public function __construct(Twig_Environment $env, $name = 'index.twig') + { + parent::__construct($env); + self::$cache = array(); + $this->name = $name; + } + + public function getZero() + { + return 0; + } + + public function getEmpty() + { + return ''; + } + + public function getString() + { + return 'some_string'; + } + + public function getTrue() + { + return true; + } + + public function getTemplateName() + { + return $this->name; + } + + public function getDebugInfo() + { + return array(); + } + + protected function doGetParent(array $context) + { + return false; + } + + protected function doDisplay(array $context, array $blocks = array()) + { + } + + public function getAttribute($object, $item, array $arguments = array(), $type = Twig_Template::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false) + { + if (function_exists('twig_template_get_attributes')) { + return twig_template_get_attributes($this, $object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck); + } else { + return parent::getAttribute($object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck); + } + } + + public function block_name($context, array $blocks = array()) + { + } +} + +class Twig_TemplateArrayAccessObject implements ArrayAccess +{ + protected $protected = 'protected'; + + public $attributes = array( + 'defined' => 'defined', + 'zero' => 0, + 'null' => null, + '1' => 1, + 'bar' => true, + 'baz' => 'baz', + '09' => '09', + '+4' => '+4', + ); + + public function offsetExists($name) + { + return array_key_exists($name, $this->attributes); + } + + public function offsetGet($name) + { + return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : null; + } + + public function offsetSet($name, $value) + { + } + + public function offsetUnset($name) + { + } +} + +class Twig_TemplateMagicPropertyObject +{ + public $defined = 'defined'; + + public $attributes = array( + 'zero' => 0, + 'null' => null, + '1' => 1, + 'bar' => true, + 'baz' => 'baz', + '09' => '09', + '+4' => '+4', + ); + + protected $protected = 'protected'; + + public function __isset($name) + { + return array_key_exists($name, $this->attributes); + } + + public function __get($name) + { + return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : null; + } +} + +class Twig_TemplateMagicPropertyObjectWithException +{ + public function __isset($key) + { + throw new Exception('Hey! Don\'t try to isset me!'); + } +} + +class Twig_TemplatePropertyObject +{ + public $defined = 'defined'; + public $zero = 0; + public $null = null; + public $bar = true; + public $baz = 'baz'; + + protected $protected = 'protected'; +} + +class Twig_TemplatePropertyObjectAndIterator extends Twig_TemplatePropertyObject implements IteratorAggregate +{ + public function getIterator() + { + return new ArrayIterator(array('foo', 'bar')); + } +} + +class Twig_TemplatePropertyObjectAndArrayAccess extends Twig_TemplatePropertyObject implements ArrayAccess +{ + private $data = array( + 'defined' => 'defined', + 'zero' => 0, + 'null' => null, + 'bar' => true, + 'baz' => 'baz', + ); + + public function offsetExists($offset) + { + return array_key_exists($offset, $this->data); + } + + public function offsetGet($offset) + { + return $this->offsetExists($offset) ? $this->data[$offset] : 'n/a'; + } + + public function offsetSet($offset, $value) + { + } + + public function offsetUnset($offset) + { + } +} + +class Twig_TemplatePropertyObjectDefinedWithUndefinedValue +{ + public $foo; + + public function __construct() + { + $this->foo = @$notExist; + } +} + +class Twig_TemplateMethodObject +{ + public function getDefined() + { + return 'defined'; + } + + public function get1() + { + return 1; + } + + public function get09() + { + return '09'; + } + + public function getZero() + { + return 0; + } + + public function getNull() + { + } + + public function isBar() + { + return true; + } + + public function isBaz() + { + return 'should never be returned'; + } + + public function getBaz() + { + return 'baz'; + } + + protected function getProtected() + { + return 'protected'; + } + + public static function getStatic() + { + return 'static'; + } +} + +class Twig_TemplateGetIsMethods +{ + public function get() + { + } + + public function is() + { + } +} + +class Twig_TemplateMethodAndPropObject +{ + private $a = 'a_prop'; + + public function getA() + { + return 'a'; + } + + public $b = 'b_prop'; + + public function getB() + { + return 'b'; + } + + private $c = 'c_prop'; + + private function getC() + { + return 'c'; + } +} + +class Twig_TemplateMagicMethodObject +{ + public function __call($method, $arguments) + { + return '__call_'.$method; + } +} + +class Twig_TemplateMagicMethodExceptionObject +{ + public function __call($method, $arguments) + { + throw new BadMethodCallException(sprintf('Unknown method "%s".', $method)); + } +} + +class CExtDisablingNodeVisitor implements Twig_NodeVisitorInterface +{ + public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) + { + if ($node instanceof Twig_Node_Expression_GetAttr) { + $node->setAttribute('disable_c_ext', true); + } + + return $node; + } + + public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) + { + return $node; + } + + public function getPriority() + { + return 0; + } +} + +// to be removed in 2.0 +interface Twig_TemplateTestLoaderInterface extends Twig_LoaderInterface, Twig_SourceContextLoaderInterface +{ +} diff --git a/vendor/twig/twig/test/Twig/Tests/TemplateWrapperTest.php b/vendor/twig/twig/test/Twig/Tests/TemplateWrapperTest.php new file mode 100644 index 000000000..9cd1ced9a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/TemplateWrapperTest.php @@ -0,0 +1,64 @@ + '{% block foo %}{% endblock %}', + 'index_with_use' => '{% use "imported" %}{% block foo %}{% endblock %}', + 'index_with_extends' => '{% extends "extended" %}{% block foo %}{% endblock %}', + 'imported' => '{% block imported %}{% endblock %}', + 'extended' => '{% block extended %}{% endblock %}', + ))); + + $wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index')); + $this->assertTrue($wrapper->hasBlock('foo')); + $this->assertFalse($wrapper->hasBlock('bar')); + $this->assertEquals(array('foo'), $wrapper->getBlockNames()); + + $wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index_with_use')); + $this->assertTrue($wrapper->hasBlock('foo')); + $this->assertTrue($wrapper->hasBlock('imported')); + $this->assertEquals(array('imported', 'foo'), $wrapper->getBlockNames()); + + $wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index_with_extends')); + $this->assertTrue($wrapper->hasBlock('foo')); + $this->assertTrue($wrapper->hasBlock('extended')); + $this->assertEquals(array('foo', 'extended'), $wrapper->getBlockNames()); + } + + public function testRenderBlock() + { + $twig = new Twig_Environment(new Twig_Loader_Array(array( + 'index' => '{% block foo %}{{ foo }}{{ bar }}{% endblock %}', + ))); + $twig->addGlobal('bar', 'BAR'); + + $wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index')); + $this->assertEquals('FOOBAR', $wrapper->renderBlock('foo', array('foo' => 'FOO'))); + } + + public function testDisplayBlock() + { + $twig = new Twig_Environment(new Twig_Loader_Array(array( + 'index' => '{% block foo %}{{ foo }}{{ bar }}{% endblock %}', + ))); + $twig->addGlobal('bar', 'BAR'); + + $wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index')); + + ob_start(); + $wrapper->displayBlock('foo', array('foo' => 'FOO')); + + $this->assertEquals('FOOBAR', ob_get_clean()); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php b/vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php new file mode 100644 index 000000000..88f39a1fa --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/TokenStreamTest.php @@ -0,0 +1,82 @@ +assertEquals('foo', $stream->getFilename()); + $this->assertEquals('{{ foo }}', $stream->getSource()); + $this->assertEquals('foo', $stream->getSourceContext()->getName()); + $this->assertEquals('{{ foo }}', $stream->getSourceContext()->getCode()); + } + + public function testNext() + { + $stream = new Twig_TokenStream(self::$tokens); + $repr = array(); + while (!$stream->isEOF()) { + $token = $stream->next(); + + $repr[] = $token->getValue(); + } + $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->next() advances the pointer and returns the current token'); + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unexpected end of template + */ + public function testEndOfTemplateNext() + { + $stream = new Twig_TokenStream(array( + new Twig_Token(Twig_Token::BLOCK_START_TYPE, 1, 1), + )); + while (!$stream->isEOF()) { + $stream->next(); + } + } + + /** + * @expectedException Twig_Error_Syntax + * @expectedExceptionMessage Unexpected end of template + */ + public function testEndOfTemplateLook() + { + $stream = new Twig_TokenStream(array( + new Twig_Token(Twig_Token::BLOCK_START_TYPE, 1, 1), + )); + while (!$stream->isEOF()) { + $stream->look(); + $stream->next(); + } + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/Util/DeprecationCollectorTest.php b/vendor/twig/twig/test/Twig/Tests/Util/DeprecationCollectorTest.php new file mode 100644 index 000000000..9f7d14d17 --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/Util/DeprecationCollectorTest.php @@ -0,0 +1,42 @@ +getMockBuilder('Twig_LoaderInterface')->getMock()); + $twig->addFunction(new Twig_SimpleFunction('deprec', array($this, 'deprec'), array('deprecated' => true))); + + $collector = new Twig_Util_DeprecationCollector($twig); + $deprecations = $collector->collect(new Twig_Tests_Util_Iterator()); + + $this->assertEquals(array('Twig Function "deprec" is deprecated in deprec.twig at line 1.'), $deprecations); + } + + public function deprec() + { + } +} + +class Twig_Tests_Util_Iterator implements IteratorAggregate +{ + public function getIterator() + { + return new ArrayIterator(array( + 'ok.twig' => '{{ foo }}', + 'deprec.twig' => '{{ deprec("foo") }}', + )); + } +} diff --git a/vendor/twig/twig/test/Twig/Tests/escapingTest.php b/vendor/twig/twig/test/Twig/Tests/escapingTest.php new file mode 100644 index 000000000..e5b90935a --- /dev/null +++ b/vendor/twig/twig/test/Twig/Tests/escapingTest.php @@ -0,0 +1,320 @@ + ''', + '"' => '"', + '<' => '<', + '>' => '>', + '&' => '&', + ); + + protected $htmlAttrSpecialChars = array( + '\'' => ''', + /* Characters beyond ASCII value 255 to unicode escape */ + 'Ā' => 'Ā', + /* Immune chars excluded */ + ',' => ',', + '.' => '.', + '-' => '-', + '_' => '_', + /* Basic alnums excluded */ + 'a' => 'a', + 'A' => 'A', + 'z' => 'z', + 'Z' => 'Z', + '0' => '0', + '9' => '9', + /* Basic control characters and null */ + "\r" => ' ', + "\n" => ' ', + "\t" => ' ', + "\0" => '�', // should use Unicode replacement char + /* Encode chars as named entities where possible */ + '<' => '<', + '>' => '>', + '&' => '&', + '"' => '"', + /* Encode spaces for quoteless attribute protection */ + ' ' => ' ', + ); + + protected $jsSpecialChars = array( + /* HTML special chars - escape without exception to hex */ + '<' => '\\x3C', + '>' => '\\x3E', + '\'' => '\\x27', + '"' => '\\x22', + '&' => '\\x26', + /* Characters beyond ASCII value 255 to unicode escape */ + 'Ā' => '\\u0100', + /* Immune chars excluded */ + ',' => ',', + '.' => '.', + '_' => '_', + /* Basic alnums excluded */ + 'a' => 'a', + 'A' => 'A', + 'z' => 'z', + 'Z' => 'Z', + '0' => '0', + '9' => '9', + /* Basic control characters and null */ + "\r" => '\\x0D', + "\n" => '\\x0A', + "\t" => '\\x09', + "\0" => '\\x00', + /* Encode spaces for quoteless attribute protection */ + ' ' => '\\x20', + ); + + protected $urlSpecialChars = array( + /* HTML special chars - escape without exception to percent encoding */ + '<' => '%3C', + '>' => '%3E', + '\'' => '%27', + '"' => '%22', + '&' => '%26', + /* Characters beyond ASCII value 255 to hex sequence */ + 'Ā' => '%C4%80', + /* Punctuation and unreserved check */ + ',' => '%2C', + '.' => '.', + '_' => '_', + '-' => '-', + ':' => '%3A', + ';' => '%3B', + '!' => '%21', + /* Basic alnums excluded */ + 'a' => 'a', + 'A' => 'A', + 'z' => 'z', + 'Z' => 'Z', + '0' => '0', + '9' => '9', + /* Basic control characters and null */ + "\r" => '%0D', + "\n" => '%0A', + "\t" => '%09', + "\0" => '%00', + /* PHP quirks from the past */ + ' ' => '%20', + '~' => '~', + '+' => '%2B', + ); + + protected $cssSpecialChars = array( + /* HTML special chars - escape without exception to hex */ + '<' => '\\3C ', + '>' => '\\3E ', + '\'' => '\\27 ', + '"' => '\\22 ', + '&' => '\\26 ', + /* Characters beyond ASCII value 255 to unicode escape */ + 'Ā' => '\\100 ', + /* Immune chars excluded */ + ',' => '\\2C ', + '.' => '\\2E ', + '_' => '\\5F ', + /* Basic alnums excluded */ + 'a' => 'a', + 'A' => 'A', + 'z' => 'z', + 'Z' => 'Z', + '0' => '0', + '9' => '9', + /* Basic control characters and null */ + "\r" => '\\D ', + "\n" => '\\A ', + "\t" => '\\9 ', + "\0" => '\\0 ', + /* Encode spaces for quoteless attribute protection */ + ' ' => '\\20 ', + ); + + protected $env; + + protected function setUp() + { + $this->env = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock()); + } + + public function testHtmlEscapingConvertsSpecialChars() + { + foreach ($this->htmlSpecialChars as $key => $value) { + $this->assertEquals($value, twig_escape_filter($this->env, $key, 'html'), 'Failed to escape: '.$key); + } + } + + public function testHtmlAttributeEscapingConvertsSpecialChars() + { + foreach ($this->htmlAttrSpecialChars as $key => $value) { + $this->assertEquals($value, twig_escape_filter($this->env, $key, 'html_attr'), 'Failed to escape: '.$key); + } + } + + public function testJavascriptEscapingConvertsSpecialChars() + { + foreach ($this->jsSpecialChars as $key => $value) { + $this->assertEquals($value, twig_escape_filter($this->env, $key, 'js'), 'Failed to escape: '.$key); + } + } + + public function testJavascriptEscapingReturnsStringIfZeroLength() + { + $this->assertEquals('', twig_escape_filter($this->env, '', 'js')); + } + + public function testJavascriptEscapingReturnsStringIfContainsOnlyDigits() + { + $this->assertEquals('123', twig_escape_filter($this->env, '123', 'js')); + } + + public function testCssEscapingConvertsSpecialChars() + { + foreach ($this->cssSpecialChars as $key => $value) { + $this->assertEquals($value, twig_escape_filter($this->env, $key, 'css'), 'Failed to escape: '.$key); + } + } + + public function testCssEscapingReturnsStringIfZeroLength() + { + $this->assertEquals('', twig_escape_filter($this->env, '', 'css')); + } + + public function testCssEscapingReturnsStringIfContainsOnlyDigits() + { + $this->assertEquals('123', twig_escape_filter($this->env, '123', 'css')); + } + + public function testUrlEscapingConvertsSpecialChars() + { + foreach ($this->urlSpecialChars as $key => $value) { + $this->assertEquals($value, twig_escape_filter($this->env, $key, 'url'), 'Failed to escape: '.$key); + } + } + + /** + * Range tests to confirm escaped range of characters is within OWASP recommendation. + */ + + /** + * Only testing the first few 2 ranges on this prot. function as that's all these + * other range tests require. + */ + public function testUnicodeCodepointConversionToUtf8() + { + $expected = ' ~ޙ'; + $codepoints = array(0x20, 0x7e, 0x799); + $result = ''; + foreach ($codepoints as $value) { + $result .= $this->codepointToUtf8($value); + } + $this->assertEquals($expected, $result); + } + + /** + * Convert a Unicode Codepoint to a literal UTF-8 character. + * + * @param int $codepoint Unicode codepoint in hex notation + * + * @return string UTF-8 literal string + */ + protected function codepointToUtf8($codepoint) + { + if ($codepoint < 0x80) { + return chr($codepoint); + } + if ($codepoint < 0x800) { + return chr($codepoint >> 6 & 0x3f | 0xc0) + .chr($codepoint & 0x3f | 0x80); + } + if ($codepoint < 0x10000) { + return chr($codepoint >> 12 & 0x0f | 0xe0) + .chr($codepoint >> 6 & 0x3f | 0x80) + .chr($codepoint & 0x3f | 0x80); + } + if ($codepoint < 0x110000) { + return chr($codepoint >> 18 & 0x07 | 0xf0) + .chr($codepoint >> 12 & 0x3f | 0x80) + .chr($codepoint >> 6 & 0x3f | 0x80) + .chr($codepoint & 0x3f | 0x80); + } + throw new Exception('Codepoint requested outside of Unicode range.'); + } + + public function testJavascriptEscapingEscapesOwaspRecommendedRanges() + { + $immune = array(',', '.', '_'); // Exceptions to escaping ranges + for ($chr = 0; $chr < 0xFF; ++$chr) { + if ($chr >= 0x30 && $chr <= 0x39 + || $chr >= 0x41 && $chr <= 0x5A + || $chr >= 0x61 && $chr <= 0x7A) { + $literal = $this->codepointToUtf8($chr); + $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'js')); + } else { + $literal = $this->codepointToUtf8($chr); + if (in_array($literal, $immune)) { + $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'js')); + } else { + $this->assertNotEquals( + $literal, + twig_escape_filter($this->env, $literal, 'js'), + "$literal should be escaped!"); + } + } + } + } + + public function testHtmlAttributeEscapingEscapesOwaspRecommendedRanges() + { + $immune = array(',', '.', '-', '_'); // Exceptions to escaping ranges + for ($chr = 0; $chr < 0xFF; ++$chr) { + if ($chr >= 0x30 && $chr <= 0x39 + || $chr >= 0x41 && $chr <= 0x5A + || $chr >= 0x61 && $chr <= 0x7A) { + $literal = $this->codepointToUtf8($chr); + $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'html_attr')); + } else { + $literal = $this->codepointToUtf8($chr); + if (in_array($literal, $immune)) { + $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'html_attr')); + } else { + $this->assertNotEquals( + $literal, + twig_escape_filter($this->env, $literal, 'html_attr'), + "$literal should be escaped!"); + } + } + } + } + + public function testCssEscapingEscapesOwaspRecommendedRanges() + { + // CSS has no exceptions to escaping ranges + for ($chr = 0; $chr < 0xFF; ++$chr) { + if ($chr >= 0x30 && $chr <= 0x39 + || $chr >= 0x41 && $chr <= 0x5A + || $chr >= 0x61 && $chr <= 0x7A) { + $literal = $this->codepointToUtf8($chr); + $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'css')); + } else { + $literal = $this->codepointToUtf8($chr); + $this->assertNotEquals( + $literal, + twig_escape_filter($this->env, $literal, 'css'), + "$literal should be escaped!"); + } + } + } +} diff --git a/vendor/twig/twig/test/bootstrap.php b/vendor/twig/twig/test/bootstrap.php new file mode 100644 index 000000000..d167b67de --- /dev/null +++ b/vendor/twig/twig/test/bootstrap.php @@ -0,0 +1,21 @@ +locateRoot(getcwd())) { + $drupalRoot = $drupalFinder->getDrupalRoot(); + $composerRoot = $drupalFinder->getComposerRoot(); + ... +} +``` + +## Examples + +- [Drupal Console Launcher](https://github.com/hechoendrupal/drupal-console-launcher/blob/master/bin/drupal.php) +- [Drush Shim](https://github.com/webflo/drush-shim) (with webflo/drupal-finder:^0.0.1) + +## License + +GPL-2.0+ diff --git a/vendor/webflo/drupal-finder/phpunit.xml.dist b/vendor/webflo/drupal-finder/phpunit.xml.dist new file mode 100644 index 000000000..4d44bacf8 --- /dev/null +++ b/vendor/webflo/drupal-finder/phpunit.xml.dist @@ -0,0 +1,8 @@ + + + + + ./tests + + + diff --git a/vendor/webflo/drupal-finder/src/DrupalFinder.php b/vendor/webflo/drupal-finder/src/DrupalFinder.php index efa43892a..083504076 100644 --- a/vendor/webflo/drupal-finder/src/DrupalFinder.php +++ b/vendor/webflo/drupal-finder/src/DrupalFinder.php @@ -23,10 +23,20 @@ class DrupalFinder */ private $composerRoot; + /** + * Composer vendor directory. + * + * @var string + * + * @see https://getcomposer.org/doc/06-config.md#vendor-dir + */ + private $vendorDir; + public function locateRoot($start_path) { $this->drupalRoot = false; $this->composerRoot = false; + $this->vendorDir = false; foreach (array(true, false) as $follow_symlinks) { $path = $start_path; @@ -83,6 +93,7 @@ class DrupalFinder if (file_exists($path . '/core/misc/drupal.js') || file_exists($path . '/core/assets/js/drupal.js')) { $this->composerRoot = $path; $this->drupalRoot = $path; + $this->vendorDir = $this->composerRoot . '/vendor'; } } } @@ -101,13 +112,23 @@ class DrupalFinder 0, -5 ); + $this->vendorDir = $this->composerRoot . '/vendor'; } } } } } + if ($this->composerRoot && file_exists($this->composerRoot . '/composer.json')) { + $json = json_decode( + file_get_contents($path . '/composer.json'), + true + ); + if (is_array($json) && isset($json['config']['vendor-dir'])) { + $this->vendorDir = $this->composerRoot . '/' . $json['config']['vendor-dir']; + } + } - return $this->drupalRoot && $this->composerRoot; + return $this->drupalRoot && $this->composerRoot && $this->vendorDir; } /** @@ -125,4 +146,12 @@ class DrupalFinder { return $this->composerRoot; } + + /** + * @return string + */ + public function getVendorDir() + { + return $this->vendorDir; + } } diff --git a/vendor/webflo/drupal-finder/tests/DrupalFinderTest.php b/vendor/webflo/drupal-finder/tests/DrupalFinderTest.php new file mode 100644 index 000000000..5ca42f965 --- /dev/null +++ b/vendor/webflo/drupal-finder/tests/DrupalFinderTest.php @@ -0,0 +1,302 @@ + '', + 'composer.json' => '', + 'core' => [ + 'includes' => [ + 'common.inc' => '', + ], + 'misc' => [ + 'drupal.js' => '', + ], + 'core.services.yml' => '', + ], + 'modules' => [], + 'vendor' => [], + ]; + + /** + * @return array + */ + protected function getDrupalComposerStructure() + { + $fileStructure = [ + 'web' => static::$fileStructure, + 'composer.json' => json_encode([ + 'require' => [ + 'drupal/core' => '*', + ], + 'extra' => [ + 'installer-paths' => [ + 'web/core' => [ + 'type:drupal-core', + ], + ], + ], + ]), + 'vendor' => [], + ]; + unset($fileStructure['web']['composer.json']); + unset($fileStructure['web']['vendor']); + + return $fileStructure; + } + + protected function setUp() + { + parent::setUp(); + $this->finder = new \DrupalFinder\DrupalFinder(); + } + + public function testDrupalDefaultStructure() + { + $root = vfsStream::setup('root', null, static::$fileStructure); + + $this->assertTrue($this->finder->locateRoot($root->url())); + $this->assertSame('vfs://root', $this->finder->getDrupalRoot()); + $this->assertSame('vfs://root', $this->finder->getComposerRoot()); + $this->assertSame('vfs://root/vendor', $this->finder->getVendorDir()); + + $this->assertTrue($this->finder->locateRoot($root->url() . '/misc')); + $this->assertSame('vfs://root', $this->finder->getDrupalRoot()); + $this->assertSame('vfs://root', $this->finder->getComposerRoot()); + $this->assertSame('vfs://root/vendor', $this->finder->getVendorDir()); + + $root = vfsStream::setup( + 'root', + null, + ['project' => static::$fileStructure] + ); + $this->assertFalse( + $this->finder->locateRoot($root->url()), + 'Not in the scope of the project' + ); + $this->assertFalse($this->finder->getDrupalRoot()); + $this->assertFalse($this->finder->getComposerRoot()); + $this->assertFalse($this->finder->getVendorDir()); + } + + public function testDrupalComposerStructure() + { + $fileStructure = $this->getDrupalComposerStructure(); + $this->assertComposerStructure($fileStructure); + } + + public function testDrupalComposerStructureWithoutRequire() + { + $fileStructure = [ + 'web' => static::$fileStructure, + 'composer.json' => json_encode([ + 'extra' => [ + 'installer-paths' => [ + 'web/core' => [ + 'drupal/core', + ], + ], + ], + ]), + ]; + unset($fileStructure['web']['composer.json']); + $this->assertComposerStructure($fileStructure); + } + + public function testNoDrupalRootWithRealFilesystem() + { + $root = $this->tempdir(sys_get_temp_dir()); + + $this->assertFalse($this->finder->locateRoot($root)); + $this->assertFalse($this->finder->getDrupalRoot()); + $this->assertFalse($this->finder->getComposerRoot()); + $this->assertFalse($this->finder->getVendorDir()); + } + + public function testDrupalDefaultStructureWithRealFilesystem() + { + $root = $this->tempdir(sys_get_temp_dir()); + $this->dumpToFileSystem(static::$fileStructure, $root); + + $this->assertTrue($this->finder->locateRoot($root)); + $this->assertSame($root, $this->finder->getDrupalRoot()); + $this->assertSame($root, $this->finder->getComposerRoot()); + $this->assertSame($root . '/vendor', $this->finder->getVendorDir()); + + // Test symlink implementation + $symlink = $this->tempdir(sys_get_temp_dir()); + $this->symlink($root, $symlink . '/foo'); + + $this->assertTrue($this->finder->locateRoot($symlink . '/foo')); + $this->assertSame($root, $this->finder->getDrupalRoot()); + $this->assertSame($root, $this->finder->getComposerRoot()); + $this->assertSame($root . '/vendor', $this->finder->getVendorDir()); + } + + public function testDrupalComposerStructureWithRealFilesystem() + { + $root = $this->tempdir(sys_get_temp_dir()); + $this->dumpToFileSystem($this->getDrupalComposerStructure(), $root); + + $this->assertTrue($this->finder->locateRoot($root)); + $this->assertSame($root . '/web', $this->finder->getDrupalRoot()); + $this->assertSame($root, $this->finder->getComposerRoot()); + $this->assertSame($root . '/vendor', $this->finder->getVendorDir()); + + // Test symlink implementation + $symlink = $this->tempdir(sys_get_temp_dir()); + $this->symlink($root, $symlink . '/foo'); + + $this->assertTrue($this->finder->locateRoot($symlink . '/foo')); + $this->assertSame($root . '/web', $this->finder->getDrupalRoot()); + $this->assertSame($root, $this->finder->getComposerRoot()); + $this->assertSame($root . '/vendor', $this->finder->getVendorDir()); + } + + public function testDrupalWithLinkedModule() + { + $root = $this->tempdir(sys_get_temp_dir()); + $this->dumpToFileSystem(static::$fileStructure, $root); + + $module = $this->tempdir(sys_get_temp_dir()); + $module_link = $root . '/modules/foo'; + $this->symlink($module, $module_link); + + $this->assertTrue($this->finder->locateRoot($module_link)); + $this->assertSame($root, realpath($this->finder->getDrupalRoot())); + $this->assertSame($root, realpath($this->finder->getComposerRoot())); + $this->assertSame($root . '/vendor', realpath($this->finder->getVendorDir())); + } + + public function testDrupalWithCustomVendor() + { + $root = $this->tempdir(sys_get_temp_dir()); + $fileStructure = static::$fileStructure; + $fileStructure['composer.json'] = json_encode([ + 'config' => [ + 'vendor-dir' => 'vendor-foo' + ] + ], JSON_UNESCAPED_SLASHES); + $fileStructure['vendor-foo'] = []; + $this->dumpToFileSystem($fileStructure, $root); + + $this->assertTrue($this->finder->locateRoot($root)); + $this->assertSame($root, realpath($this->finder->getDrupalRoot())); + $this->assertSame($root, realpath($this->finder->getComposerRoot())); + $this->assertSame($root . '/vendor-foo', realpath($this->finder->getVendorDir())); + } + + protected function dumpToFileSystem($fileStructure, $root) + { + foreach ($fileStructure as $name => $content) { + if (is_array($content)) { + mkdir($root . '/' . $name); + $this->dumpToFileSystem($content, $root . '/' . $name); + } else { + file_put_contents($root . '/' . $name, $content); + } + } + } + + protected function tempdir($dir, $prefix = '', $mode = 0700) + { + if (substr($dir, -1) != '/') { + $dir .= '/'; + } + do { + $path = $dir . $prefix . mt_rand(0, 9999999); + } while (!mkdir($path, $mode)); + register_shutdown_function( + ['DrupalFinderTest', 'tempdir_remove'], + $path + ); + + return realpath($path); + } + + public static function tempdir_remove($path) + { + if (is_link($path)) { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + rmdir($path); + } else { + unlink($path); + } + + return; + } + + foreach (scandir($path) as $child) { + if (in_array($child, ['.', '..'])) { + continue; + } + $child = "$path/$child"; + is_dir($child) ? static::tempdir_remove($child) : unlink($child); + } + rmdir($path); + } + + /** + * @param $target + * @param $link + * + * @throws PHPUnit_Framework_SkippedTestError + */ + private function symlink($target, $link) + { + try { + return symlink($target, $link); + } catch (Exception $e) { + if (defined('PHP_WINDOWS_VERSION_BUILD') + && strstr($e->getMessage(), WIN_ERROR_PRIVILEGE_NOT_HELD) + ) { + $this->markTestSkipped(<<<'MESSAGE' +No privilege to create symlinks. Run test as Administrator (elevated process). +MESSAGE + ); + } + throw $e; + } + } + + /** + * @param $fileStructure + */ + protected function assertComposerStructure($fileStructure) + { + $root = vfsStream::setup('root', null, $fileStructure); + $this->assertTrue($this->finder->locateRoot($root->url() . '/web')); + $this->assertSame('vfs://root/web', $this->finder->getDrupalRoot()); + $this->assertSame('vfs://root', $this->finder->getComposerRoot()); + $this->assertSame('vfs://root/vendor', $this->finder->getVendorDir()); + + $this->assertTrue($this->finder->locateRoot($root->url() . '/web/misc')); + $this->assertSame('vfs://root/web', $this->finder->getDrupalRoot()); + $this->assertSame('vfs://root', $this->finder->getComposerRoot()); + $this->assertSame('vfs://root/vendor', $this->finder->getVendorDir()); + + $this->assertTrue($this->finder->locateRoot($root->url())); + $this->assertSame('vfs://root/web', $this->finder->getDrupalRoot()); + $this->assertSame('vfs://root', $this->finder->getComposerRoot()); + $this->assertSame('vfs://root/vendor', $this->finder->getVendorDir()); + + $root = vfsStream::setup( + 'root', + null, + ['nested_folder' => $fileStructure] + ); + $this->assertFalse($this->finder->locateRoot($root->url())); + $this->assertFalse($this->finder->getDrupalRoot()); + $this->assertFalse($this->finder->getComposerRoot()); + $this->assertFalse($this->finder->getVendorDir()); + } +} + +define('WIN_ERROR_PRIVILEGE_NOT_HELD', '1314'); diff --git a/web/libraries/superfish b/web/libraries/superfish deleted file mode 120000 index fd7094417..000000000 --- a/web/libraries/superfish +++ /dev/null @@ -1 +0,0 @@ -../../vendor/mehrpadin/superfish/ \ No newline at end of file diff --git a/vendor/mehrpadin/superfish/CHANGELOG b/web/libraries/superfish/CHANGELOG similarity index 100% rename from vendor/mehrpadin/superfish/CHANGELOG rename to web/libraries/superfish/CHANGELOG diff --git a/vendor/mehrpadin/superfish/README b/web/libraries/superfish/README similarity index 100% rename from vendor/mehrpadin/superfish/README rename to web/libraries/superfish/README diff --git a/vendor/mehrpadin/superfish/VERSION b/web/libraries/superfish/VERSION similarity index 100% rename from vendor/mehrpadin/superfish/VERSION rename to web/libraries/superfish/VERSION diff --git a/vendor/mehrpadin/superfish/composer.json b/web/libraries/superfish/composer.json similarity index 93% rename from vendor/mehrpadin/superfish/composer.json rename to web/libraries/superfish/composer.json index a21e37f47..2bc8885f1 100644 --- a/vendor/mehrpadin/superfish/composer.json +++ b/web/libraries/superfish/composer.json @@ -1,17 +1,18 @@ -{ - "name": "mehrpadin/superfish", - "homepage": "https://github.com/mehrpadin/Superfish-for-Drupal", - "description": "Superfish library for the Drupal Superfish module.", - "repository": { - "type": "git", - "url": "git://github.com/mehrpadin/Superfish-for-Drupal" - }, - "peerDependencies": { - "jquery": ">= 1.3.0" - }, - "keywords": [ - "plugin", - "jquery" - ], - "license": "MIT" +{ + "name": "mehrpadin/superfish", + "homepage": "https://github.com/mehrpadin/Superfish-for-Drupal", + "description": "Superfish library for the Drupal Superfish module.", + "type": "drupal-library", + "repository": { + "type": "git", + "url": "git://github.com/mehrpadin/Superfish-for-Drupal" + }, + "peerDependencies": { + "jquery": ">= 1.3.0" + }, + "keywords": [ + "plugin", + "jquery" + ], + "license": "MIT" } \ No newline at end of file diff --git a/vendor/mehrpadin/superfish/css/superfish.css b/web/libraries/superfish/css/superfish.css similarity index 100% rename from vendor/mehrpadin/superfish/css/superfish.css rename to web/libraries/superfish/css/superfish.css diff --git a/vendor/mehrpadin/superfish/jquery.hoverIntent.minified.js b/web/libraries/superfish/jquery.hoverIntent.minified.js similarity index 100% rename from vendor/mehrpadin/superfish/jquery.hoverIntent.minified.js rename to web/libraries/superfish/jquery.hoverIntent.minified.js diff --git a/vendor/mehrpadin/superfish/sfsmallscreen.js b/web/libraries/superfish/sfsmallscreen.js similarity index 95% rename from vendor/mehrpadin/superfish/sfsmallscreen.js rename to web/libraries/superfish/sfsmallscreen.js index 7a2d1981c..9765fedc9 100644 --- a/vendor/mehrpadin/superfish/sfsmallscreen.js +++ b/web/libraries/superfish/sfsmallscreen.js @@ -71,7 +71,7 @@ return refined; } - // Creating ', + items += '', childUL = list.find('> ul'); // Using the function for the sub-menu of this item. for (var u = 0; u < childUL.length; u++){ @@ -135,7 +136,7 @@ $(this).removeAttr('style').removeClass('sfHover').attr('id', $(this).attr('id') + '-accordion'); }); // Doing the same and making sure all the sub-menus are off-screen (hidden). - accordion.find('ul').removeAttr('style').not('.sf-hidden').addClass('sf-hidden'); + accordion.children('ul').removeAttr('style').not('.sf-hidden').addClass('sf-hidden'); // Creating the accordion toggle switch. var toggle = ''; @@ -167,7 +168,7 @@ // If the accordion is already expanded: // Hiding its expanded sub-menus and then the accordion itself as well. accordionElement.add(accordionElement.find('li.sf-expanded')).removeClass('sf-expanded') - .end().find('ul').hide() + .end().children('ul').hide() // This is a bit tricky, it's the same trick that has been in use in the main plugin for some time. // Basically we'll add a class that keeps the sub-menu off-screen and still visible, // and make it invisible and removing the class one moment before showing or hiding it. @@ -246,7 +247,7 @@ // Creating the